python到arduino串口读写

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python到arduino串口读写相关的知识,希望对你有一定的参考价值。

我试图在一些python代码和arduino代码之间来回“ping pong”信息。我想定期向arduino代码发送两个设定值(例如在分钟上),在arduino和更新变量上读取它们,然后定期将状态信息从arduino发送回python(例如:30秒)。最终python将从mySQL db(后来的dev)发送和提取信息。

现在我无法让信息可靠地来回反弹。我在搜索中没有发现任何与此相近的内容,我尝试修改的所有内容都无效。我最近的就是这个(它实际上并没有在发送和接收之间来回切换):

蟒蛇

#!/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("
");
  Serial.flush();
}

我最终得到的是重复的相同值(不是实际发送的,不确定它是否是字符串或字节问题)并且没有回到python脚本。非常感谢任何帮助或想法。谢谢。

编辑:修改代码到我目前正在运行,如下所示。 Arduino正在接收由minicom验证的精细和串行通信。但是python脚本仍然在“来自arduino的消息:”之后打印出一个空行。

答案

您不应该在写入和读取之间关闭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
'

所以这似乎工作正常。

在测试你的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
另一答案

首先,您必须安装模块调用Serial。要做到这一点,请转到文件夹调用Scripts,它位于python安装文件夹中。如果您使用的是Python 3版本,它通常位于以下位置,

C:Python34Scripts  

打开该文件夹后,使用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])   

以上是关于python到arduino串口读写的主要内容,如果未能解决你的问题,请参考以下文章

wxPython-Python:串口问题

arduino 串口不工作

读取 Arduino 的串口

关于Arduino的串口中断

Arduino UNO + Proteus串口通讯仿真实验汇总

python 与Arduino沟通以为是串口