Python pySerial 2.6:在 readline() 中指定行尾
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16470903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
pySerial 2.6: specify end-of-line in readline()
提问by Mr. Polywhirl
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?
我正在使用 pySerial 向 Eddie 发送命令。我需要在我的阅读行中指定一个回车,但 pySerial 2.6 摆脱了它......有解决方法吗?
Here are the Eddie command setis listed on the second and third pages of this PDF. Here is a backup imagein the case where the PDF is inaccessible.
以下是本 PDF 的第二页和第三页上列出的Eddie 命令集。这是PDF 无法访问时的备用图片。
General command form:
通用命令格式:
Input: <cmd>[<WS><param1>...<WS><paramN>]<CR>
Response (Success): [<param1>...<WS><paramN>]<CR>
Response (Failure): ERROR[<SP>-<SP><verbose_reason>]<CR>
As you can see all responses end with a \r. I need to tell pySerial to stop.
如您所见,所有响应都以\r. 我需要告诉 pySerial 停止。
What I have now:
我现在所拥有的:
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
采纳答案by lou
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.
我遇到了同样的问题并实现了我自己的 readline() 函数,我从 pyserial 包中的 serialutil.py 文件中复制和修改了该函数。
The serial connection is part of the class this function belongs to and is saved in attribute 'self.ser'
串行连接是该函数所属类的一部分,并保存在属性“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.
这是比等待超时更安全、更好、更快的选择。
EDIT: I came across thispost 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:
编辑:我在尝试让 io.TextIOWrapper 方法工作时遇到了这篇文章(感谢zmo)。因此,您可以使用:
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()
Make sure to pass the argument 1to the BufferedRWPair, otherwise it will not pass the data to the TextIOWrapper after every byte causing the serial connection to timeout again.
确保将参数传递1给BufferedRWPair,否则它不会在每个字节后将数据传递给 TextIOWrapper,导致串行连接再次超时。
When setting line_bufferingto Trueyou no longer have to call the flushfunction after every write (if the write is terminated with a newline character).
当设置line_buffering为True您不再需要flush在每次写入后调用该函数(如果写入以换行符终止)。
EDIT:
The TextIOWrapper method works in practice for smallcommand strings, but its behavior is undefined and can lead to errorswhen transmitting more than a couple bytes. The safest thing to do really is to implement your own version of readline.
编辑:TextIOWrapper 方法在实践中适用于小命令字符串,但其行为未定义,并且在传输超过几个字节时可能会导致错误。最安全的做法是实现您自己的readline.
回答by rodion
It seems that the timeout occurs because readline()waits for an '\n'character to come from the serial device, which it never sends.
似乎超时发生是因为readline()等待'\n'来自串行设备的字符,它从不发送。
According to the pyserial documentation, you can specify the end of line character:
根据pyserial 文档,您可以指定行尾字符:
response = self.ser.readline(eol='\r')
Does that work?
那样有用吗?
回答by zmo
from pyserial's documentation:
来自 pyserial 的文档:
(sic)
(原文如此)
Note:
笔记:
The eolparameter for readline()is no longer supported when pySerial is run with newer Python versions (V2.6+) where the module iois available.
EOL
该eol参数readline()时pySerial与较新版本的Python运行(V2.6 +),其中模块不再支持io是可用的。停产
To specify the EOLcharacter for readline()or to use universal newline mode, it is advised to use io.TextIOWrapper:
要指定EOL字符readline()或使用通用换行符模式,建议使用io.TextIOWrapper:
import serial
import io
ser = serial.serial_for_url('loop://', timeout=1)
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
sio.write(unicode("hello\n"))
sio.flush() # it is buffering. required to get the data out *now*
hello = sio.readline()
print hello == unicode("hello\n")
回答by sajin
reading 10 data from port 3 with board rate 38400, The data is separated with \n character when comes in the incoming data
以38400的速率从端口3读取10个数据,传入数据时数据以\n字符分隔
import serial as self
ser=self.Serial("COM3", 38400)
buffer = []
count = 0.0
c = "import serial
ser=serial.Serial('COM5',9600)
ser.write('command\r') # sending command
ser.read_until('\r') # read until '\r' appears
"
while count < 10:
c = "##代码##"
if ser.inWaiting():
while True:
val = ser.read(1)
if "\n" in val:
break
else:
c += val
buffer.append(c) # stores all data received into a list
count += 1
print buffer
回答by Chenming Zhang
From pyserial 3.2.1 (default from debian Stretch) read_untilis available. if you would like to change cartridge from default ('\n') to '\r', simply do:
从 pyserial 3.2.1(debian Stretch 的默认值)开始,read_until可用。如果您想将墨盒从默认 ('\n') 更改为 '\r',只需执行以下操作:
##代码##'\r' could be changed to whatever you will be using as cartridge.
'\r' 可以更改为您将用作墨盒的任何内容。

