pySerial 2.6:在 readline() 中指定行尾 [英] pySerial 2.6: specify end-of-line in readline()
问题描述
我正在使用 pySerial 向 Eddie 发送命令.我需要在我的阅读行中指定一个回车,但 pySerial 2.6 摆脱了它......有解决方法吗?
I am sending commands to Eddie using pySerial. I need to specify a carriage-return in my readline, but pySerial 2.6 got rid of it... Is there a workaround?
这里是 Eddie 命令集 列在此 PDF 的第二页和第三页上.这是一个 备份图片,以防无法访问 PDF.
Here are the Eddie command set is listed on the second and third pages of this PDF. Here is a backup image in the case where the PDF is inaccessible.
Input: <cmd>[<WS><param1>...<WS><paramN>]<CR>
Response (Success): [<param1>...<WS><paramN>]<CR>
Response (Failure): ERROR[<SP>-<SP><verbose_reason>]<CR>
如您所见,所有响应都以 \r
结尾.我需要告诉 pySerial 停止.
As you can see all responses end with a \r
. I need to tell pySerial to stop.
def sendAndReceive(self, content):
logger.info('Sending {0}'.format(content))
self.ser.write(content + '\r')
self.ser.flush();
response = self.ser.readline() # Currently stops reading on timeout...
if self.isErr(response):
logger.error(response)
return None
else:
return response
推荐答案
我遇到了同样的问题并实现了我自己的 readline() 函数,我从 pyserial 包中的 serialutil.py 文件中复制和修改了该函数.
I'm having the same issue and implemented my own readline() function which I copied and modified from the serialutil.py file found in the pyserial package.
串行连接是该函数所属类的一部分,保存在属性self.ser"中
The serial connection is part of the class this function belongs to and is saved in attribute 'self.ser'
def _readline(self):
eol = b'\r'
leneol = len(eol)
line = bytearray()
while True:
c = self.ser.read(1)
if c:
line += c
if line[-leneol:] == eol:
break
else:
break
return bytes(line)
这是比等待超时更安全、更好、更快的选择.
This is a safer, nicer and faster option than waiting for the timeout.
我在尝试让 io.TextIOWrapper 方法工作时遇到了这篇帖子(感谢
I came across this post when trying to get the io.TextIOWrapper method to work (thanks zmo). So instead of using the custom readline function as mentioned above you could use:
self.ser = serial.Serial(port=self.port,
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1)
self.ser_io = io.TextIOWrapper(io.BufferedRWPair(self.ser, self.ser, 1),
newline = '\r',
line_buffering = True)
self.ser_io.write("ID\r")
self_id = self.ser_io.readline()
确保将参数1
传递给BufferedRWPair
,否则它不会在每个字节后将数据传递给TextIOWrapper,导致串行连接再次超时.
Make sure to pass the argument 1
to the BufferedRWPair
, otherwise it will not pass the data to the TextIOWrapper after every byte causing the serial connection to timeout again.
当将 line_buffering
设置为 True
时,您不再需要在每次写入后调用 flush
函数(如果写入以换行符终止)字符).
When setting line_buffering
to True
you no longer have to call the flush
function after every write (if the write is terminated with a newline character).
TextIOWrapper 方法在实践中适用于small 命令字符串,但其行为未定义并且可能导致 错误 传输超过几个字节时.最安全的做法是实现您自己的 readline
版本.
The TextIOWrapper method works in practice for small command strings, but its behavior is undefined and can lead to errors when transmitting more than a couple bytes. The safest thing to do really is to implement your own version of readline
.
这篇关于pySerial 2.6:在 readline() 中指定行尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!