我使用pySerial从arduino发送一些数据。
我的数据看起来像
bytearray(DST, SRC, STATUS, TYPE, CHANNEL, DATA..., SIZEOFDATA)
其中sizeofData是一个接收所有字节的测试。
问题是,每当一个字节为零时,我的python程序就停止在那里读取:
serial_port = serial.Serial("/dev/ttyUSB0")
while serial_port.isOpen():
response_header_str = serial_port.readline()
format = '>';
format += ('B'*len(response_header_str));
response_header = struct.unpack(format, response_header_str)
pprint(response_header)
serial_port.close()
例如,当我发送bytearray(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
时,一切都很好。但是,当我发送bytearray(1,2,3,4,0,1,2,3,4)
之类的内容时,我不会看到以零开头的所有内容。
问题是我无法避免发送零,因为我只是发送"内存转储"例如当我发送一个浮点值时,可能有零个字节。
如何告诉pyserial不要忽略零字节。
答案 0 :(得分:0)
我查看了PySerial的来源,问题出在PySerial的FileLike.readline
(http://svn.code.sf.net/p/pyserial/code/trunk/pyserial/serial/serialutil.py)的实现中。违规功能是:
def readline(self, size=None, eol=LF):
"""\
Read a line which is terminated with end-of-line (eol) character
('\n' by default) or until timeout.
"""
leneol = len(eol)
line = bytearray()
while True:
c = self.read(1)
if c:
line += c
if line[-leneol:] == eol:
break
if size is not None and len(line) >= size:
break
else:
break
return bytes(line)
明显的问题是if c:
行。当c == b'\x00'
计算结果为false时,例程就会超出读循环。最简单的方法是将自己重新实现为:
def readline(port, size=None, eol="\n"):
"""\
Read a line which is terminated with end-of-line (eol) character
('\n' by default) or until timeout.
"""
leneol = len(eol)
line = bytearray()
while True:
line += port.read(1)
if line[-leneol:] == eol:
break
if size is not None and len(line) >= size:
break
return bytes(line)
为了澄清你的评论,这是将消耗空字节的Serial.readline
方法的替代,并将它们添加到返回的字符串,直到它到达eol
字符,我们在此定义为"\n"
。
使用新方法的示例,其中文件对象替换套接字:
>>> # Create some example data terminated by a newline containing nulls.
>>> handle = open("test.dat", "wb")
>>> handle.write(b"hell\x00o, w\x00rld\n")
>>> handle.close()
>>>
>>> # Use our readline method to read it back in.
>>> handle = open("test.dat", "rb")
>>> readline(handle)
'hell\x00o, w\x00rld\n'
希望这更有意义。