pySerial: невозможно прочитать данные более 8 символов

Я использую pyserial для записи и чтения между двумя Raspberry Pi через UART.

Raspberry pi 1: отправить данные на Raspberry pi 2

    while 1:
        ser=serial.Serial('/dev/ttyAMA0')
        if not ser.isOpen():
            ser.open()
        msg=raw_input('RPi 1 send:')
        ser.write(msg)
        ser.close()

Raspberry pi 2: получение данных от Raspberry pi 1

    while 1:
        ser=serial.Serial('/dev/ttyAMA0' ,timeout=0)
        if not ser.isOpen():
            ser.open()
        data=ser.read(1024)
        if data.__len__()>0:
            print 'RPi 2 receive:',data
        ser.close()

Я запускаю оба кода.

и отправить данные

    RPi 1 send : Hello

и получать данные

    RPi 2 receive : Hello

Но если RPi 1 отправляет данные более 8 символов

Например

    RPi 1 send : Hello Raspberry pi NO.2

Результат

    RPi 2 receive: Hello Ra
    RPi 2 receive: spberry 
    RPi 2 receive: pi NO.2

Это моя проблема. Потому что я хочу, чтобы он получил вот так

(RPi 2 получает: Hello Raspberry pi NO.2) # показать только одну строку.

и если отправить (более 8 символов) снова, он появится в новой строке.

Какой код соединить его в одну строку? или другой способ сделать это? :)


person Wittaya    schedule 27.01.2014    source источник
comment
read() читает только то, что готово в данный момент.   -  person cmd    schedule 27.01.2014


Ответы (2)


мне нравится это делать

отправитель.py

delim = "\x00"
ser.write(msg+delim)

приемник.py

delim = "\x00"
recvd = "".join(iter(lambda:ser.read(1),delim))
print recvd
person Joran Beasley    schedule 27.01.2014
comment
Теперь я редактирую код с вашим предложением, и он отображается правильно. но я новичок в python, и я не знаю, почему вы добавляете delim? и почему разделитель должен быть \x00 ? Как работает эта строка .join(iter(lambda:ser.read(1),delim))? Не могли бы вы описать этот код для меня? так что большое спасибо за ответ :) - person Wittaya; 28.01.2014
comment
эта строка просто говорит, продолжайте читать, пока мы не получим наш разделитель... вы можете использовать любой разделитель, который хотите... однако \0 (почти) никогда не будет (почти) в фактическом содержимом сообщения, поэтому его хорошо использовать - person Joran Beasley; 28.01.2014

При чтении с использованием ser.read вы просто читаете то, что уже находится в буфере, или ждете поступления символов в буфер. Указанный вами размер представляет собой максимальное количество символов, которые можно получить, но, как вы уже поняли, он может быть намного меньше.

У вас есть 2 простых решения:

  1. используйте ser.readline и поместите терминатор в свои строки (например, \n)
  2. если вы заранее знаете, сколько символов читать, повторяйте чтение, пока не получите их все

В обоих случаях укажите тайм-аут (например, 1 секунду) при открытии последовательной линии, чтобы вернуть контроль над своим кодом, если удаленный конец по какой-либо причине ничего не отправляет.

Надеюсь, поможет.

person mguijarr    schedule 27.01.2014