Прекратить чтение байтов из последовательного порта (Python/RPi/UART)
Эта проблема довольно сложная. Кажется, у меня есть простая двусторонняя связь между двумя устройствами, где сторона чтения - Raspberry pi 3. Я пытаюсь передать файл. Я отправляю его по частям (5kb часть). Это выглядит как:
1) Отправляющая сторона отправляет первые 5 Кбайт (ровно 5136 байт, где первые 16 байт являются ID / SIZE / ADD_INFO / CRC)
2) RPi3 считывает 5136 байтов и вычисляет CRC для порции.
3) RPi3 сравнить CRC, полученный от отправляющей стороны и рассчитанный по RPi
4a) Если CRC не совпадает, я переключаю линии с линии RX на линию TX с помощью буфера с двойной шиной с выходами с 3 состояниями и устанавливаю High State на линию TX (я сохраняю это в течение 30 мс).
4b) Если CRC совпадает, я просто жду следующего фрагмента файла
5) Команды переключателя отправляющей стороны тоже и считывают мое состояние TX, если состояние HIGH/1 (когда CRC не совпадает), он отправляет тот же блок (повторную передачу), если состояние LOW/0 отправляет другой блок. (изменение состояния занимает 10 мс)
На осциллографе это выглядит так (4а):
и это (4b):
У блока 5136 есть свободное время для вычисления CRC, тогда у нас есть изменение состояния на стороне RPi3, если нужно, потому что CRC не совпадает (красные линии на 4a) и чтение стороны TX со стороны отправки.
Хорошо, теперь немного упрощенного кода из RPi:
def recv():
while True:
#Set line to low because I want to read data
GPIO.output(16, GPIO.LOW)
ID = ser.read(4)
SIZE = ser.read(4)
ADD_INFO = ser.read(4)
CRC = ser.read(4)
#get crc from sending side
crc_chunk = int.from_bytes(CRC, byteorder='little')
data = ser.read(5120)
#calculating CRC from chunk
rpiCRC = crcSTM(data)
while True:
<--- here I wait about 20ms to calculate CRC
if rpiCRC != crc_chunk:
#Crc doesn't match I want retransmission
GPIO.output(16, GPIO.HIGH)
<--- keep it HIGH for about 30ms
break
else:
#keep it low because crc match and we are waiting for next chunk
GPIO.output(16, GPIO.HIGH)
break
Все это выглядит законным, но по существу. Я всегда получаю только первый кусок после того, как RPi просто перестает читать байты. Это происходит только в том случае, если в "4b" я получаю первый кусок правильно и жду следующего, а затем RPi просто прекращает читать байты или время от времени дает мне лишь некоторые царапины. Я проверяю, что если я правильно получу первый блок и настроил ретрансляцию, но все выглядит великолепно, и я получаю все время повторную передачу первого блока и получаю все время. Я пришел к этому, что изменение строки на отправляющей стороне, когда у меня есть состояние LOW/1, влияет на RPi и просто перестает правильно читать байты. Не знаю, почему это портит, и не знаю, как с этим бороться. Я попытался очистить буфер, закрыв порт перед отправкой боковой строки изменения и открыв ее после повторного изменения строки, но все это просто ничего не делает, что я могу сделать еще?
PS Это ожидание, что я делаю в своем собственном таймере, но нет необходимости помещать сюда код, такой как код со стороны отправителя, потому что проблема на стороне RPi. PS извините за хаотичный язык, но я пытался объяснить это так просто, как я могу
1 ответ
Хорошо, я борюсь с этим. Я включил опцию "Хотите ли вы, чтобы оболочка входа была доступна через последовательный порт" в sudo raspi-congif
, Не знаю, почему это все портит, но отключить это исправить. Это довольно странно, потому что я некоторое время играю с Raspberry и Serial, и не было никаких проблем, если RPi3 отправлял что-то через uart или когда он просто читал без изменения строк и т. Д.:)