简体   繁体   English

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

[英]Why does my python serial code not work, while sending the same data from the arduino serial monitor does?

I have an arduino that reads in two ints over a serial connection when I send the data from the arduino serial monitor it works as it should, but no matter what I do I can't get it to work when I send the same data from python using pySerial, I have been at this hours and have gotten nowhere我有一个 arduino,当我从 arduino 串行监视器发送数据时,它通过串行连接读取两个整数,它可以正常工作,但是无论我做什么,当我发送相同的数据时,它都无法工作python 使用 pySerial,我一直在这个时间并且一无所获

I have tried encoding the data as utf8, different encodings flushing the output buffer and have read too many other similar stackoverflow Q&As to count我尝试将数据编码为 utf8,不同的编码刷新输出缓冲区,并阅读了太多其他类似的 stackoverflow Q&A 来计算

I am using python 3.7.1 in Windows 10 but the code will untimately be running on a Rpi我在 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);
  }
}

I send "1,100" from the arduino serial monitor and the uno responds with "theres Data" and on the software serial it prints the values it was just sent this works but when I try to send "1,100\\r" from my python script nothing happens the script runs without error the Rx led on the uno flashes but there is no output on the software serial port It must be something wrong with my python serial code.我从 arduino 串行监视器发送“1,100”,uno 以“theres Data”响应,并在软件串行上打印刚刚发送的值,这有效,但是当我尝试从我的 python 脚本发送“1,100\\r”时什么也没有发生脚本运行没有错误 uno 上的 Rx 指示灯闪烁,但软件串行端口上没有输出 这一定是我的 python 串行代码有问题。

You are missing the part where you read from the port.您错过了从端口读取的部分。

Contrary to the terminal or serial monitor, where everything that arrives to the port is immediately and automatically displayed, with pyserial you need to explicitly read bytes from the RX buffer:与终端或串行监视器相反,到达端口的所有内容都会立即自动显示,使用 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

You need to choose one of those and add it to your code.您需要选择其中之一并将其添加到您的代码中。

To make sure you read everything you can add a loop to read until nothing else is waiting in the buffer and maybe a certain amount of time elapses:为了确保您阅读了所有内容,您可以添加一个循环来读取,直到缓冲区中没有其他内容等待并且可能经过一定的时间:

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)

This will keep reading for 1 second after the buffer is detected to be empty.这将在检测到缓冲区为空后继续读取 1 秒。 I took it from here .我从这里拿的。

EDIT: As you say in the comments, you were indeed missing the read commands but that was on purpose.编辑:正如您在评论中所说,您确实错过了读取命令,但这是故意的。

Your other potential problem is the way you handle Serial.parseInt() on your Arduino code.您的另一个潜在问题是您在 Arduino 代码上处理Serial.parseInt()的方式。

Serial.parseInt() reads integer values up to the delimiter (in your case the colon) but you need to explicitly call Serial.read() to swallow the delimiter itself. Serial.parseInt()读取整数值直到分隔符(在您的情况下为冒号),但您需要显式调用Serial.read()以吞下分隔符本身。 So just try calling Serial.read() after every Serial.parseInt() and your code should work.所以只是尝试调用Serial.read()每隔后Serial.parseInt()和你的代码应该工作。

One other thing you can do is to compare the result of Serial.parseInt() with 0 to check if you got a timeout.您可以做的另一件事是将Serial.parseInt()的结果与 0 进行比较,以检查是否超时。

So I have managed to make it work.所以我设法让它工作。 (for now, I think) I put back a 2 sec wait (which I had when I first wrote this code) after opening the port in my python code and changed my write command to ser.write(bytes(b'4,5\\n')) I also removed the ser.flushOutput() and it seems to be working okay. (目前,我认为)在我的 python 代码中打开端口并将我的写入命令更改为ser.write(bytes(b'4,5\\n'))我也删除了ser.flushOutput()并且它似乎工作正常。 I didn't need to make any changes to the arduino code.我不需要对 arduino 代码进行任何更改。 I have no real idea why all of a sudden it now works as the code I now have is almost identical to what I started with before I started debugging it and trying to make it work, which is infuriating to me as I have no clue what I did to fix it :<我不知道为什么突然它现在可以工作了,因为我现在拥有的代码几乎与我开始调试并尝试使其工作之前开始的代码相同,这让我很生气,因为我不知道是什么我确实修复了它:<

Thanks All谢谢大家

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM