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,发送回车的主要内容,如果未能解决你的问题,请参考以下文章

python中Pyserial如何实现RS485串口通讯

用于学习 Django 的 Python 2.7 或 3.3

无法为“python 3.3”安装“pip”,但对“python 2.7”运行良好

在 Python 中编写适用于 Windows 中的 Python 2.7+ 和 Python 3.3+ 的 .CSV 文件

在 CMD 中“python”启动 Python 3.3,“py”启动 Python 2.7,我该如何更改?

通过 pip 为 python 2.7 安装 py2exe:此包需要 Python 3.3 或更高版本