Обработка необработанных данных, считанных из последовательного порта, с помощью последовательной библиотеки Python?

Я не программист на Python, а скорее разработчик электронных схем, однако на этот раз я должен обработать некоторые необработанные данные, отправленные микроконтроллером через порт RS232 в сценарий Python (который вызывается сценарием PHP).

Я потратил довольно много часов, пытаясь определить лучшие способы чтения необработанных байтов из последовательного (RS232) порта с использованием Python, и я получил результаты, но я хотел бы, чтобы кто-нибудь мог прояснить некоторые несоответствия, которые я заметил во время исследования, и вот они являются:

1:
Я вижу, что многих людей, задававших аналогичный вопрос, спрашивали, используют ли они модуль serial или pySerial и как они устанавливали последовательную библиотеку. Могу только сказать, что я действительно не знаю, какой модуль я использую, поскольку модуль работал «из коробки». Где-то я читал serial и pySerial это одно и то же, но я не могу найти, правда ли это. Все, что я знаю, это то, что я использую Python 2.7.9 с ОС Raspbian.

2:
Я читал, что есть методы read() и readline() для чтения из последовательного порта, но в pySerial API docs не упоминается readline() метод. Более того, я обнаружил, что аргумент «количество байтов для чтения» может быть передан в метод readline(), а также в метод read() (и работает таким же образом, ограничивая количество байтов для чтения), но я не могу найти это для документирования. .

3:
При поиске способа определить, были ли прочитаны все данные из буфера RS232, у меня есть здесь нашел следующий код:

read_byte = ser.read()
while read_byte is not None:
    read_byte = ser.read()
    print '%x' % ord(read_byte)

но это приводит к:

Traceback (most recent call last):
  File "./testread.py", line 53, in <module>
    read_all()
  File "./testread.py", line 32, in read_all
    print '%x' % ord(read_byte)
TypeError: ord() expected a character, but string of length 0 found

после чтения последнего байта из буфера, и я смог обнаружить пустой буфер только с помощью следующего кода:

while True:
    c = rs232.read()
    if len(c) == 0:
        break
    print int(c.encode("hex"), 16), " ",

поэтому я не уверен, что код, который у меня не сработал, предназначен для какой-то библиотеки последовательного интерфейса, отличной от моей. Мой код для порта openinig - BTW:

rs232 = serial.Serial(
    port = '/dev/ttyUSB0',
    baudrate = 2400,
    parity = serial.PARITY_NONE,
    stopbits = serial.STOPBITS_ONE,
    bytesize = serial.EIGHTBITS,
    timeout = 1
)

4:
Данные, которые я получаю от микроконтроллера, имеют следующий формат:

0x16 0x02 0x0b 0xc9 ... 0x0d 0x0a

Это some raw bytes + \r\n. Поскольку «сырые байты» могут содержать 0x00, может ли кто-нибудь подтвердить, что чтение байтов в строковую переменную Python не является проблемой? Насколько я понимаю, это должно работать, но я не уверен на 100%.


person Chupo_cro    schedule 22.10.2016    source источник


Ответы (1)


PySerial работает для меня, хотя я не использовал его на Pi.

3: Read () возвращает строку - она ​​будет нулевой длины, если данные не считываются, поэтому ваша более поздняя версия верна. Поскольку строка не является символом, вы должны использовать, например, ord (read_byte [0]) для печати числа, соответствующего первому символу (если длина строки> 0) Ваша функция:

while True:
    c = rs232.read()
    if len(c) == 0:
        break
    print int(c.encode("hex"), 16), " ",

Требуется что-то добавить для накопления прочитанных данных, иначе они будут выброшены

rcvd = ""
while True:
    c = rs232.read()
    if len(c) == 0:
        break
    rcvd += c
    for ch in c:
        print ord(ch), " ",

4: Да, вы можете получить и поместить в строку нулевые (0x00) байты. Например:

a="\x00"
print len(a)

напечатает длину 1

person barny    schedule 22.10.2016
comment
Разве «Да, вы можете, но 0 байтов в строке» означает: «Да, вы можете, но без нулевых байтов в строке»? Я хотел бы знать, например, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, полученный от RS232 и присвоенный строковой переменной, может вызвать проблемы. Насколько я понимаю, внутреннее строковое представление - это строки C с завершающим нулем, но я не могу найти, можно ли хранить нули в высокоуровневом представлении, несмотря на внутреннее представление. - person Chupo_cro; 25.10.2016
comment
Внутреннее представление строк в обычном Python, который мы используем в Linux / Windows, не заканчивается нулем. Вы можете поместить в строку любые символы значений. - person barny; 25.10.2016
comment
Это означало бы, что этот проголосовавший за ответ говорит: «Самая популярная реализация Python внутри написана на C, так что, вероятно, где-то под капотом есть строка с завершающим NULL. ', не так? - person Chupo_cro; 25.10.2016
comment
Кстати, я не могу больше редактировать (в течение первых 5 минут после публикации) или удалять свои собственные комментарии, так как при наведении курсора мыши нет значка x (или чего-то еще). Функции раньше работали нормально, но больше не работают. Проблема в точности такая, как описано здесь. К сожалению, у меня недостаточно очков репутации, чтобы оставить комментарий, подтверждающий проблему. Примечание: у меня не так много очков репутации, но я знаю, как раньше работала функция редактирования / удаления собственных комментариев. - person Chupo_cro; 25.10.2016
comment
Этот ответ верен только в том случае, если сказать, что реализация строки непрозрачна для разработчика, пишущего на Python, и определенно неверно в отношении реализации с использованием нулевого завершения, как прокомментировал Джозия Йодер. - person barny; 25.10.2016
comment
Вы можете редактировать комментарий только в течение нескольких минут после публикации, но вы должны иметь возможность удалять свои собственные комментарии - я получаю X - попробовать другой браузер? - person barny; 25.10.2016
comment
Да, я сказал, что редактирование будет работать «в течение первых 5 минут после публикации». Тем временем я опубликовал подтверждение проблемы, включая скриншоты, в качестве «ответа» на вопрос, который я упомянул. Поскольку у меня недостаточно очков репутации, отправка «ответа» была единственным способом, которым я мог ответить. Судя по полученным мною голосам, эта проблема затронула больше пользователей. Более того, несколько часов назад оценка вопроса была -5, а теперь оценка +1, что означает, что у других такая же проблема. Да, я пробовал использовать FF и Chrome, и результат был тот же - нет X больше. - person Chupo_cro; 25.10.2016