为啥我的 python 串行代码不起作用,而从 arduino 串行监视器发送相同的数据?

Posted

技术标签:

【中文标题】为啥我的 python 串行代码不起作用,而从 arduino 串行监视器发送相同的数据?【英文标题】:Why does my python serial code not work, while sending the same data from the arduino serial monitor does?为什么我的 python 串行代码不起作用,而从 arduino 串行监视器发送相同的数据? 【发布时间】:2019-07-19 23:12:30 【问题描述】:

我有一个 arduino,当我从 arduino 串行监视器发送数据时,它通过串行连接读取两个整数,它可以正常工作,但无论我做什么,当我发送使用 pySerial 来自 python 的相同数据,我一直在这个时间,却一无所获

我已经尝试将数据编码为 utf8,不同的编码会刷新输出缓冲区,并且已经阅读了太多其他类似的 *** Q&A 来计数

我在 Windows 10 中使用 python 3.7.1,但代码将不合时宜地在 Rpi 上运行

import os
import time
import serial
ser = serial.Serial('COM7', baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=5)
print("writting")
time.sleep(0.5)
ser.write(b'4,5')
ser.write(b'\r\n')
time.sleep(0.5)
ser.flushOutput()
ser.close()

#include <SoftwareSerial.h>
byte buttonPin = 9;
const int pin_led = LED_BUILTIN; // Pin for indication LED
int sensorPin = A0;
int sensorValue = 0;
int remotePower = 0;  

SoftwareSerial mySerial(11, 12); // RX, TX

void setup()

  pinMode(pin_led, OUTPUT); // Set LED pin as output
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);


int oldremotePower = 0; 

void loop()

  // if there's any serial available, read it:
  while (Serial.available() > 0) 
    Serial.println("theres Data");
    // look for the next valid integer in the incoming serial stream:
    int mode = Serial.parseInt();
    // do it again:
    int action = Serial.parseInt();
    // do it again:
    //int blue = Serial.parseInt();

    // look for the newline. That's the end of your sentence:
    if (Serial.read() == '\n') 
      // constrain the values to 0 - 255 and invert
      // if you're using a common-cathode LED, just use "constrain(color, 0, 255);"
      mode = constrain(mode, 1, 4);
      action =  constrain(action, 0, 100);

      mySerial.print(mode);
      mySerial.print(",");
      mySerial.println(action);
    
  


    oldremotePower = remotePower;
    sensorValue = analogRead(sensorPin);
    remotePower = map(sensorValue, 0, 1023, 1, 100);
    if (oldremotePower != remotePower)
      //Serial.println(oldremotePower);
      //Serial.println(remotePower);
        

  if (digitalRead(buttonPin) == LOW) 
    mySerial.println(remotePower);
  

我从 arduino 串行监视器发送“1,100”,uno 以“theres Data”响应,并在软件串行上打印刚刚发送的值 这可行,但是当我尝试从我的 python 脚本发送“1,100\r”时,没有任何反应,脚本运行没有错误,uno 上的 Rx 指示灯闪烁,但软件串行端口上没有输出它一定是我的 python 串行有问题代码。

【问题讨论】:

实际上,我对您的通信结构不太满意,但是您是否尝试过删除ser.flushOutput()?另外,删除 sleep 语句,因为它们是不必要的。 Arduino 在新的 USB 连接上重置 (serial.Serial('COM7')。等待 2 秒,然后将内容发送到您的草图 【参考方案1】:

您缺少从端口读取的部分。

与终端或串行监视器相反,到达端口的所有内容都会立即自动显示,使用 pyserial 您需要从 RX 缓冲区显式读取字节:

incoming = ser.read()     #Read one byte
incoming = ser.read(n)    #Read n bytes, whit n and INT
incoming = ser.readline() #Read everything until a \n is received
incoming = ser.read(ser.inWaiting()) #Read everything in the buffer

您需要选择其中之一并将其添加到您的代码中。

为了确保您阅读了所有内容,您可以添加一个循环来阅读,直到缓冲区中没有其他内容等待并且可能经过了一定的时间:

timeout=time.time()+1.0
while ser.inWaiting() or time.time()-timeout<0.0:
    if ser.inWaiting()>0:
        data+=ser.read(ser.inWaiting())
        timeout=time.time()+1.0
print(data)

在检测到缓冲区为空后,这将继续读取 1 秒。我是从here 那里拿到的。

编辑:正如您在 cmets 中所说,您确实缺少读取命令,但这是故意的。

您的另一个潜在问题是您在 Arduino 代码上处理 Serial.parseInt() 的方式。

Serial.parseInt() 读取整数值直到分隔符(在您的情况下为冒号),但您需要显式调用 Serial.read() 以吞下分隔符本身。因此,只需尝试在每个 Serial.parseInt() 之后调用 Serial.read(),您的代码就应该可以工作了。

您可以做的另一件事是将Serial.parseInt() 的结果与 0 进行比较,以检查您是否超时。

【讨论】:

我想你误解了我从 arduino 读取数据没有问题,只是将数据发送到 arduino 可以忽略从硬件串行接收到的任何数据,因为我不需要/想要任何来自arduino softwareSerial 仅用于调试,应该输出与我使用 arduino 串行监视器时接收的硬件串行接收相同的输出,但是当我使用 python 代码时没有任何反应 根据您更新的评论,我从 Arduino ReadASCIIString 示例开始,并且在 parseInt() 调用之间没有读取,所以我认为 parseInt 跳过了逗号。我已经修复了我的代码(不知何故),所以我要写下我的答案,但是在 parseInt() 之后调用 .read() 是我以后要记住的事情,谢谢你的帮助【参考方案2】:

所以我设法使它工作。 (现在,我想)在我的 python 代码中打开端口并将我的写入命令更改为ser.write(bytes(b'4,5\n')) 我还删除了ser.flushOutput(),它似乎工作正常。我不需要对 arduino 代码进行任何更改。我不知道为什么突然之间它现在可以工作了,因为我现在拥有的代码几乎与我开始调试它并尝试使其工作之前的代码相同,这让我很生气,因为我不知道是什么我确实修复了它:

谢谢大家

【讨论】:

以上是关于为啥我的 python 串行代码不起作用,而从 arduino 串行监视器发送相同的数据?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的代码在传递给 .exe 时不起作用?

为啥我的产品代码的正则表达式不起作用? [关闭]

为啥我的主循环在 tkinter 中不起作用?

为啥这个 Python“循环代码”不起作用?

为啥我的想法在 python2 中不起作用?

串行 AT 命令在 python 脚本中不起作用,但在 Minicom 中起作用