pyserial 2.7,python 3.3,发送回车
Posted
技术标签:
【中文标题】pyserial 2.7,python 3.3,发送回车【英文标题】:pyserial 2.7, python 3.3, sending carriage returns 【发布时间】:2014-04-29 17:17:29 【问题描述】:我一直在尝试使用 UART 接口将 Raspberry Pi 接口与嵌入式电路结合起来。 Pi 上的 UART 接口工作正常,我可以从电路接收消息,但我无法向电路发送消息。
我正在使用 Python 3.3 和 Pyserial 2.7。示例代码可用,但它使用 Pyserial 2.6。当与旧版本的 Python (ser.write() 接受字符串,但现在它只接受字节数组。
我遇到的问题是发送回车......旧代码应该只用:
ser.write("L1\r")
但现在我正在使用以下内容:
ser.write(bytearray("L1\r", "ascii"))
电路不响应命令。我认为生成的消息是将\r
作为两个单独的字符而不是回车发送。如何确保我的代码输出带有回车符的命令?
注意:我可以合理地预期电路运行良好,并且 Pi 的 UART 接口可以正常工作。该电路是 Atlas Scientific 溶解氧电路。电路的文档要求命令以l1<cr>
或L1<CR>
的形式编写。
相关链接:
旧示例代码 (https://www.atlas-scientific.com/_files/code/pi_sample_code.pdf)
描述写入方法的文档 (http://pyserial.sourceforge.net/pyserial_api.html#classes)
提前致谢!
编辑:Netch 提出了一个强项:ser.write(b'L1\r')
工作并且更干净。然而,这两种方法都在发送正确的“\r”序列。问题是电路仍然不将L1\r
视为有效命令。在这一点上,我认为我的问题可能是我的串口的某些属性。
我的端口是这样声明的:
ser = serial.Serial(
port = '/dev/ttyAMA0',
baudrate = 38400,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
timeout = 1
)
这个端口声明是根据电路的数据表完成的(不幸的是,我只能发布两个链接:(谷歌很容易找到它)。
【问题讨论】:
你确定它真的需要字节 arrays 还是字节序列就足够了?可以拨打ser.write(b'L1\r')
吗?您是否最初配置了端口(特别是原始模式是可取的)?
其实这样干净多了,Netch!我已经通过让 Pi 传输到自身来进一步测试我的代码。实际上,在ser.write(bytearray("L1\r", "ascii"))
和ser.write(b'L1\r')
中都将\r 作为适当的字符发送。这次电路的调试LED闪烁红色,表示命令未知。我认为这里的回车可能没问题,虽然我在发送消息时仍然明显犯了一些错误。当我们谈论串行端口时,“原始模式”是什么意思?我已经设置了奇偶校验、波特率、字节大小和停止位。
【参考方案1】:
我找到了解决办法!!不幸的是,我无法解释它是如何工作的。也许任何阅读此内容的人都可以详细说明并给出适当的解释!
电路的文档要求命令格式为CMD<CR>
。事实上,制造商提供的示例代码通过pyserial将L1
命令发送为ser.write("L1\r")
。
现在ser.write()
需要字节,但是我发现ser.write(b'L1\r')
不起作用。虽然电路不知道该命令,但还是收到了。
玩了一会儿,我发现ser.write(b'\rL1\r')
有效!在处理命令之前,调试指示灯会闪烁一次红色。看来我只需要发送一个“虚拟命令”来引起电路的注意!
我不确定这是否是 pyserial、电路或我自己的无知的错误。如果有人能对此有所了解,将不胜感激! :D
我在这里链接了电路文档,以防有人感兴趣。 https://www.atlas-scientific.com/_files/_datasheets/_circuit/DO_Circuit_5.0.pdf
【讨论】:
我猜这是特定于电路的问题。读取一个命令,它必须携带一个标志是否在行首。如果标志未正确初始化,它可能处于“行内”状态。带有 \r 的显式前缀将此标志置于已定义状态。【参考方案2】:[编辑] 对于未来的观众,我只想指出,对于较新的 EZO 版本的电路,命令是“L,1”或真正的“L,1\r” [/编辑]
这是电路的一个已知问题。上电后第一次读取会失败。而不是在每次读取时都添加一个 \r,只需发送一个包含 \r 的虚假命令,然后重置输入缓冲区
ser.write('bogus\r'.encode()) # EDIT: had to add .encode() to get it to work. see https://***.com/questions/22275079/pyserial-write-wont-take-my-string
ser.flushInput() # or for pyserial 3+ ser.reset_input_buffer()
#now do your thing
编辑:必须添加 .encode() 才能使其工作。见pySerial write() won't take my string
在 EZO™ 类电路处于 UART 模式时上电后, 发送给它的第一个命令将作为错误返回。这是因为 UART 缓冲区将显示它已收到一个字符 充电。只需将一个空白字符发送到 pH 电路即可 通电,这将清除缓冲区。
【讨论】:
很高兴收到其他用户的确认!我们最近开始在我们的工作场所使用更新的 EZO 芯片,我相信它们可以按预期工作(我没有亲自处理它们)以上是关于pyserial 2.7,python 3.3,发送回车的主要内容,如果未能解决你的问题,请参考以下文章
用于学习 Django 的 Python 2.7 或 3.3
无法为“python 3.3”安装“pip”,但对“python 2.7”运行良好
在 Python 中编写适用于 Windows 中的 Python 2.7+ 和 Python 3.3+ 的 .CSV 文件