[英]pyserial 2.7, python 3.3, sending carriage returns
I have been attempting to have a Raspberry Pi interface with an embedded circuit using the UART interface. 我一直在尝试使用带有UART接口的带有嵌入式电路的Raspberry Pi接口。 The UART interface on the Pi is in working order and I can receive messages from the circuit, though I am having trouble sending messages to the circuit. Pi上的UART接口工作正常,尽管我无法向电路发送消息,但我可以从电路接收消息。
I am using Python 3.3 with Pyserial 2.7. 我在Pyserial 2.7中使用Python 3.3。 Sample code is available, though it uses Pyserial 2.6. 可以使用示例代码,尽管它使用Pyserial 2.6。 When used with older versions of Python (<2.6), ser.write()
accepts strings, but now it only accepts bytearrays. 当与旧版本的Python(<2.6)一起使用时, ser.write()
接受字符串,但现在仅接受ser.write()
。
The problem I am having is in sending carriage returns... The old code supposedly functioned with just: 我遇到的问题是发送回车符...原来的代码只能运行:
ser.write("L1\\r")
but now I am using the following: 但现在我正在使用以下内容:
ser.write(bytearray("L1\\r", "ascii"))
The circuit does not respond to the command. 电路不响应该命令。 I think the resultant message is sending \\r
as two individual characters rather than a carriage return. 我认为结果消息将\\r
作为两个单独的字符而不是回车符发送。 How would I make sure my code is outputting commands appended with carriage returns? 我如何确定我的代码输出的是带有回车符的命令?
Notes: I can reasonably expect that the circuit is working well and that the Pi's UART interface is functional. 注意:我可以合理地预期电路工作正常并且Pi的UART接口可以正常工作。 The circuit is an Atlas Scientific Dissolved Oxygen Circuit. 该回路是阿特拉斯科学溶解氧回路。 The circuit's documentation demands that commands be written in the form l1<cr>
or L1<CR>
. 电路的文档要求以l1<cr>
或L1<CR>
的形式编写命令。
Relevant links: 相关链接:
Old sample code ( https://www.atlas-scientific.com/_files/code/pi_sample_code.pdf ) 旧的示例代码( https://www.atlas-scientific.com/_files/code/pi_sample_code.pdf )
Documentation describing write method ( http://pyserial.sourceforge.net/pyserial_api.html#classes ) 描述写入方法的文档( http://pyserial.sourceforge.net/pyserial_api.html#classes )
Thanks in advance! 提前致谢!
EDIT: Netch makes a strong point: ser.write(b'L1\\r')
works and is much cleaner. 编辑:Netch提出了一个强项: ser.write(b'L1\\r')
可以工作并且更干净。 Both methods, however, ARE sending a correct '\\r' sequence.. The problem is that the circuit still does not regard L1\\r
as a valid command. 但是,这两种方法都在发送正确的'\\ r'序列。问题是电路仍然没有将L1\\r
视为有效命令。 At this point, I think my issue may be some property of my serial port. 在这一点上,我认为我的问题可能是串行端口的某些属性。
My port is declared as such: 我的端口被声明为:
ser = serial.Serial(
port = '/dev/ttyAMA0',
baudrate = 38400,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
timeout = 1
)
This port declaration is done with accordance to the circuit's datasheet (I can only post two links unfortunately :( Google brings it up easily). 该端口声明是根据电路的数据表完成的(不幸的是,我只能发布两个链接:(Google轻松将其提起)。
I have found a solution!! 我找到了解决方案! Unfortunately, I cannot explain how it works. 不幸的是,我无法解释它是如何工作的。 Perhaps anyone reading this could elaborate on it and give a proper explanation! 也许任何阅读此书的人都可以对此进行详细阐述并给出适当的解释!
The circuit's documentation demands commands be in the form CMD<CR>
. 电路的文档要求命令采用CMD<CR>
的形式。 Indeed, sample code provided by the manufacturer sends the L1
command through pyserial as ser.write("L1\\r")
. 实际上,制造商提供的示例代码通过pyserial将L1
命令发送为ser.write("L1\\r")
。
Now that ser.write()
demands bytes however, I have found that ser.write(b'L1\\r')
does not work.. The command is received though it is somehow unknown to the circuit. 现在, ser.write()
需要字节,我发现ser.write(b'L1\\r')
不起作用。尽管电路不知如何,但仍接收到该命令。
After toying around for a while, I have discovered that ser.write(b'\\rL1\\r')
works! ser.write(b'\\rL1\\r')
了一段时间后,我发现ser.write(b'\\rL1\\r')
可以工作了! The debugging led flashes red once before processing the command. 在执行命令之前,调试指示灯将闪烁红色一次。 It seems like I just need to send a 'dummy command' to get the circuit's attention! 看来我只需要发送“虚拟命令”即可引起电路注意!
I am not sure if this is the fault of pyserial, the circuit, or my own ignorance. 我不确定这是否是脓疱,电路或我自己的无知。 If anyone can shed some light on this, it would be much appreciated! 如果有人可以对此有所了解,将不胜感激! :D :D
I have linked here the circuits documentation in case anyone is interested. 如果有人有兴趣,我已经在这里链接了电路文档。 https://www.atlas-scientific.com/_files/_datasheets/_circuit/DO_Circuit_5.0.pdf https://www.atlas-scientific.com/_files/_datasheets/_circuit/DO_Circuit_5.0.pdf
[EDIT] For future viewers, I just want to point out that for the newer EZO version of the circuit, the command is "L,1" or really "L,1\\r" [/EDIT] [编辑]对于将来的观众,我只想指出,对于较新的EZO版本的电路,命令为“ L,1”或实际上为“ L,1 \\ r” [/ EDIT]
This is a known issue with the circuit. 这是电路的已知问题。 The first read after power up will fail. 上电后的第一个读取将失败。 instead of prepending a \\r with every read, just send a bogus command with \\r included and then reset input buffer 而不是每次读取都在前面加上\\ r,只需发送包含\\ r的伪指令,然后重置输入缓冲区
ser.write('bogus\r'.encode()) # EDIT: had to add .encode() to get it to work. see https://stackoverflow.com/questions/22275079/pyserial-write-wont-take-my-string
ser.flushInput() # or for pyserial 3+ ser.reset_input_buffer()
#now do your thing
EDIT: had to add .encode() to get it to work. 编辑:必须添加.encode()使其工作。 see pySerial write() won't take my string 看到pySerial write()不会接受我的字符串
After powering up the EZO™ class circuit when it is in UART mode the first command sent to it will comeback as an error. 在处于UART模式的EZO™类电路上电后,发送给它的第一个命令将作为错误返回。 This is because the UART buffer will show that it has received a character during power up. 这是因为UART缓冲区将显示它在上电期间已收到一个字符。 Simply send a blank character to the pH circuit after it is powered up, this will clear the buffer. 通电后,只需将空白字符发送到pH电路,这将清除缓冲区。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.