Я хочу написать программу, которая взаимодействует с интеллектуальными счетчиками (электричество, тепло и т. Д.) По протоколу Метр-шина . У меня есть M-Bus <-> RS232 конвертер и RS232 <-> USB.
Когда я тестирую свой скрипт Python с помощью теплосчетчика, отправляя ему команду, он отвечает мне длинным, но правильным кадром, а затем, если я запрашиваю его снова вскоре после того, как получаю только частичный ответ кадра. Ожидание около 30 секунд помогает правильно получить весь кадр. Этот частичный ответ всегда один и тот же.
Кадры учета теплосчетчиков
Но с счетчиком электроэнергии он всегда один и тот же, хотя весь правильный кадр будет короче, чем у счетчика тепла, я всегда получаю только такую же часть (чуть более половины байтов и никогда не начало). Кадры ответа счетчика электроэнергии
Также есть команда, которая инициализирует ведомое устройство - ведомое устройство отвечает '\ xE5', хотя я вижу мигание диода Rx, я не могу поймать этот единственный байт.
Что я пробовал:
Я пытался прочитать определенно больше байтов, чем могло быть в моем буфере, как ser.read(500)
Пробовал с использованием ser.inwaiting
, но он вернул бы 0, пока я не использовал time.sleep(1)
до этого
Загрузка кусков байтов из pySerial inWaiting возвращает неверное количество байтов
Управление 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)
Я отслеживал кадры M-Bus с EMU и мой последовательный порт с Serial Port Monitor . Кадры, отправленные и полученные EMU, всегда правильные, как и в Serial Monitor. Если я использую свой код для отправки и получения фреймов, Serial Monitor получает те же результаты, что и в моем терминале - он видит неправильные, «нарезанные» фреймы.
Устройства отвечают только после получения правильных запросов (я вижу, мигает диод Rx).
Я не знаю, есть ли проблема с многопоточностью, или с буфером, или, может быть, сценарий Python недостаточно быстр, чтобы перехватить все байты из буфера?