树莓派SIM7600G-H 4G HAT读取SIM卡短信时ser.read()无返回问题
树莓派SIM7600G-H模块读取短信异常排查
原问题描述
在树莓派4上搭载SIM7600G-H 4G HAT模块并插入SIM卡,尝试用Python脚本读取SIM卡中的短信,但ser.read()步骤无任何输出。
使用的Python代码
import serial import time ser = serial.Serial('/dev/ttyS0',115200, timeout=1) ser.write(b'AT+CMGF=1\r\n') time.sleep(1) ser.write(b'AT+CMGL=\"ALL\"\r\n') time.sleep(1) response = ser.read().decode() print(response) # 无任何输出
minicom中的输出(运行脚本时)
AT+CMGF=1 OK AT+CMGL=\"ALL\" +CMGL: 0; \"REC READ\",\"+1XXXXXXXXXXXXXX\",\"24/04/19, xx:xx:xx-xx\" TEST1 +CMGL: 0; \"REC READ\",\"+1XXXXXXXXXXXXXX\",\"24/04/19, xx:xx:xx-xx\" TEST2 +CMGL: 0; \"REC READ\",\"+1XXXXXXXXXXXXXX\",\"24/04/19, xx:xx:xx-xx\" TEST3 OK
后续测试与新问题
- 将串口
timeout从1改为5,脚本运行后立即向SIM卡发送一条新消息,成功读取到所有短信。 - 重启树莓派后把
timeout改回1,不发新消息再次运行脚本,仍能读取所有短信。 - 但把读取短信的逻辑封装成函数嵌入到更大的Python脚本中时,无任何输出;且原本正常的独立脚本也无法再读取短信了。
问题分析与解决方案
1. 原问题:ser.read()无输出的原因
ser.read()默认只读取1个字节,而串口返回的短信内容是大量数据,单个字节可能为空或未被正确捕获;加上原脚本timeout=1可能不足以让模块返回完整内容,导致读取不到有效输出。
2. 解决原问题的修改建议
- 改用
ser.read_all()读取串口缓冲区所有内容,或用ser.readlines()按行读取 - 调整超时时间,确保模块有足够时间返回数据
- 增加缓冲区清空步骤,避免残留数据干扰
修改后的示例代码:
import serial import time ser = serial.Serial('/dev/ttyS0', 115200, timeout=3) # 先清空缓冲区残留数据 ser.flushInput() ser.write(b'AT+CMGF=1\r\n') time.sleep(0.5) # 读取AT+CMGF=1的响应,避免干扰后续指令 ser.read_all() ser.write(b'AT+CMGL="ALL"\r\n') time.sleep(1) response = ser.read_all().decode('utf-8', errors='ignore') print(response) # 关闭串口,避免资源占用 ser.close()
3. 嵌入函数后异常的排查方向
- 串口资源未释放:如果函数中重复创建
serial.Serial实例但未关闭,会导致串口被占用,后续脚本无法访问。确保每次使用后调用ser.close(),或用上下文管理器with自动管理:def read_sms(): with serial.Serial('/dev/ttyS0', 115200, timeout=3) as ser: ser.flushInput() ser.write(b'AT+CMGF=1\r\n') time.sleep(0.5) ser.read_all() ser.write(b'AT+CMGL="ALL"\r\n') time.sleep(1) return ser.read_all().decode('utf-8', errors='ignore') - 超时设置不合理:嵌入大脚本后,其他操作可能占用系统资源,导致模块返回数据变慢,需适当延长
timeout时间。 - 缓冲区残留数据:大脚本中可能有其他串口操作,导致缓冲区有残留数据,每次读取前必须调用
ser.flushInput()清空。 - 权限问题:运行大脚本时的用户权限可能和独立脚本不同,确保当前用户对
/dev/ttyS0有读写权限(可通过sudo usermod -a -G dialout pi添加权限)。
内容的提问来源于stack exchange,提问作者Helen
相关产品推荐
相关产品推荐

