Хорошо, из hexdump полученных байтов видно, что за каждым символом ASCII следует байт NULL (\x00
). Это просто представление символов в UTF-16-LE. Декодер UTF-8 просто сохраняет кодовые точки начальных байтов, потому что все они ниже 128, оставляя все перемежающиеся нули. И вы не можете просто декодировать байтовую строку как UTF-16 (что это на самом деле), потому что вы получили ее через readline
, который просто остановился после символа новой строки и не прочитал следующий ноль.
Если Вы могли бы прочитать другую строку, она, вероятно, начиналась бы с того нулевого символа, в результате чего строка появлялась бы в кодировке UTF-16-BE ...
Что можно сделать тогда?
Тривиальный обходной путь это просто избавиться от нулевых символов. Если вы можете быть уверены, что получите только простые символы ASCII (без акцентированных символов, таких как é
, без смайликов, без греческих или кириллических c и т. Д. c.), Этого будет достаточно:
RxedData = port.readline()
line = RxedData.replace(b'\x00', b'').decode('ascii')
print("Line 1: ", line)
row = line.split(',')[1:-1]
print("Line 2: ", row)
С этими значениями: ['0x2a', '0x0', '0x2c', '0x0', '0x30', '0x0', '0x30', '0x0', '0x30', '0x0', '0x30', '0x0', '0x30', '0x0', '0x30', '0x0', '0x30', '0x0', '0x31', '0x0', '0x2c', '0x0', '0x31', '0x0', '0x31', '0x0', '0x3a', '0x0', '0x35', '0x0', '0x31', '0x0', '0x3a', '0x0', '0x35', '0x0', '0x30', '0x0', '0x2c', '0x0', '0x31', '0x0', '0x33', '0x0', '0x2f', '0x0', '0x30', '0x0', '0x32', '0x0', '0x2f', '0x0', '0x32', '0x0', '0x30', '0x0', '0x2c', '0x0', '0x31', '0x0', '0x32', '0x0', '0x2e', '0x0', '0x33', '0x0', '0x34', '0x0', '0x35', '0x0', '0x2c', '0x0', '0x4b', '0x0', '0x50', '0x0', '0x41', '0x0', '0x2c', '0x0', '0x31', '0x0', '0x32', '0x0', '0x33', '0x0', '0x34', '0x0', '0x35', '0x0', '0x2e', '0x0', '0x36', '0x0', '0x36', '0x0', '0x2c', '0x0', '0x53', '0x0', '0x4c', '0x0', '0x50', '0x0', '0x48', '0x0', '0x2c', '0x0', '0x0', '0x0', '0x0', '0x0', '0x2c', '0x0', '0x2d', '0x0', '0x2d', '0x0', '0x2d', '0x0', '0x2d', '0x0', '0x2d', '0x0', '0x2d', '0x0', '0x2d', '0x0', '0x2d', '0x0', '0x2c', '0x0', '0x24', '0x0', '0xa']
вы должны получить:
Line 1: *,00000001,11:51:50,13/02/20,12.345,KPA,12345.66,SLPH,,--------,$
Line 2: ['00000001', '11:51:50', '13/02/20', '12.345', 'KPA', '12345.66', 'SLPH', '', '--------']
Хорошая точка зрения в том, что это просто и надежно при условии, что у вас есть только простой ASCII
Ожидание, соответствующее кодированию, будет заключаться в использовании TextIOWrapper вокруг последовательного порта и указании в нем кодировки UTF-16-LE. Я не смог протестировать его (нет серийного номера на моем боксе и не нужно), поэтому только догадываясь, что нужно сделать.
COM_Port = serial.Serial(COM_PortName)
with io.TextIOWrapper(io.BufferedRWPair(COM_Port, COM_Port), encoding = 'utf-16-le') as port:
while True:
line = port.readline()
print("Line 1: ", line)
row = line.split(',')[1:-1]
print("Line 2: ", row)
Здесь TextIOWrapper позаботится о нулевом байте, следующем за байтом новой строки, и даст вам прямо истинные строки Unicode.