You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySerial读取Arduino红外编码器数据异常 调用pygame.display.update后冻结

可行修复方案
  • 将串口读取逻辑移至独立子线程
    主线程中pygame.display.update()的渲染操作会抢占主线程IO资源,导致串口读取被阻塞。单独启动守护线程处理串口数据,通过队列将最新状态传递给主线程游戏逻辑即可解决冲突,代码示例如下:
import threading
import queue

# 初始化全局队列,最多存储1条最新数据
sensor_data_queue = queue.Queue(maxsize=1)

def serial_read_worker():
    while True:
        if serialInst.inWaiting():
            packet = serialInst.readline()
            try:
                current_data = int(packet.decode('utf').rstrip('\n'))
                # 清空队列旧数据,保证永远取到最新的传感器状态
                if not sensor_data_queue.empty():
                    sensor_data_queue.get_nowait()
                sensor_data_queue.put_nowait(current_data)
            except ValueError:
                # 忽略解析异常,避免线程崩溃
                continue

# 串口初始化完成后启动线程,daemon=True保证程序退出时线程自动关闭
threading.Thread(target=serial_read_worker, daemon=True).start()

修改后的readData函数直接从队列取值即可:

def readData(self):
    if not sensor_data_queue.empty():
        current_state = sensor_data_queue.get_nowait()
        print(current_state)
        self.last_sensor_state = current_state
    # 无新数据时返回上一次有效状态,避免逻辑中断
    return self.last_sensor_state
  • 简化串口通信协议,降低解析开销
    修改Arduino端输出逻辑,不要发送带换行符的数字字符串,直接发送单字节ASCII字符'0'/'1',Python端改用单字节读取,避免readline等待换行符的阻塞问题。
    Arduino端代码修改示例:
// 替换原有Serial.println(1) / Serial.println(0)逻辑
if (传感器被遮挡) {
  Serial.write('1');
} else {
  Serial.write('0');
}

对应Python端读取逻辑修改:

def readData(self):
    # 清空缓冲区所有旧数据,只保留最后一个字节的最新状态
    while serialInst.inWaiting() > 0:
        latest_byte = serialInst.read(1)
    try:
        data = latest_byte.decode('utf')
        if data == '1':
            print('1')
            self.last_sensor_state = 1
        elif data == '0':
            print('0')
            self.last_sensor_state = 0
    except:
        pass
    return self.last_sensor_state
  • 限制Pygame渲染帧率,减少CPU占用
    在主循环中添加帧率控制,避免pygame.display.update()高频调用占用过多系统资源,给串口读取留足时间片:
# 主循环初始化时创建Clock对象
game_clock = pygame.time.Clock()

while 游戏运行:
    readData()
    # 其他游戏逻辑
    pygame.display.update()
    # 固定30帧,可根据实际需求调整
    game_clock.tick(30)
  • 升级Pygame版本修复M1适配问题
    如果以上方案无效,可更新Pygame到最新版本,M1芯片的渲染阻塞问题在2.1.0及以上版本有大量适配修复,升级命令:
    pip install pygame --upgrade

内容的提问来源于stack exchange,提问作者Josh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:57:03