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

时间:2019-07-19 23:12:30

标签: python serialization arduino pyserial

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

我尝试将数据编码为utf8,不同的编码刷新了输出缓冲区,并且读取了太多其他类似的stackoverflow 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串行一定有问题代码。

2 个答案:

答案 0 :(得分:0)

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

与终端或串行监视器相反,到达端口的所有信息都将立即自动显示,而使用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那里拿走了。

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

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

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

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

答案 1 :(得分:0)

所以我设法使它起作用。 (现在,我认为)我在python代码中打开端口并将写命令更改为ser.write(bytes(b'4,5\n'))后,我等待了2秒钟(第一次编写此代码时,我已经等待了) 我还删除了ser.flushOutput(),看来一切正常。我不需要对arduino代码进行任何更改。我不知道为什么突然间它现在能正常工作,因为我现在拥有的代码几乎与我开始调试它并试图使其正常工作之前所开始的代码完全相同,这让我非常恼火,因为我不知道什么我确实修复了它:<

谢谢所有