0

I am having issues with my PID controller for a BAR 30 depth sensor. The issue that I have is my ESC have two initial start up { 1500 - 1900} is min - max respectively clockwise and { 1500-1900} is max respectively counter clockwise. What I want is for me to set a depth and I can submerge to a certain depth and lock in at that certain depth.

#include <PID_v1.h>
#include <MS5837.h>
#include <Wire.h>
#include <Servo.h>
MS5837 sensor;
Servo vertical_thruster1;


// Variables

float current_depth ;
float set_depth = 0.50 ; //  depth u wish to go in meters 
float PID_error = 0;
float previous_error = 0;
float elapsedTime,  Time , timePrev;
double pwmvertical_thruster1 = 1440;

int s;

float PID_value = 0;
float PID_p = 0;
float PID_d = 0;
float PID_i = 0;
//PID constants
float kp = 100;         
float ki = 0.003;
float kd = 5.2;




void setup() {
  Serial.begin(9600);  
 vertical_thruster1.attach(4);
   vertical_thruster1.writeMicroseconds(1500);

 Time = millis ();

 ///Bar 30 Configuration 

  Serial.println("Starting");  
  Wire.begin();
 while (!sensor.init()) {
Serial.println("Init failed!");
Serial.println("Are SDA/SCL connected correctly?");
Serial.println("Blue Robotics Bar30: White=SDA, Green=SCL");
Serial.println("\n\n\n");
delay(2000);
  }  
  sensor.setModel(MS5837::MS5837_30BA);
  sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
}

void loop() {

///*  
// First read the current value of the depth sensor
sensor.read();    
current_depth = sensor.depth();

timePrev = Time; 
Time= millis();
elapsedTime = ( Time - timePrev) / 1000;

// calculate the error between the set depth and current depth  
 PID_error =  set_depth - current_depth ;

 // Calculate the P Value
 PID_p = kp * PID_error;
   Serial.print("PID_p: ");
    Serial.print(PID_p);
    Serial. println ( "\t\t");
// Calculate the i value in a range on +-0.3 

 if (-0.2 < PID_error < 0.2) 
 { 
  PID_i = PID_i + (ki * PID_error);
 }
Serial.print("PID_i: ");
Serial.print(PID_i);
Serial. println ( "\t\t");
// Calculate the d value 
 PID_d = kd*((PID_error - previous_error)/elapsedTime);
Serial.print("PID_d: ");
Serial.print(PID_d);
Serial. println ( "\t\t");
// The total PID value 
PID_value = (PID_p + PID_i + PID_d) ; 

// range for the blue robotics esc

if ( PID_value < -150)
 { 
 PID_value = -150;
  }
  if( PID_value >150)
  { 
  PID_value = 150;

  }
  Serial.print("PID_value: ");
  Serial.print(PID_value);
  Serial. println ( "\t\t");
 // calcualte the pwm 

 s =  (pwmvertical_thruster1 + PID_value  );
 if(s < 1350)
{
 s= 1450;

}
else if(s> 1650)
{
  s=1550;

}
  Serial.print("Depth: "); 
  Serial.print(sensor.depth()); 
  Serial.println(" m");
  Serial.print ( "Speed s  ");
  vertical_thruster1.writeMicroseconds(s);
  Serial.print( s) ;  
  Serial. println ( "\t\t");
  previous_error = PID_error;
  //  */
  delay(300);
 }
2

A PID controller should be a good match for your application, but it appears that your code doesn't take advantage of the PID_v1 library at all; a PID_v1 object is never declared, and it appears you are attempting to manually compute what the PID library is designed to do for you automatically.

I would recommend you 'start slow and simple' by learning how to use a PID controller in its most basic form. The PID library has a very basic example, which I have modified slightly to demonstrate how a PID controller works. I tested this example with a UNO, a potentiometer (variable resistor) and a capacitor. The resistor and capacitor values aren't critical - I used the first things I found in my parts box. The output on Pin 3 is a PWM pulse train signal, and the resistor/capacitor combination filters this pulse train to a variable level analog signal, which the PID controller sees as the analog 'Input' on A5.

Once you have this running, you can vary the pot value to see how the PID changes the output value in order to achieve the setpoint value on the input, and you can vary the setpoint and PID parameters to play around with different configurations. Once you are comfortable with basic PID operation, you should then be able to configure it properly for your application.

Hope this helps,

#include <PID.h>

 //Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 2, 5, 1, DIRECT);

void setup()
{
    Serial.begin(115200);

    //initialize the variables we're linked to
    //Input = analogRead(0);
    Input = analogRead(A5);  //I used A5 as A0 was unavailable
    Setpoint = 100;

    //turn the PID on
    myPID.SetMode(AUTOMATIC);
}

void loop()
{
    //Input = analogRead(0);
    Input = analogRead(A5); //I used A5 as A0 was unavailable
    myPID.Compute();
    analogWrite(3, Output);
    Serial.print("Input = "); Serial.print(Input); Serial.print(", Output = "); Serial.println(Output);
    delay(100);

}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.