Python读取串口时cal数据随机停止写入文件问题求助
串口读取cal数据异常问题
我正在从串口读取数据并写入文本文件,但无论如何设置cal,程序总会在几秒后停止读取cal数据或停止写入其输出,mm和light相关数据运行完全正常。
我已经尝试过:
- 移除延迟
- 提高波特率
- 在循环中添加打印语句排查卡顿(看起来一切正常)
单独编写仅处理cal数据的相似程序时运行正常,不清楚问题出在哪里。
相关代码
with open(path + r"\mm_response.txt", "w") as f, open(path + r"\cal_response.txt", "w") as h, open(path + r"\light_response.txt", "w") as g: while main.a == 1: #continuosly send 89 hex command to receive data back from mm ser_mm.write(serial.to_bytes([0x89])) #read serial data if lux == 1 and cal == 1: response_mm = ser_mm.readline(12) response_light = ser_light.read(16) response_cal = ser_cal.readline() elif lux == 1 and cal == 0: response_mm = ser_mm.readline(12) response_light = ser_light.read(16) response_cal = 0 elif lux == 0 and cal == 1: response_mm = ser_mm.readline(12) response_light = 0 response_cal = ser_cal.readline() elif lux == 0 and cal == 0: response_mm = ser_mm.readline(12) response_light = 0 response_cal = 0 else: response_mm = ser_mm.readline(12) response_light = 0 response_cal = 0 #remove special characters from multimeter data response_mm = str(response_mm) response_mm = ''.join(letter for letter in response_mm if letter.isalnum()) #remove special characters from light data response_light = str(response_light) response_light = ''.join(letter for letter in response_light if letter.isalnum()) #remove special characters from multimeter data response_cal = str(response_cal) response_cal = ''.join(letter for letter in response_cal if letter.isalnum()) #record null value from light meter as zero reading response_light = response_light.replace("x19", "0") #remove special characters from light data response_cal = response_cal.replace("b", "0") #record values g.write(response_light) g.flush() f.write(response_mm) f.flush() h.write(response_cal) h.flush() #add delay so there aren't thousands of data points time.sleep(0.0001)
可能的原因及修复方案
1. 串口读取阻塞导致同步异常
当前代码中三个串口的读取操作是同步串行执行的,一旦某一个读取未及时返回,会阻塞后续操作。多串口同时运行时,cal的串口读取可能被其他操作抢占资源,导致缓冲区堆积后无法正常读取。
修复: 给cal串口添加超时设置,避免永久阻塞。初始化串口时指定超时时间:
# 示例:初始化cal串口时添加timeout参数 ser_cal = serial.Serial(port='COMx', baudrate=9600, timeout=0.1)
2. cal数据处理逻辑存在漏洞
当response_cal为空字节串时,str(response_cal)会转为"b''",经过isalnum()过滤后变成空字符串,后续的replace("b", "0")不会生效,写入文件的是空内容,看起来像是停止了输出。单独运行时数据量小,问题未暴露;多串口运行时,空数据被高频写入,掩盖了正常数据。
修复: 优化cal的数据处理逻辑,先判断数据有效性:
# 替换原cal数据处理代码 if isinstance(response_cal, bytes): # 先解码为字符串,忽略编码错误 cal_str = response_cal.decode('utf-8', errors='ignore').strip() # 空值或无效值转为0,否则保留有效字符 response_cal = cal_str if cal_str.isalnum() else '0' else: response_cal = '0'
3. 循环频率过高耗尽CPU资源
time.sleep(0.0001)意味着每秒执行10000次循环,CPU占用过高会导致串口驱动无法及时处理cal的数据。单独运行时CPU资源充足,问题不明显;多串口同时运行时,资源不足导致cal的串口处理被延迟。
修复: 适当提高延迟时间,比如改为time.sleep(0.01)(每秒100次循环),既控制数据量,也给串口驱动留出处理时间。
4. 文件写入的隐性冲突
尽管调用了flush(),但高频同时写入三个文件可能导致文件句柄的隐性阻塞。可以调整写入顺序,或者给cal的文件写入单独设置缓冲策略。
内容的提问来源于stack exchange,提问作者Theodore Leon
相关产品推荐
相关产品推荐

