我试图打乒乓球"在一些python代码和arduino代码之间来回信息。 我想定期向arduino代码发送两个设定值(例如在分钟内),在arduino和amp;上读取它们。更新变量然后定期将状态信息从arduino发送回python(例如:30秒)。最终python将从mySQL db(后来的dev)发送和提取信息。
现在我无法让信息可靠地来回反弹。我在搜索中找不到任何与此相近的内容,而且我尝试修改的所有内容都无法正常工作。我最近的就是这个(它实际上并没有在发送和接收之间来回切换):
的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()
Arduino的:
// 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("\n");
Serial.flush();
}
我最终获得的是重复的相同值(不是实际发送的,不确定它是否是字符串或字节问题)并且没有回到python脚本。非常感谢任何帮助或想法。感谢。
编辑:修改了我目前正在运行的代码,如下所示。 Arduino正在接收由minicom验证的精细和串行通信。但是,在#du;来自arduino的消息之后,python脚本仍会打印一个空行:&#34;。
答案 0 :(得分:8)
在写入和阅读之间,你不应该在Python中关闭串口。当Arduino响应时,端口仍有可能仍然关闭,在这种情况下数据将丢失。
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
函数默认只返回一个字节,因此您需要在循环中调用它或等待数据传输然后读取整个缓冲区。
在Arduino方面,您应该考虑当没有可用数据时loop
函数中会发生什么。
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
函数的开头等待,直到数据到达:
void loop()
{
while (!Serial.available()) {} // wait for data to arrive
// serial read section
while (Serial.available())
{
// continue as before
编辑2
以下是我与Python的Arduino应用程序接口时的结果:
>>> import serial
>>> s = serial.Serial('/dev/tty.usbmodem1411', 9600, timeout=5)
>>> s.write('2')
1
>>> s.readline()
'Arduino received: 2\r\n'
所以这似乎工作得很好。
在测试你的Python脚本时,似乎问题是当你打开串口时Arduino重置(至少我的Uno没有),所以你需要等待几秒才能启动它。您也只是为响应阅读了一行,所以我也在下面的代码中解决了这一问题:
#!/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
答案 1 :(得分:1)
我发现最好使用命令Serial.readString()
代替Serial.read()
,以获得Arduino的连续I / O。
答案 2 :(得分:0)
首先,您必须安装模块调用Serial。为此,请转到python安装文件夹中的Scripts文件夹。如果您使用的是Python 3版本,则通常位于以下位置,
C:\Python34\Scripts
打开该文件夹后,使用Shift键右键单击该文件夹。然后单击“在此处打开命令窗口”。之后,cmd
将弹出。在该cmd
窗口中编写以下代码,
pip install PySerial
然后按Enter。将安装 PySerial 模块。记住要安装模块,您必须具有INTERNET连接。
成功安装模块后,打开python IDLE并写下下面的代码并运行它。
import serial
# "COM11" is the port that your Arduino board is connected.set it to port that your are using
ser = serial.Serial("COM11", 9600)
while True:
cc=str(ser.readline())
print(cc[2:][:-5])