Python Serial:如何使用read或readline函数一次读取多个字符

use*_*001 18 python serial-port readline pyserial

我无法使用我的程序读取多个角色,我似乎无法弄清楚我的程序出了什么问题,因为我对python很新.

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()
Run Code Online (Sandbox Code Playgroud)

这是我得到的结果

connected to: COM5
1: 1
2: 2
3: 4
4: 3
5: 1
Run Code Online (Sandbox Code Playgroud)

实际上我在期待这个

connected to: COM5
1:12431
2:12431
Run Code Online (Sandbox Code Playgroud)

像上面提到的那样能够同时读取多个字符而不是一个接一个.

jwy*_*k67 28

我看到了几个问题.

第一:

ser.read()一次只返回1个字节.

如果指定计数

ser.read(5)
Run Code Online (Sandbox Code Playgroud)

它将读取5个字节(如果在5个字节到达之前发生超时,则更少).

如果您知道输入始终使用EOL字符正确终止,则可以使用更好的方法

ser.readline()
Run Code Online (Sandbox Code Playgroud)

这将继续读取字符,直到收到EOL.

第二:

即使你让ser.read()或ser.readline()返回多个字节,因为你在迭代返回值,你仍然会一次处理一个字节.

摆脱了

for line in ser.read():
Run Code Online (Sandbox Code Playgroud)

然后说:

line = ser.readline()
Run Code Online (Sandbox Code Playgroud)


133*_*day 9

串行一次发送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()
Run Code Online (Sandbox Code Playgroud)

  • “您需要实现自己的方法,该方法可以将字符读入缓冲区,直到到达某些标记为止”-这不是* serial.readline`的确切含义吗? (2认同)

小智 7

我使用这种小方法通过Python读取Arduino串行监视器

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

  • 我假设您使用 `cc[2:][:-5]` 来去除 `b'` 和 `\r\n'`。使用 `.decode("utf-8")` 不是更好吗? (7认同)

Des*_*rit 6

我从我的 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()
Run Code Online (Sandbox Code Playgroud)

  • 我认为你的评论 #convert from ansii 应该是 #convert from ascii (4认同)