windows PySerial 不与 Arduino 交谈
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8149628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PySerial not talking to Arduino
提问by Matt Ellen
- Python version: 2.6.6
- PySerialversion: 2.5
- Arduino board: Duemilanove328
- Python版本:2.6.6
- PySerial版本:2.5
- Arduino板:Duemilanove328
I have written some code to simulate some hardware I'm working with and uploaded it to the Arduino board. This code works. I know this, because I get the expected response from HyperTerminal.
我已经编写了一些代码来模拟我正在使用的一些硬件并将其上传到 Arduino 板。此代码有效。我知道这一点,因为我从超级终端得到了预期的响应。
However, when I try to connect using PySerial the connection does not error, but I get no response to the commands I send.
但是,当我尝试使用 PySerial 进行连接时,连接不会出错,但我发送的命令没有任何响应。
Why might this be?
为什么会这样?
Python code
Python代码
import serial
def main():
sp = serial.Serial()
sp.port = 'COM4'
sp.baudrate = 19200
sp.parity = serial.PARITY_NONE
sp.bytesize = serial.EIGHTBITS
sp.stopbits = serial.STOPBITS_ONE
sp.timeout = 0.5
sp.xonxoff = False
sp.rtscts = False
sp.dsrdtr = False
sp.open()
sp.write("GV\r\n".encode('ascii'))
value = sp.readline()
print value
sp.write("GI\r\n".encode('ascii'))
value = sp.readline()
print value
sp.close()
if __name__ == "__main__":
main()
NB: the code on the Arduino sends back \r\n
at the end of a response to a command.
注意:Arduino 上的代码在对\r\n
命令的响应结束时发回。
HyperTerminal configuration:
超级终端配置:
Edit
编辑
I have found that if I increase the timeout to 10 seconds and add a sp.readline()
before I send anything, then I get responses to both commands.
我发现如果我将超时增加到 10 秒并sp.readline()
在发送任何内容之前添加一个,那么我会收到对这两个命令的响应。
How long is the hardware handshake usually between PySerial and an Arduino or USB RS-232 ports?
PySerial 和 Arduino 或 USB RS-232 端口之间的硬件握手通常需要多长时间?
采纳答案by ib.lundgren
Can not verify this but it could be that you try and read before there is any data there, thus you get no reply back.
无法验证这一点,但可能是您在那里有任何数据之前尝试阅读,因此您没有得到回复。
To test this you could try and poll until there is data
要对此进行测试,您可以尝试轮询直到有数据
value = None
while not value:
value = sp.readline()
print value
Edit
编辑
The Arduino will reset when you open a serial connection, any data written during bootup will likely go to bit heaven. You could use a sleep for 2 seconds (could not find the exact time it takes, will likely vary anyway) before you do any reads/writes.
当您打开串行连接时,Arduino 将重置,在启动期间写入的任何数据都可能会进入天堂。在进行任何读/写操作之前,您可以使用 sleep 2 秒(无法找到所需的确切时间,无论如何可能会有所不同)。
Alternatively you could write to it until you get a response back, after you get a return you start doing "real work".
或者,您可以写信直到收到回复,收到回复后,您就开始做“真正的工作”。
回答by Matt Ellen
For the time being I am using a workaround. I have set the timeout
to 1.5 seconds and put a readline
call in before the first write.
目前我正在使用一种解决方法。我已将 设置timeout
为 1.5 秒并readline
在第一次写入之前拨打电话。
So now the Python code looks like:
所以现在 Python 代码如下所示:
import serial
def main():
sp = serial.Serial()
sp.port = 'COM4'
sp.baudrate = 19200
sp.parity = serial.PARITY_NONE
sp.bytesize = serial.EIGHTBITS
sp.stopbits = serial.STOPBITS_ONE
sp.timeout = 1.5 #1.5 to give the hardware handshake time to happen
sp.xonxoff = False
sp.rtscts = False
sp.dsrdtr = False
sp.open()
sp.readline() #to give the hardware handshake time to happen
sp.write("GV\r\n".encode('ascii'))
value = sp.readline()
print value
sp.write("GI\r\n".encode('ascii'))
value = sp.readline()
print value
sp.close()
if __name__ == "__main__":
main()
回答by Memphis
I've also encountered this problem recently and here's my solution:
我最近也遇到了这个问题,这是我的解决方案:
import serial
ser = serial.Serial(4, timeout=2)
ser.setRTS(True)
ser.setRTS(False)
while 1:
line = ser.readline()
print(line)
ser.close
Turns out this will successfully reset the Arduino board.
事实证明这将成功重置 Arduino 板。
回答by nvd
Add a delay after you open the port as Arduino is reset and the bootloader starts listening for new firmware. If something is sent at that moment, the MCU remains stuck in bootloader. The delay causes the bootloader to timeout.
在您打开端口后添加延迟,因为 Arduino 被重置并且引导加载程序开始侦听新固件。如果在那一刻发送了一些东西,MCU 仍然停留在引导加载程序中。延迟会导致引导加载程序超时。
sp.open()
time.sleep(2) # 2 seconds or possibly a bit less
sp.write("blahblah")
回答by P_B
You can easily and robustly connect and communicate between Python and Arduino boards using the compatible libraries SerialTransfer.hand pySerialTransfer. These libraries automatically packetize and parse serial packets using start/end markers, cyclic redundancy checking, consistent overhead byte stuffing, and dynamic payload lengths.
您可以使用兼容库SerialTransfer.h和pySerialTransfer在 Python 和 Arduino 板之间轻松而稳健地连接和通信。这些库使用开始/结束标记、循环冗余检查、一致开销字节填充和动态有效载荷长度自动打包和解析串行数据包。
SerialTransfer.h is installable through the Arduino IDE's Libraries Manager and pySerialTrasnfer is pip-installable.
SerialTransfer.h 可通过 Arduino IDE 的库管理器安装,pySerialTrasnfer 可通过 pip 安装。
Example Python:
示例 Python:
from pySerialTransfer import pySerialTransfer as txfer
if __name__ == '__main__':
try:
link = txfer.SerialTransfer('COM13')
link.txBuff[0] = 'h'
link.txBuff[1] = 'i'
link.txBuff[2] = '\n'
link.send(3)
while not link.available():
if link.status < 0:
print('ERROR: {}'.format(link.status))
print('Response received:')
response = ''
for index in range(link.bytesRead):
response += chr(link.rxBuff[index])
print(response)
link.close()
except KeyboardInterrupt:
link.close()
Example Arduino:
示例 Arduino:
#include "SerialTransfer.h"
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
SerialTransfer myTransfer;
void setup()
{
Serial.begin(115200);
mySerial.begin(9600);
myTransfer.begin(mySerial);
}
void loop()
{
myTransfer.txBuff[0] = 'h';
myTransfer.txBuff[1] = 'i';
myTransfer.txBuff[2] = '\n';
myTransfer.sendData(3);
delay(100);
if(myTransfer.available())
{
Serial.println("New Data");
for(byte i = 0; i < myTransfer.bytesRead; i++)
Serial.write(myTransfer.rxBuff[i]);
Serial.println();
}
else if(myTransfer.status < 0)
{
Serial.print("ERROR: ");
Serial.println(myTransfer.status);
}
}