python to arduino 串行读取 &写
问题描述
我正在尝试在一些 python 代码和 arduino 代码之间来回乒乓"信息.我想定期向 arduino 代码发送两个设定点(例如在分钟内),在 arduino &更新变量然后定期将状态信息从arduino发送回python(例如:30秒).最终,python 将从 mySQL 数据库(后来的开发)发送和提取信息.
I'm trying to "ping pong" info back and forth between some python code and arduino code. I want to send two setpoints to the arduino code periodically (for instance on the minute), read them on arduino & update variables then send status info from arduino back to python periodically (such as on the :30 second). Eventually python will be sending and pulling info from a mySQL db (later dev).
现在我无法让信息可靠地来回反弹.我在搜索中没有找到任何与此相关的东西,而且我尝试修改的所有内容都不起作用.我最接近的是这个(它实际上并没有在发送和接收之间来回切换):
Right now I can't get the info to bounce back and forth reliably. I haven't found anything close to this in the searches and everything I've tried to modify isn't working. Closest I have is this (and it doesn't actually switch back and forth between send and receive):
Python
#!/usr/bin/python
import serial
import syslog
import time
#The following line is for serial over GPIO
port = '/dev/ttyS0'
ard = serial.Serial(port,9600,timeout=5)
i = 0
while (i < 4):
# Serial write section
setTempCar1 = 63
setTempCar2 = 37
ard.flush()
setTemp1 = str(setTempCar1)
setTemp2 = str(setTempCar2)
print ("Python value sent: ")
print (setTemp1)
ard.write(setTemp1)
time.sleep(4)
# Serial read section
msg = ard.readline()
print ("Message from arduino: ")
print (msg)
i = i + 1
else:
print "Exiting"
exit()
阿杜诺:
// Serial test script
int setPoint = 55;
String readString;
void setup()
{
Serial.begin(9600); // initialize serial communications at 9600 bps
}
void loop()
{
while(!Serial.available()) {}
// serial read section
while (Serial.available())
{
if (Serial.available() >0)
{
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
}
if (readString.length() >0)
{
Serial.print("Arduino received: ");
Serial.println(readString); //see what was received
}
delay(500);
// serial write section
char ard_sends = '1';
Serial.print("Arduino sends: ");
Serial.println(ard_sends);
Serial.print("
");
Serial.flush();
}
我最终得到的只是重复的相同值(不是实际发送的值,不确定是字符串还是字节问题)并且没有返回到 python 脚本.非常感谢任何帮助或想法.谢谢.
All I end up getting is the same values repeated (not what was actually sent, not sure if its a string or byte issue) and nothing back to the python script. Any help or ideas are greatly appreciated. Thanks.
将代码修改为我当前正在运行的代码,如下所示.Arduino 正在接收 minicom 验证的良好和串行通信.但是python脚本仍然在来自arduino的消息:"之后打印一个空行.
Modified code to what I'm currently running as suggested below. Arduino is receiving fine and serial communication verified by minicom. But python script still prints a blank line after "Message from arduino: ".
解决方案
你不应该在 Python 中在读写之间关闭串口.当 Arduino 响应时,端口可能仍然关闭,在这种情况下,数据将丢失.
You shouldn't be closing the serial port in Python between writing and reading. There is a chance that the port is still closed when the Arduino responds, in which case the data will be lost.
while running:
# Serial write section
setTempCar1 = 63
setTempCar2 = 37
setTemp1 = str(setTempCar1)
setTemp2 = str(setTempCar2)
print ("Python value sent: ")
print (setTemp1)
ard.write(setTemp1)
time.sleep(6) # with the port open, the response will be buffered
# so wait a bit longer for response here
# Serial read section
msg = ard.read(ard.inWaiting()) # read everything in the input buffer
print ("Message from arduino: ")
print (msg)
Python Serial.read
函数默认只返回一个字节,所以你需要要么循环调用它,要么等待数据传输完毕再读取整个缓冲区.
The Python Serial.read
function only returns a single byte by default, so you need to either call it in a loop or wait for the data to be transmitted and then read the whole buffer.
在 Arduino 方面,您应该考虑在没有数据可用时在您的 loop
函数中会发生什么.
On the Arduino side, you should consider what happens in your loop
function when no data is available.
void loop()
{
// serial read section
while (Serial.available()) // this will be skipped if no data present, leading to
// the code sitting in the delay function below
{
delay(30); //delay to allow buffer to fill
if (Serial.available() >0)
{
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
}
相反,在 loop
函数开始处等待,直到数据到达:
Instead, wait at the start of the loop
function until data arrives:
void loop()
{
while (!Serial.available()) {} // wait for data to arrive
// serial read section
while (Serial.available())
{
// continue as before
编辑 2
这是我通过 Python 与您的 Arduino 应用程序交互时得到的结果:
Here's what I get when interfacing with your Arduino app from Python:
>>> import serial
>>> s = serial.Serial('/dev/tty.usbmodem1411', 9600, timeout=5)
>>> s.write('2')
1
>>> s.readline()
'Arduino received: 2
'
所以这似乎工作正常.
在测试您的 Python 脚本时,问题似乎是当您打开串行端口时 Arduino 会重置(至少我的 Uno 会重置),因此您需要等待几秒钟才能启动.您也只读取了响应的一行,所以我也在下面的代码中修复了这个问题:
In testing your Python script, it seems the problem is that the Arduino resets when you open the serial port (at least my Uno does), so you need to wait a few seconds for it to start up. You are also only reading a single line for the response, so I've fixed that in the code below also:
#!/usr/bin/python
import serial
import syslog
import time
#The following line is for serial over GPIO
port = '/dev/tty.usbmodem1411' # note I'm using Mac OS-X
ard = serial.Serial(port,9600,timeout=5)
time.sleep(2) # wait for Arduino
i = 0
while (i < 4):
# Serial write section
setTempCar1 = 63
setTempCar2 = 37
ard.flush()
setTemp1 = str(setTempCar1)
setTemp2 = str(setTempCar2)
print ("Python value sent: ")
print (setTemp1)
ard.write(setTemp1)
time.sleep(1) # I shortened this to match the new value in your Arduino code
# Serial read section
msg = ard.read(ard.inWaiting()) # read all characters in buffer
print ("Message from arduino: ")
print (msg)
i = i + 1
else:
print "Exiting"
exit()
现在是上面的输出:
$ python ardser.py
Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1
Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1
Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1
Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1
Exiting
相关文章