简体   繁体   English

pyserial 2.7,python 3.3,发送回车

[英]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: 相关链接:

  1. 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

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM