我想编写一个通过Meter-Bus协议与智能电表(电,热等)通信的程序。我有一个M-Bus <-> RS232转换器和RS232 <-> USB。
当我用热量计测试我的Python脚本时,通过发送命令以长而正确的帧响应我,然后如果我仅得到部分帧响应后不久再次查询它。等待30秒钟左右有助于正确获得整个画面。 部分响应始终相同。 Heat meter respond frames
但是使用电表时,它总是相同的,尽管整个正确的框架要比使用电表时要短,但我总是得到它的相同部分(少半字节)从来没有开始)。 Electricity meter respond frames
还有一个初始化从属设备的命令-从属设备以'\ 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脚本的速度不足以捕获缓冲区中的所有字节?