python到arduino串行读取&写 [英] python to arduino serial read & write

查看:26
本文介绍了python到arduino串行读取&写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在一些 python 代码和 arduino 代码之间来回乒乓"信息.我想定期(例如在分钟上)向 arduino 代码发送两个设定点,在 arduino & 上阅读它们.更新变量然后定期将状态信息从arduino发送回python(例如:30秒).最终,python 将从 mySQL 数据库(后来的开发)发送和提取信息.

现在我无法让信息可靠地来回反弹.我在搜索中没有发现任何与此类似的东西,而且我尝试修改的所有内容都不起作用.我最接近的是这个(它实际上并没有在发送和接收之间来回切换):

蟒蛇

#!/usr/bin/python导入序列导入系统日志导入时间#以下行用于通过 GPIO 串行端口 = '/dev/ttyS0'ard = serial.Serial(port,9600,timeout=5)我 = 0而 (i <4):# 串口写入部分setTempCar1 = 63setTempCar2 = 37ard.flush()setTemp1 = str(setTempCar1)setTemp2 = str(setTempCar2)打印(发送的Python值:")打印(setTemp1)ard.write(setTemp1)时间.sleep(4)# 串行读取部分msg = ard.readline()打印(来自arduino的消息:")打印(味精)我 = 我 + 1别的:打印退出"出口()

阿杜诺:

//串口测试脚本int setPoint = 55;字符串读取字符串;无效设置(){Serial.begin(9600);//以 9600 bps 初始化串行通信}空循环(){while(!Serial.available()) {}//串行读取部分而 (Serial.available()){如果(Serial.available()> 0){char c = Serial.read();//从串行缓冲区中获取一个字节读取字符串 += c;//使字符串为readString}}if (readString.length() > 0){Serial.print("Arduino 收到:");Serial.println(readString);//查看收到了什么}延迟(500);//串行写入部分char ard_sends = '1';Serial.print("Arduino 发送:");Serial.println(ard_sends);Serial.print("\n");串行.flush();}

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

按照下面的建议将代码修改为我当前正在运行的代码.Arduino 正在接收由 minicom 验证的良好和串行通信.但是python脚本在来自arduino的消息:"之后仍然打印一个空行.

解决方案

在 Python 中,您不应该在写入和读取之间关闭串行端口.Arduino响应时有可能端口仍然关闭,在这种情况下数据将丢失.

 运行时:# 串口写入部分setTempCar1 = 63setTempCar2 = 37setTemp1 = str(setTempCar1)setTemp2 = str(setTempCar2)打印(发送的Python值:")打印(setTemp1)ard.write(setTemp1)time.sleep(6) # 端口打开时,响应将被缓冲# 所以在这里稍等一会回复# 串行读取部分msg = ard.read(ard.inWaiting()) # 读取输入缓冲区中的所有内容打印(来自arduino的消息:")打印(味精)

Python Serial.read 函数默认只返回一个字节,因此您需要在循环中调用它或等待数据传输完毕然后读取整个缓冲区.

在 Arduino 方面,您应该考虑在没有数据可用时 loop 函数中会发生什么.

void loop(){//串行读取部分while (Serial.available())//如果没有数据,这将被跳过,导致//下面的延迟函数中的代码{延迟(30);//延迟以允许缓冲区填充如果(Serial.available()> 0){char c = Serial.read();//从串行缓冲区中获取一个字节读取字符串 += c;//使字符串为readString}}

相反,在 loop 函数开始处等待,直到数据到达:

void loop(){while (!Serial.available()) {}//等待数据到达//串行读取部分而 (Serial.available()){//像以前一样继续

编辑 2

这是我从 Python 与您的 Arduino 应用程序交互时得到的结果:

<预><代码>>>>导入序列>>>s = serial.Serial('/dev/tty.usbmodem1411', 9600, timeout=5)>>>s.write('2')1>>>s.readline()'收到 Arduino:2\r\n'

所以这似乎工作正常.

在测试您的 Python 脚本时,问题似乎是当您打开串行端口时 Arduino 会重置(至少我的 Uno 是这样),因此您需要等待几秒钟才能启动.您也只读取一行响应,所以我也在下面的代码中修复了这个问题:

#!/usr/bin/python导入序列导入系统日志导入时间#以下行用于通过 GPIO 串行port = '/dev/tty.usbmodem1411' # 注意我使用的是 Mac OS-Xard = serial.Serial(port,9600,timeout=5)time.sleep(2) # 等待 Arduino我 = 0而 (i <4):# 串口写入部分setTempCar1 = 63setTempCar2 = 37ard.flush()setTemp1 = str(setTempCar1)setTemp2 = str(setTempCar2)打印(发送的Python值:")打印(setTemp1)ard.write(setTemp1)time.sleep(1) # 我缩短了它以匹配你的 Arduino 代码中的新值# 串行读取部分msg = ard.read(ard.inWaiting()) # 读取缓冲区中的所有字符打印(来自arduino的消息:")打印(味精)我 = 我 + 1别的:打印退出"出口()

现在是上面的输出:

$ python ardser.py发送的 Python 值:63来自arduino的消息:Arduino收到:63Arduino发送:1发送的 Python 值:63来自arduino的消息:Arduino收到:63Arduino发送:1发送的 Python 值:63来自arduino的消息:Arduino收到:63Arduino发送:1发送的 Python 值:63来自arduino的消息:Arduino收到:63Arduino发送:1退出

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()

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.

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: ".

解决方案

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)

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.

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
    }
  }

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

EDIT 2

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\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:

#!/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

这篇关于python到arduino串行读取&amp;写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆