使用 Python 串口库处理从串口读取的原始数据?

Processing raw data read from serial port with Python serial library?

我不是 Python 程序员,而是电子电路设计师,但是这次我必须处理微控制器通过 RS232 端口向 Python 脚本发送的一些原始数据(由PHP 脚本)。

我花了好几个小时试图确定使用 Python 从串行 (RS232) 端口读取原始字节的最佳方法,我确实得到了结果 - 但我希望有人能澄清一下我在研究过程中注意到的某些不一致之处是:

1:
我看到很多问类似问题的人都被问到他们使用的是 serial 还是 pySerial 模块以及他们是如何安装串行库的。我只能说我真的不知道我使用的是哪个模块,因为该模块开箱即用。我在某处读到 serialpySerial 是同一回事,但我找不到这是否属实。我所知道的是我正在使用 Python 2.7.9 和 Raspbian OS.

2:
我读过有 read()readline() 方法用于从串行端口读取,但在 pySerial API docs 中没有提到 readline() 方法。此外,我发现 'number of bytes to read' 参数可以传递给 readline() 方法以及 read() 方法(并且工作方式相同,限制要读取的字节数)但是我找不到要记录的内容。

3:
在搜索如何确定是否已读取来自 RS232 缓冲区的 所有 数据时,我 here 找到了以下代码:

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 端口代码是顺便说一句:

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

4:
我从 µC 收到的数据格式如下:

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

some raw bytes + \r\n。由于 'raw bytes' 可以包含 0x00,有人可以确认将字节读入 Python 字符串变量不是问题吗?据我所知,这应该很好用,但我不是 100% 确定。

PySerial 对我有用,虽然我没有在 Pi 上使用它。

3: Read() returns 一个字符串 - 如果没有读取数据,这将是零长度,所以你的更高版本是正确的。由于字符串不是字符,您应该使用例如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: 是的,您可以接收 nul (0x00) 字节并将其放入字符串中。例如:

a="\x00"
print len(a)

将打印长度 1