在Python中读取串口数据的问题

0 投票
3 回答
14948 浏览
提问于 2025-04-16 14:06

我有一个Python程序,想从串口读取14个字节的数据,但这些数据到达得非常慢。我想把所有的字节都放进一个大小为14的字节数组里。我知道在Python 3.0中有新的字节数组功能,但我现在用的是Python 2.6.6。升级可能会带来意想不到的问题,所以我得继续用2.6.6。

数据在串口上不是持续流动的,大概每两分钟才会收到一条消息。这些数据流动得很慢。我遇到的问题是,我的代码不能可靠地一次读取一个字节。我想把这些数据准确地分成14个字节,然后处理这些数据,再重新开始读取新的14个字节。

我这样做是不是错了?有什么建议吗?

    ser = serial.Serial('/dev/ttyUSB1', 1200, timeout=0)
    ser.open()
    print "connected to: " + ser.portstr
    count=0
    while True:
        line =ser.readline(size=14) # should block, not take anything less than 14 bytes
        if line:
            # Here I want to process 14 bytes worth of data and have
            # the data be consistent.
            print "line(" + str(count) + ")=" + line
            count=count+1
    ser.close()

这是我期待的结果:line(1)=� 0~ 888.ABC� /以回车结束

----------开始输出------

line(0)=0
line(1)=~ ??1. ABC �    # here get some multiple bytes and stuff gets out of synch

�ine(2)=
line(3)=0
line(4)=~
line(5)= 
line(6)=8
line(7)=8
line(8)=8
line(9)=.
line(10)= 
line(11)=A
line(12)=B
line(13)=C
line(14)= 
line(15)=�
line(16)=

#...
line(48)=
line(49)=�
line(50)=0
line(51)=~
line(52)= 
line(53)=8
line(54)=8
line(55)=8
line(56)=.
line(57)= 
line(58)=A
line(59)=B
line(60)=C
line(61)= 
line(62)=�
line(63)=

line(64)=

----------结束输出------

3 个回答

-1

更改波特率。

ser = serial.Serial('/dev/ttyUSB1', 9600, timeout=0)

设置为一个兼容的波特率。

为了获取14字节的数据:

data = ser.read(size=14)
2

试试这个:

ser = Serial('/dev/ttyUSB1', 1200, timeout=0)
print "connected to: " + ser.portstr
count=0
while True:
     for line in ser.readlines()   
          print "line(" + str(count) + ")=" + line
          count=count+1

ser.close()   

如果你还没用过,可能会对 line.strip() 这个函数感兴趣。另外,注意 ser.readlines() 中的 s,它和 .readline() 是不一样的。

4

PySerial的API文档提到,readline()这个函数会一直读取,直到遇到换行符(\n)或者达到指定的大小为止。不过,read()这个函数则表示它会一直等待,直到达到指定的大小。两个函数都提到,如果设置了超时时间,它们会提前返回。

Possible values for the parameter timeout:

timeout = None: wait forever
timeout = 0: non-blocking mode (return immediately on read)
timeout = x: set timeout to x seconds (float allowed)

你可以试试把 timeout=None 用在这里,而不是 timeout=0

撰写回答