Python与Arduino串行通信产生半随机结果

时间:2019-03-21 22:41:25

标签: python arduino pyserial serial-communication duplex

我正在尝试让一个Arduino通过传感器将数据提供给Python。然后,当将这些数据接收到Python中时,Python需要将信号发送回Arduino,以使电动机对传入的数据做出反应。目前,我的代码会导致这种情况,但是,如果我查看数据,将会发现随机峰值的数据与场景不符。例如,我将5牛顿的负载放在传感器上,它将读取5牛顿的几次迭代,然后它会突增到随机的值。我只看了Arduino IDE中的Arduino输出,它是稳定而持续的数据流。我已经看过Python在没有发出信号的情况下收到了什么,并且给出了与Arduino相同的东西。我不知道为什么当我不得不两次来回发送信息时会遇到此问题。如果有人对如何获得良好的阅读有更好的解决方案,我将不胜感激。

Python

import serial
import csv
import time
import sys
from time import localtime, strftime
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,timeout=1)
time.sleep(2)
start_time=time.time()
Force = []
Actuator_Signal=[]
Cycle_Count=[]
state = True
Up = True
numPoints = 10
ForceList = [0]*numPoints
AvgForce = 0

#This allows the user to input test conditions.
Force_Input = input("What is the force you want to test with in Newtons?")
Cycles = input("How many cycles would you like to run?")
Material = input("What kind of material is to be tested?")
print("The test will be conducted with", Force_Input, " Newtons of force and for a total of" , Cycles, " cycles.", " on", Material)
print ("REMOVE HANDS AND OTHER OBJECTS AWAY FROM AREA OF OPERATION.")
print("Testing will begin.")
time.sleep(5)

start_time = time.time()
#This creates the unique file for saving test result data.
outputFileName =  "  Cycle_Pull_Test_#.csv"
outputFileName = outputFileName.replace("#", strftime("%Y-%m-%d_%H %M %S", localtime()))


with open(outputFileName, 'w',newline='') as outfile:
    HeaderNames = ['Material','Newtons','Time']
    outfileWrite = csv.DictWriter(outfile, fieldnames = HeaderNames)
    outfileWrite.writeheader() 
#This takes the data from the arduino and interprits it.
    while True:

        while (Arduino.inWaiting()==0):
            pass
        try:
            data = Arduino.readline()
            dataarray = data.decode().rstrip().split(',')
            for i in range(0,numPoints):
                Force = abs(round(float(dataarray[0]),3))
                ForceList[i] = Force
                AvgForce = round((sum(ForceList)/numPoints),3)
                elapsed_time = round(time.time()-start_time,3)
                print (AvgForce, elapsed_time)

#This Controls the actuators direction based on the force input on the loadcell.

            if AvgForce > float(Force_Input):
                Up = False
                state = True 
                Arduino.write(b'd') 
            else: 
                Arduino.write(b'u')
                Up = True
            if state == True and Up == True:
                state = False
                Cycles = float(Cycles) + 1

            if Cycles >= float(Cycle_Count[0]):
                Arduino.write(b'o')
                print("Testing is done.")
                time.sleep(1) 
                sys.exit("All the data will be saved now")



        except (KeyboardInterrupt, SystemExit,IndexError,ValueError):
            pass
#This writes the data from the loadcell to a csv file for future use.
        outfileWrite.writerow({'Material' : Material, 'Newtons' : AvgForce, 'Time' :elapsed_time })

Arduino

#include <HX711_ADC.h> // HX711 Library
#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;
int python_direction = 0;
float interval = 12000;
float pretime= 0;
float curtime = 0;

HX711_ADC LoadCell(11, 12);

float force;  
float calforce;
float newtons;

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.0); // user set calibration factor (float)


}

void loop() {
  LoadCell.update();

  forceRead();
  actuatorControl();


}void forceRead()
{
  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;
  Serial.println(newtons);


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

void actuatorControl(){

  if (Serial.available()>0){
    python_direction = Serial.read();
    Serial.print (python_direction);
    Serial.print (",");
  }
  if (python_direction == 'd'){
    motor.setSpeed(255);  // Run forward at full speed.

  }
  if (python_direction == 0){
    motor.setSpeed(0);  // Stop motor.

  }
  if (python_direction == 'u'){
    motor.setSpeed(-255);  // Run backward at full speed.


  }
}

0 个答案:

没有答案