python到arduino串行读写
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24074914/
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
python to arduino serial read & write
提问by Boombrewer
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).
我试图在一些 python 代码和 arduino 代码之间来回“乒乓”信息。我想定期向 arduino 代码发送两个设置点(例如在分钟上),在 arduino 上读取它们并更新变量,然后定期从 arduino 将状态信息发送回 python(例如在 :30 秒)。最终,python 将从 mySQL 数据库(后来的开发)发送和提取信息。
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
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();
}
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.
我最终得到的只是重复的相同值(不是实际发送的值,不确定是字符串还是字节问题)并且没有返回到 python 脚本。非常感谢任何帮助或想法。谢谢。
EDIT: 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: ".
编辑:将代码修改为我目前正在运行的代码,如下所示。Arduino 正在接收由 minicom 验证的良好和串行通信。但是python脚本仍然在“来自arduino的消息:”之后打印一个空行。
采纳答案by Peter Gibson
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.
您不应该在写入和读取之间关闭 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)
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.
PythonSerial.read
函数默认只返回单个字节,因此您需要在循环中调用它或等待数据传输完毕然后读取整个缓冲区。
On the Arduino side, you should consider what happens in your loop
function when no data is available.
在 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
}
}
Instead, wait at the start of the loop
function until data arrives:
相反,在loop
函数开始时等待数据到达:
void loop()
{
while (!Serial.available()) {} // wait for data to arrive
// serial read section
while (Serial.available())
{
// continue as before
EDIT 2
编辑 2
Here's what I get when interfacing with your Arduino app from Python:
这是我从 Python 与您的 Arduino 应用程序交互时得到的信息:
>>> import serial
>>> s = serial.Serial('/dev/tty.usbmodem1411', 9600, timeout=5)
>>> s.write('2')
1
>>> s.readline()
'Arduino received: 2\r\n'
So that seems to be working fine.
所以这似乎工作正常。
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:
在测试你的 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()
Here's the output of the above now:
现在是上面的输出:
$ 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
回答by Thushara Madushan
First you have to install a module call Serial. To do that go to the folder call Scripts which is located in python installed folder. If you are using Python 3 version it's normally located in location below,
首先,您必须安装一个模块调用 Serial。为此,请转到位于 python 安装文件夹中的文件夹调用脚本。如果您使用的是 Python 3 版本,它通常位于下面的位置,
C:\Python34\Scripts
Once you open that folder right click on that folder with shift key. Then click on 'open command window here'. After that cmd
will pop up. Write the below code in that cmd
window,
打开该文件夹后,使用 shift 键右键单击该文件夹。然后单击“在此处打开命令窗口”。之后cmd
会弹出。在该cmd
窗口中编写以下代码,
pip install PySerial
and press enter.after that PySerialmodule will be installed. Remember to install the module u must have an INTERNET connection.
然后按回车。之后PySerial模块将被安装。记住安装模块你必须有一个互联网连接。
after successfully installed the module open python IDLE and write down the bellow code and run it.
成功安装模块后打开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])
回答by Huidong Wei
I found it is better to use the command Serial.readString()
to replace the Serial.read()
to obtain the continuous I/O for Arduino.
我发现最好使用命令Serial.readString()
替换Serial.read()
以获得 Arduino 的连续 I/O。