I'm working on a school project to build a hovercraft and I'm really new to coding and need help troubleshooting this code. So far the code is receiving input from the distance sensor and generates a decreased duty cycle (to reduce fan/LED output) in response to a smaller error. However when the input is greater than the setpoint, there is no output (output=0).
I'm very confused by this and have tried everything I can think of (from using abs then incorporating a separate function (as shown)).
Note: I am using an Arduino UNO and an LED (in place of a fan)
/******************************************************************************
Pin 1 VCC (URM V3.2) -> VCC (Arduino)
Pin 2 GND (URM V3.2) -> GND (Arduino)
Pin 4 PWM (URM V3.2) -> Pin 3 (Arduino)
Pin 6 COMP/TRIG (URM V3.2) -> Pin 5 (Arduino)
Pin 9 (Arduino) -> Mosfet Gate Pin (Left)
Source Voltage -> LED, Resistor and Mosfet Drain Pin (Middle)
Ground -> Mosfet Source Pin (Right)
******************************************************************************/
int mosfetLED = 9; // Pin to modulate Mosfet Gate
int uPWM = 3; // PWM Output for URM37 (u) Comp Pin
int uTRIG = 5; // PWM Input for URM 37 (u) to Trigger the PWM Pin
double Input = 0; // Sets Distance Variable back to zero
uint8_t EnPwmCmd[4]={0x44,0x02,0xbb,0x01};
/* Enables EPROM Writing (0x44), Establishes Mode of Operation (0xx02),
to be PWM Passive Mode (0xbb), Sum=Low 8 bit of the sum of
command+data0+data1 (0x01) (Reutilized from Jiang from DFRobot)
Note: uint8_t is shorthand for unsigned int of 8 bit length */
#include <PID_v1.h> // Calls in the PID Library
double Setpoint, Output; // Define the variables for input data
double aggKp = 8, aggKi = 0.4, aggKd = 2; // Define the PID aggressive tuning parameters
double consKp = 1, consKi = 0.05, consKd = 0.25;
//Set conservative tuning parameters
PID myPID (&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
// What does this do?
// ????? Will double and unsigned integers be a problem??
double gap; // Distance away from setpoint
// Stand-in Variables:
// double DistanceMeasured = 2000;
void setup() {
Serial.begin (9600); // Sets the baud rate to 9600
pinMode (uTRIG, OUTPUT); // Connects to COMP/TRIG Pin on URM37 to initiate the pulse
digitalWrite (uTRIG, HIGH); // Won't trigger URM37 (u) (PWM Pin) until LOW again
pinMode (uPWM, INPUT); // Input receives time data between pulses
pinMode (mosfetLED, OUTPUT); // Allows pin 9 to modulate a MOSFET Transistor connected to an LED
for (int i=0;i<4;i++){ // Runs URM37 in passive mode four times ???? 4 bits of data??
Serial.write (EnPwmCmd[i]); // Writes to the serial monitor the data received from the URM37 ???????
}
Setpoint = (20); // Desired distance (20 cm)
myPID.SetMode (AUTOMATIC); // Activate the PID Control
}
void loop () {
digitalWrite (uTRIG, LOW); // Triggers the relase of an Ultrasonic signal
digitalWrite (uTRIG, HIGH); // Returns to normal, off position
double DistanceMeasured = pulseIn (uPWM,LOW);
// Counts the ms between LOW readings
if (DistanceMeasured == 50000){ // the reading is invalid
Serial.print ("Invalid");
}
else{
Input = DistanceMeasured/50; // When valid, every 50ms low level stands for 1cm
}
void PIDfunction ();
double DutyCycle = ((Output/256)*100); // Finds duty cycle percent outpout
Serial.print ("Input = "); // Displays Variable Name
Serial.print (Input); // Displays the distance measurement
Serial.println (" cm"); // Display units and advances a line
Serial.print ("Output = "); // Displays Variable Name
Serial.println (Output); // Displays Variable Value
Serial.print ("Duty Cycle = "); // Displays Variable Name
Serial.print (DutyCycle); // Displays Variable Value
Serial.println ("%"); // Display units and advances a line
Serial.print ("Gap = "); // Displays Variable Name
Serial.print (abs (gap)); // Displays Variable Value
Serial.println (" cm"); // Display units and advances a line
Serial.println (" "); // Advances a line
}
void PIDfunction () {
gap = (Setpoint - Input); // Distance away from setpoint
if (gap < 8) {
myPID.SetTunings (consKp, consKi, consKd);
// Close to Setpoint and don't want to overshoot, use conservative parameters
}
else {
myPID.SetTunings (aggKp, aggKi, aggKd);
// Farther away and need more aggresive repsonse to return
}
myPID.Compute (); // Compute PID to solve for Output
if (Output > 0) {
digitalWrite (mosfetLED, Output); // Output variable modulates LED brightness
delay (500);
}
else {
gap = (Input - Setpoint); // Distance away from setpoint
if (gap < 8) {
myPID.SetTunings (consKp, consKi, consKd); // Close to Setpoint and don't want to overshoot, use conservative parameters
}
else {
myPID.SetTunings (aggKp, aggKi, aggKd); // Farther away and need more aggresive repsonse to return
}
myPID.Compute (); // Compute PID to solve for Output
digitalWrite (mosfetLED, Output); // Output variable modulates LED brightness
delay (500);
}
}
I wondered if anyone could help me with this issue. I would really appreciate any feedback (whether it be on coding, annotating, or other)!
