pySerial 2.6:在 readline() 中指定行尾 [英] pySerial 2.6: specify end-of-line in readline()

查看:41
本文介绍了pySerial 2.6:在 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 方法工作时遇到了这篇帖子(感谢zmo).因此,您可以使用:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆