Pyserial格式化 - 超过127的字节返回为2个字节,而不是一个
我在Arduino上运行了一个程序,它可以接收串口输入,并把这些输入保存到一个变量里。这个功能非常好用。通过Arduino自带的串口监视器,我成功地发送和接收了0到255之间的字节。
但是,当我使用pyserial发送任何大于127的字节(比如0b01111111
)时,pyserial
会返回2。这意味着对于大于127的值,比如0b10000000
,会发送2个字节,而不是1个。
所以我觉得问题出在pyserial
上。
ser.write(chr(int('01000000', base=2)).encode('utf-8'))
这个发送是完全正常的,并且在Arduino那边也能正确接收到。
ser.write(chr(int('10000000', base=2)).encode('utf-8'))
但是返回的是2,并且在Arduino上显示为0b11000010
和0b10000000
。
1 个回答
2
正如NPE所说,这里讲的是UTF-8的编码方式。简单来说,128到2047之间的字节(也就是8到11位的二进制数)会被转换成两个字节。如果原来的11位是abcdefghijk,那么在UTF-8中就变成了110abcde 10fghijk。在你的例子中(为了凑成11位,左边补了0),00010000000会被转换成11000010 10000000,也就是\xc2\x80,这正是你看到的结果。想了解更多,可以查看维基百科关于UTF-8的文章。
你可以用下面的代码在Python中看到这个效果(我把int('10000000', base=2)替换成了128):
>>> unichr(128).encode('utf-8')
'\xc2\x80'
让我感到困惑的是,你可以用chr(int('10000000', base=2)).encode('utf-8'),或者直接用chr(128).encode('utf-8')。当我这样做时,我得到了:
>>> chr(int('10000000', base=2)).encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128)
你有没有改变默认的编码方式?
你需要的是一种编码方式,它能用一个字节表示0到255,并且与Unicode匹配。所以试试用'latin_1'代替:
>>> unichr(128).encode('latin_1')
'\x80'