Солнечный инвертор (Delta RPI M6A) имеет магистральную шину RS485. Мастер запрашивает инвертор несколько раз в секунду для отправки набора данных ответа, который затем делает инвертор. Общий набор связи составляет 176 байт. Raspberry Pi 3B подключается к этой шине с использованием конвертера ICI FT-232 (USB-последовательный) (FT-32).Отсутствие байтов при чтении данных RS485 с использованием pySerial (инвертор солнечной батареи Delta)
Программа Python используется для чтения данных, передаваемых по шине. Это прекрасно работает, только если нет байтов, которые интерпретируются как специальные символы (по крайней мере, это то, что я думаю). Я сначала прочитал ввод 1 байт за раз. После того, как была найдена правильная последовательность «начала передачи» (STX, за которой следует ACK, за которым следует инверторID = 1), тогда ожидается набор данных из 160 байтов плюс конечная последовательность. Последнее байтовое чтение должно быть ETX (= ascii 3).
Ожидаемый результат: Screenshot of expected output
Я думаю, что проблема в том, что если некоторые из байтов являются эквивалентом специальных символов, таких как побег или перевод строки, то эти байты не «видели» в ser.read(). Затем я получу байт ETX на несколько байт раньше, указав, что некоторые байты где-то посередине не были захвачены.
Соответствующая часть кода:
if bytes_to_read == 1:
raw_data = ser.read()
pos = pos + 1;
# print pos;
if ord(raw_data) == 2: # 2 = start of text character
pos = 1;
print str(pos) + ' ' + str(ord(raw_data))
elif pos == 2 and ord(raw_data) == 6: # 6 = acknowledge character
ack = True;
print str(pos) + ' ' + str(ord(raw_data))
elif pos == 2 and ord(raw_data) != 6: # 6 = acknowledge character
ack = False;
print str(pos) + ' ' + str(ord(raw_data)) + ' ack reset to False'
elif pos == 3 and ack and ord(raw_data) == 1:
bytes_to_read = 164;
print str(pos) + ' ' + str(ord(raw_data))
elif bytes_to_read == 164:
raw_data_byte = ser.read(164)
print len(raw_data_byte);
bytes_to_read = 1;
ack = False;
print 'got to read 164 bytes, first byte is ' + str(ord(raw_data_byte[0])) + ', last byte: ' + str(ord(raw_data_byte[163]));
if ord(raw_data_byte[0]) == 160 and ord(raw_data_byte[163]) == 3: # 160 = data bytes specified by sender
print ('ready to process ' + str(len(raw_data_byte)) + ' bytes')
supplied_power_byte1 = bin(ord(raw_data_byte[101]))[2:].zfill(8)
supplied_power_byte2 = bin(ord(raw_data_byte[102]))[2:].zfill(8)
Захваченные байты позже обработаны, чтобы разрешить запись в базу данных.
Я пробовал ser.read() и ser.readline() с тем же результатом.
Я был бы признателен за любые намеки, которые укажут мне в правильном направлении.
Спасибо, Bram