Python Serial: как использовать функцию read или readline для чтения более 1 символа за раз

У меня проблемы с чтением более чем одного символа с помощью моей программы, я не могу понять, что пошло не так с моей программой.

import serial

ser = serial.Serial(
    port='COM5',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
        timeout=0)

print("connected to: " + ser.portstr)
count=1

while True:
    for line in ser.read():

        print(str(count) + str(': ') + chr(line) )
        count = count+1

ser.close()

вот результаты, которые я получаю

connected to: COM5
1: 1
2: 2
3: 4
4: 3
5: 1

на самом деле я ожидал этого

connected to: COM5
1:12431
2:12431

что-то вроде вышеупомянутого, которое способно читать несколько символов одновременно, а не один за другим.

Ответ 1

Я вижу пару вопросов.

Первый:

ser.read() будет возвращать только 1 байт за раз.

Если вы укажете счет

ser.read(5)

он будет читать 5 байт (меньше, если тайм-аут возникает до появления 5 байтов).

Если вы знаете, что ваш вход всегда правильно завершен символами EOL, лучше использовать

ser.readline()

Это будет продолжать читать символы до тех пор, пока не будет получен EOL.

Во-вторых:

Даже если вы получаете ser.read() или ser.readline(), чтобы возвращать несколько байтов, поскольку вы повторяете возвращаемое значение, вы все равно будете обрабатывать его по одному байту за раз.

Избавиться от

for line in ser.read():

и просто скажите:

line = ser.readline()

Ответ 2

Серийные данные отправляют 8 бит за раз, что переводится в 1 байт, а 1 байт - 1 символ.

Вам нужно реализовать свой собственный метод, который может считывать символы в буфер до тех пор, пока не будет достигнут какой-либо дозор. Соглашение заключается в отправке сообщения типа 12431\n указанием одной строки.

Итак, вам нужно реализовать буфер, в котором будет храниться X количество символов, и как только вы достигнете этого \n, выполните свою операцию в строке и перейдите к следующей строке в буфер.

Обратите внимание, что вам придется позаботиться о случаях переполнения буфера, т.е. Когда полученная строка длиннее вашего буфера и т.д....

РЕДАКТИРОВАТЬ

import serial

ser = serial.Serial(
    port='COM5',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
        timeout=0)

print("connected to: " + ser.portstr)

#this will store the line
line = []

while True:
    for c in ser.read():
        line.append(c)
        if c == '\n':
            print("Line: " + ''.join(line))
            line = []
            break

ser.close()

Ответ 3

Я использую этот небольшой метод для чтения последовательного монитора Arduino с Python

import serial
ser = serial.Serial("COM11", 9600)
while True:
     cc=str(ser.readline())
     print(cc[2:][:-5])

Ответ 4

Я получал некоторую дату от моего arduino uno (0-1023 номера). Используя код от 1337holiday, jwygralak67 и некоторые советы из других источников:

import serial
import time

ser = serial.Serial(
    port='COM4',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
        timeout=0)

print("connected to: " + ser.portstr)

#this will store the line
seq = []
count = 1

while True:
    for c in ser.read():
        seq.append(chr(c)) #convert from ANSII
        joined_seq = ''.join(str(v) for v in seq) #Make a string from array

        if chr(c) == '\n':
            print("Line " + str(count) + ': ' + joined_seq)
            seq = []
            count += 1
            break


ser.close()

Ответ 5

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