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

树莓派GSM/GPRS/GNSS HAT用Python读GPS报OSError: [Errno 5]错误

问题原因分析
  • 串口硬件/系统配置异常:树莓派3默认/dev/ttyS0是性能较差的mini串口,绑定蓝牙模块,重启后可能因为配置回退导致蓝牙重新占用串口,引发底层IO调用失败;SIM868模块峰值工作电流较高,仅靠树莓派GPIO供电不足时也会触发串口IO错误。
  • 代码逻辑缺陷:错误捕获后采用递归调用重新启动函数的逻辑,会导致旧串口句柄无法彻底释放,多次报错后串口资源被占满,触发ioctl调用失败;未设置串口超时、主动查询+自动输出NMEA的AT指令冲突,也可能导致模块串口挂死。
  • 模块状态异常:GNSS模块长时间运行后出现固件死锁,重启树莓派时未同步复位扩展板模块,导致模块处于异常工作状态,响应串口请求时报错。
排查解决步骤

1. 硬件与系统配置修复

  • 禁用树莓派蓝牙、切换硬件串口:执行sudo raspi-config,选择「Interface Options」-「Serial」,关闭串口登录shell、开启硬件串口功能;编辑/boot/firmware/config.txt(旧系统为/boot/config.txt),添加两行配置:
    dtoverlay=disable-bt
    enable_uart=1
    
    执行sudo systemctl disable hciuart禁用蓝牙服务后重启设备,确认串口映射无误后,将代码中串口路径改为/dev/serial0(硬件串口的统一软链接,稳定性远高于ttyS0)。
  • 优化供电:给GSM/GNSS扩展板单独接外部5V 2A供电,不要完全依赖树莓派GPIO引脚供电,避免峰值电流不足导致的模块异常。

2. 代码逻辑修改

  • 移除递归重试逻辑:递归调用会导致栈溢出、资源释放不完全,将错误后的重启逻辑改为循环重试,不要递归调用函数本身。
  • 优化串口初始化参数:添加超时配置,避免串口读取卡死:
    ser = serial.Serial("/dev/serial0", baudrate=115200, timeout=2, inter_byte_timeout=0.1)
    
  • 简化AT指令逻辑:移除AT+CGNSTST=1指令,主动查询CGNSINF的场景下不需要开启自动NMEA输出,两种模式冲突会导致模块串口挂死。
  • 优化缓冲区读取逻辑:pyserial 3.x版本推荐用in_waiting替代旧的inWaiting()方法,添加读取间隔与编码错误忽略,避免乱码报错:
    time.sleep(0.1)
    while ser.in_waiting > 0:
        data += ser.read(ser.in_waiting).decode('utf-8', errors='ignore')
        time.sleep(0.05)
    
  • 错误处理添加模块复位逻辑:捕获到IO错误时,除关闭串口外,可先发送AT+CGNSPWR=0关闭GNSS模块,延时1秒后再重新初始化,避免模块状态死锁。

3. 底层验证

安装minicom工具执行minicom -b 115200 -D /dev/serial0,手动发送AT指令测试串口稳定性,如果minicom下也出现IO错误,可直接确认是硬件供电或模块本身故障,排查接线或更换扩展板即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:48:02