python - PySerial read() 错过了帧数据的开头
问题描述
我想编写一个通过Meter-Bus协议与智能仪表(电、热等)通信的程序。我有一个 M-Bus <-> RS232 转换器和 RS232 <-> USB。
当我用热量计测试我的 Python 脚本时,通过向它发送一个命令,它会以一个长而正确的帧响应我,然后如果我在只得到部分帧响应后不久再次查询它。等待大约 30 秒有助于正确获取整个帧。这种部分响应总是相同的。 热量表响应帧
但是对于电表,它总是一样的,尽管整个正确的帧会比热量表的情况短,但我总是只得到它的相同部分(略多于一半的字节,从来没有开始)。电表响应帧
还有一个初始化从属的命令——从属用“\xE5”响应,即使我看到 Rx 二极管闪烁,我也无法捕捉到这个单字节。
我试过的:
我尝试读取的字节肯定比缓冲区中的字节多
ser.read(500)
尝试使用
ser.inwaiting
,但它会返回 0,直到我使用time.sleep(1)
它之前操纵
xonxoff
参数和timeout
。
一切都没有效果。
import serial
import time
def ser_to_mbus():
ser = serial.Serial(
port='COM4',
baudrate=2400,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE,
timeout=2,
#write_timeout=1,
xonxoff=False,
rtscts=False,
dsrdtr=False,
#inter_byte_timeout=0.01,
)
# Should receive a hex response '\xE5' with command below.
#to_send = b'\x68\x0B\x0B\x68\x73\xFD\x52\x84\x11\x10\x00\xFF\xFF\xFF\xFF\x63\x16'
#to_send = b'\x10\x7B\x01\x7C\x16' # heat meter request frame
to_send = b'\x10\x7B\xFD\x78\x16' # electricity meter request frame
ser.write(to_send)
ser.close()
def mbus_to_ser():
ser = serial.Serial(
port='COM4',
baudrate=2400,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE,
timeout=1,
#write_timeout=1,
xonxoff=1,
rtscts=False,
dsrdtr=False,
#inter_byte_timeout=0.2,
)
time.sleep(1) # Otherwise ser.in_waiting is empty.
buffer_size = ser.in_waiting
frame = ser.read(buffer_size)
return frame
ser_to_mbus()
frame = mbus_to_ser()
print(frame)
我一直在使用EMU监视 M-Bus 帧,并使用Serial Port Monitor 监视我的串行端口。EMU 发送和接收的帧总是正确的,串行监视器也是如此。如果我使用我的代码发送和接收帧,串行监视器会得到与我在终端中所做的相同的结果——它会看到错误的“切片”帧。
设备只有在收到正确的请求后才会响应(我看到 Rx 二极管闪烁)。
我不知道线程是否存在问题,或者缓冲区是否存在问题,或者 Python 脚本是否速度不够快,无法从缓冲区中捕获所有字节?
解决方案
推荐阅读
- javascript - 无法仅获取 fileList 中的 FILE,因为它显示了数组和单词 File
- ruby-on-rails - Rails ActiveStorage 是附加的吗?是的,但不符合 rspec 的预期
- sql - 将 SQL 值从链接数据重新编码/转换为新列:为什么 CASE WHEN 返回多个值?
- integration-testing - 为 citrus 中的所有服务全局存储 JWT 访问令牌
- objective-c - 包含 UITableView 的 UITableViewCell 的自适应高度
- javascript - 收到错误“TypeError:无法读取未定义的属性‘通道’”
- javascript - Android webview - 在 javascript 中加载 katex
- spring - SOAP 服务调用中的命名空间不正确
- javascript - 未捕获的类型错误:无法读取未定义的属性(读取“错误”)
- python - 如何使芹菜任务使用工人的进程池?