python至arduino串行读写

发布于 2021-01-29 17:47:59

我正在尝试在某些python代码和arduino代码之间来回“乒乓”信息。我想定期向arduino代码发送两个设定值(例如在分钟上),在arduino上读取它们并更新变量,然后定期(例如在30秒内)将状态信息从arduino发送回python。最终,python将从mySQL数据库发送信息并从中提取信息(后来的开发)。

现在,我无法获得可靠往返的信息。我没有在搜索中找到与此相近的任何内容,而且我尝试修改的所有内容均无效。我最近的是这个(它实际上并没有在发送和接收之间来回切换):

蟒蛇

#!/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验证的精细和串行通信。但是python脚本在“来自arduino的消息:”之后仍然打印空白行。

关注者
0
被浏览
43
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

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

    PythonSerial.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
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看