Pyserial получает противоречивые данные от arduino

#python #arduino #python-3.5 #pyserial

#python #arduino #python-3.5 #pyserial

Вопрос:

Я пытаюсь написать код для датчика, который будет считываться arduino, а затем отправить эти данные в python, чтобы их можно было распечатать и сохранить для будущего анализа. Проблема в том, что когда я смотрю на последовательный монитор arduino, это согласованный поток чисел. Это то, что я хочу, однако, когда это доходит до python, это приводит к случайному умножению этого числа на 100. Это происходит примерно каждые 4 строки данных. У меня возникли проблемы с попыткой выяснить, почему это происходит, основываясь на написанном мной коде и кодах, которые я использовал в качестве рекомендаций.

Arduino

 #include <HX711_ADC.h>
#include "CytronMotorDriver.h"


// Configure the motor driver.
CytronMD motor(PWM_DIR, 3, 2);  // PWM = Pin 3, DIR = Pin 2.

int up = HIGH;
int down = LOW;
int dstate = up;
float interval = 12000;
float pretime= 0;
float curtime = 0; 


// LOAD CELL
//HX711 constructor (dout pin, sck pin)
HX711_ADC LoadCell(11, 12);
float force;  
float calforce;
float newtons;


// The setup routine runs once when you press reset.
void setup() {
 Serial.begin(9600);
 LoadCell.begin();
 LoadCell.start(2000); // tare preciscion can be improved by adding a few seconds of stabilising time
 LoadCell.setCalFactor(100); // user set calibration factor (float)
}

// The loop routine runs over and over again forever.
void loop() {

  LoadCell.update();
  force = LoadCell.getData();
  force = (force/285); // Force in (N) // 285 is conversion factor
  calforce = (-1.0389*force) 0.0181, // This is in lbs
  newtons = 4.45*calforce;



  //receive from serial terminal for tare
  if (Serial.available() > 0) {
  char inByte = Serial.read();
  if (inByte == 't') LoadCell.tareNoDelay();
  }

unsigned long curtime = millis();

  if (dstate == up amp;amp; (curtime - pretime >= interval)) {
    motor.setSpeed(255);  // Run forward at full speed.
    pretime = curtime; 
    dstate = down;


  }

  if (dstate == down amp;amp; (curtime - pretime >= interval)) {
    motor.setSpeed(-255);  // Run backward at full speed.
    pretime = curtime;
    dstate = up;

  }


  Serial.println(newtons);
}
  

Вывод Arduino
0.08
0.08
0.08
0.08
0.08
0.08
0.08
0.08
0.08
0.08
0.08
0.08

Python

 import serial
import csv
import time
from time import localtime, strftime
#import numpy as np
import warnings
import serial.tools.list_ports


__author__ = 'Matt Munn'
arduino_ports = [
    p.device
    for p in serial.tools.list_ports.comports()
    if 'Arduino' in p.description
]
if not arduino_ports:
    raise IOError("No Arduino found - is it plugged in? If so, restart computer.")
if len(arduino_ports) > 1:
    warnings.warn('Multiple Arduinos found - using the first')

Arduino = serial.Serial(arduino_ports[0],9600)

Arduino.flush()
Arduino.reset_input_buffer()

start_time=time.time()

Force = []

outputFileName = "Cycle_Pull_Test_#.csv"
outputFileName = outputFileName.replace("#", strftime("%Y-%m-%d_%H %M %S", localtime()))

with open(outputFileName, 'w',newline='') as outfile:

    outfileWrite = csv.writer(outfile)

    while True:
        while (Arduino.inWaiting()==0):
            pass
        try:
            data = Arduino.readline()
            dataarray = data.decode().rstrip().split(',')
            Arduino.reset_input_buffer()
            Force = round(float(dataarray[0]),3)
            print (Force)
        except (KeyboardInterrupt, SystemExit,IndexError,ValueError):
            pass

        outfileWrite.writerow([Force,"N"])
  

Вывод на Python
0.08
8.0
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08
8.0
0.08

Это всего лишь голые кости моего кода, я намерен управлять линейным приводом на основе показаний датчика, но если я не смогу обеспечить согласованность этого потока данных, то я не смогу продолжить проект. Спасибо!

Комментарии:

1. Примеры правильных и неправильных последовательных данных значительно прояснили бы этот вопрос. Я подозреваю, что проблема заключается в Arduino.reset_input_buffer() вашем цикле — единственное, чего можно достичь, это выбросить действительные данные, хотя это, скорее всего, приведет к слишком маленьким результатам, а не к слишком большим.

2. Когда он запущен, поток данных составляет что-то вроде 0.08 0.08 8 0.08 0.08 0.08 8, это пример вывода, который я обычно получаю. В идеале я бы хотел, чтобы это был просто поток 0,08 или любое другое числовое значение, которое считывает arduino.

3. Похоже, что reset_input_buffer() отсекает первые три символа следующего чтения.

4. Я удалил это на основе вашей рекомендации, и, похоже, ничего не изменилось с моим считыванием данных.

5. Я удалил flush() строку, и теперь, похоже, она работает на данный момент.