一尘不染

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

python

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

以下是此PDF第二和第三页上列出的Eddie命令集。这是无法访问PDF的备用图片

通用命令格式:

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

阅读 181

收藏
2020-12-20

共1个答案

一尘不染

我遇到了同样的问题,并实现了我自己的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方法工作时,我遇到了这篇文章。因此,可以使用以下代码来代替使用上面提到的自定义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()

确保将参数传递1BufferedRWPair,否则在每个字节导致串行连接再次超时后,它将不会将数据传递给TextIOWrapper。

设置为时line_bufferingTrue不再需要flush在每次写操作后调用函数(如果写操作以换行符终止)。

编辑:TextIOWrapper方法实际上适用于 小的
命令字符串,但其行为是不确定的,并且在传输多个字节时可能导致错误。实际上,最安全的做法是实现您自己的readline

2020-12-20