pySerial 2.6:在readline()中指定行尾

时间:2013-05-09 20:51:58

标签: python serial-port pyserial

我正在使用pySerial向Eddie发送命令。我需要在readline中指定一个回车符,但pySerial 2.6摆脱了它...是否有解决方法?

以下是此PDF的第二页和第三页上列出的Eddie command set。在PDF无法访问的情况下,这是backup image

一般命令表格:

Input:              <cmd>[<WS><param1>...<WS><paramN>]<CR>
Response (Success): [<param1>...<WS><paramN>]<CR>
Response (Failure): ERROR[<SP>-<SP><verbose_reason>]<CR> 

正如您所看到的,所有回复都以\r结尾。我需要告诉pySerial停止。

我现在拥有的东西:

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

5 个答案:

答案 0 :(得分:20)

我遇到了同样的问题并实现了我自己的readline()函数,我从pyserial包中的serialutil.py文件中复制和修改了该函数。

串行连接是此函数所属类的一部分,并保存在属性“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)

这比等待超时更安全,更好,更快。

编辑: 我试图让io.TextIOWrapper方法工作时遇到this帖子(感谢zmo)。 因此,不使用上面提到的自定义readline函数,您可以使用:

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,导致串行连接再次超时。

line_buffering设置为True时,您不必再在每次写入后调用flush函数(如果使用换行符终止写入)。

编辑: TextIOWrapper方法在实践中适用于 small 命令字符串,但其行为未定义,并且在传输超过几个字节时可能导致errors。最安全的做法是实现自己的readline版本。

答案 1 :(得分:4)

来自pyserial的documentation

(原文如此)

注意:

使用较新的Python版本(V2.6 +)运行pySerial且模块eol可用时,不再支持readline()的{​​{1}}参数。 EOL

要指定io的{​​{1}}字符或使用通用换行模式,建议使用EOL

readline()

答案 2 :(得分:1)

使用电路板速率38400从端口3读取10个数据,当输入数据进入时,数据用\ n字符分隔

import serial as self
ser=self.Serial("COM3", 38400)  
buffer = []
count = 0.0
c = "\0"
while count < 10:
    c = "\0"
    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

答案 3 :(得分:0)

来自pyserial 3.2.1(默认为debian Stretch) read_until 。如果您要将墨盒从默认('\ n')更改为'\ r',只需执行以下操作:

import serial
ser=serial.Serial('COM5',9600)
ser.write('command\r')  # sending command
ser.read_until('\r')   # read until '\r' appears

'\ r'可以更改为要用作墨盒的任何一种。

答案 4 :(得分:-3)

似乎超时发生是因为readline()等待来自串口设备的'\n'字符,它从不发送。

根据pyserial documentation,您可以指定行尾字符:

response = self.ser.readline(eol='\r')

这有用吗?