Hi.
I am trying to put together a Depth controller for a RoV (remotely operated vehicle).
I think I have the Pid working OK.
My issue at the moment is with the output.
The output will be going into a ESC that’s reversible.
With a input of 90 the ESC is idle and a input of 0 is max speed reverse and a input of 180 its max speed forward.
Not sure on how to implement that into the code below.
/* Depth control
Thanks to Brett Beauregard for the Pid Library.
Arduino PID Library - Version 1.0.1 by Brett Beauregard <br3ttb@gmail.com> brettbeauregard.com
NOT yet completed on 06 June 2012
*/
#include <PID_v1.h>
double requireddepth, actualdepth, adjust;
PID myPID(&actualdepth, &adjust, &requireddepth,2,5,1, DIRECT);
void setup()
{
Serial.begin(9600);
myPID.SetMode(AUTOMATIC);
}
void loop()
{
actualdepth = (analogRead(A1)- 494); // POT to alter depth
requireddepth = analogRead(A2); // POT to alter required depth
myPID.Compute();
int temp = adjust - 90;
Serial.print("speed of ESC = "); // the ESC is a revising capable and 90 being idle 0 fast reverse and 180 fast forward
Serial.print(temp);
Serial.print(" Actual Depth ");
Serial.print(actualdepth);
Serial.print(" Required depth = ");
Serial.println(requireddepth);
}
This is still in the sketch stage ATM and I do have a pressure sensor , a pot and a servo to test the outputs.
Any advice on this Please.
Regards Antony
You want the PID to control Speed and Direction to maintain depth. Motor speed would be positive or negative. For your purposes you have the motor speed (temp) got from -90 to + 90. (when you write to the controller you use temp + 90)
If you are too deep you need a positive speed, and if you are too shallow you need a negative speed. Positive speed takes you up, and negative speed takes you down.
You might need to simulate the submarine by using a continuous rotation servo and a potentiometer. If you try doing it with just a potentiometer you will see the output value head toward the limit because the pot is not responding to the changing output value.
You might need to simulate the submarine by using a continuous rotation servo and a potentiometer. If you try doing it with just a potentiometer you will see the output value head toward the limit because the pot is not responding to the changing output value.
yes I understand that.
But how will a continuous rotation servo help me??
The depth is measured with a pressure sensor. with the output "actualdepth"
A little background on its control method:- I use a joystick to control the depth. And when I release the joystick it goes into neutral.
At this point I need to have a auto depth hold.
I am able to apply pressure to the sensor to simulate the depth and adjust as nessaery.
I have never used a pid, but how about setting the initial value of the ESC to 90 and add the adjustment from the pid to it on each iteration. Use constrain to ensure it stays within range.
It depends what form the inputs and outputs to/from the PID take, and how you're going to relate these to the raw 'depth' input and the raw 'vertical drive control' output. This needs to be set up to suit your PID parameters.
For example, if you design the PID settings to suit inputs and outputs in the range 0 .. 1 then you can offset and scale the inputs and outputs to suit that. If you want your PID to output 0 ..255 values then that will need very different PID parameters to achieve the same response characteristics.
So, yuou have to decide what the input and output values to the PID mean, configure the PID to suit those definitions, and then transform the raw values to/from that form. (If you decide to set it up to use the raw values directly then of course the transformation is a no-op.)
Peter :- I know very little about Pid's I have read all the info on the site were I got the Pid from..
I am not sure what you are telling me but I will do my best to understand.
The pressure sensor (MSP3101P2-ND) 100psi, output voltage .5 to 4.5 volts
I am using a analog input that is in the range of 0 (on surface) to 1024(Max depth 58.512 mtr)
The Pid outputs should a value range -90 to +90 so I can add to 90 (idle point)
As I am typing this I sort understand were you are coming from
Gona play for a while and see what I can achieve.
Hi People.
Still getting no joy with this.
It is very similar to a auto altitude hold on a helicopter.
I have been at this for some 16 hours now and such a simple project is not so simple.
The test rig is flawed as suggested by 2nd post.
Looking for any Help/Sugestions/Directions.
This doesn't tell us squat. The code is doing something. You want it to be doing something. The no joy statement implies (vaguely) that the two somethings are not the same thing. We don't know what either thing is, though.
Your PID algorithm is working on some inputs and outputs that you define. They will relate to inputs and outputs on your Arduino.
As the programmer, you have control over the raw values on the external interface, and the values that your PID algorithm uses. For example you might choose to pass the raw inputs straight to the PID and use the PID output directly. Or you might choose to normalise/condition the inputs and outputs that the PID uses.
You need to choose what the PID input and output values will be before you can tune the PID parameters. It's not hard, but you have to do it.
Hi.
Paul.S I have been trying to put together other different code and found them all to be nothing like whats wanted. If I could give you any facts then I would. But at the moment nothing is right with my programming.(only just started Arduino)
PeterH. Hi. The inputs.. Normalise/Condition ?? Is this to bring then all into the same range ??
And the values to change .. I have no idea here on what to change. Suggestion's please.
Hi.
I have decided not to use the PID method with the Depth maintaining sketch.
I have put together a sketch that is just simple If and Else to get the job done.
#include <Servo.h>
int requireddepth = 0; // variable to store the value coming from the sensor
int currentdepth = 0;
int tick = false;// Am I already in LOOP
int Virt_thruster_adjust = 0;// Amount to maintian depth
int vertical_thruster = 90;// actual thruster speed forward or revirse
int Vertical_Potentiometer ;// Signal from topside control box
Servo Vertical_Thruster;
void setup() {
Serial.begin(9600);
Vertical_Thruster.attach(9);
}
void loop() {
Vertical_Potentiometer = analogRead(A0); // same as signal from topside control
Vertical_Potentiometer = map(Vertical_Potentiometer, 0 , 1023 , 0 , 180);// 0 to 180 out
if ( Vertical_Potentiometer > 88 && Vertical_Potentiometer < 92 ) { //Skips if joystick is centred SO Hold current depth
currentdepth = analogRead(A3); // take a depth reading with Pressure sensor
if (tick == false){ // I want to do this Hold Depth
requireddepth = currentdepth; // Now hold this as a referance point
tick = true; // Now I cannot redo the requird depth and I am in Depth maintain loop
}
//********** AREA here is still not skiping if currentdepth = requireddepth + or - 2..Not sure how to fix this
currentdepth = analogRead(A3); //Take another reading as first is in check loop with Pressure sensor
if (currentdepth > requireddepth){
Virt_thruster_adjust = Virt_thruster_adjust - 1; // Decrease thruster speed
Serial.print (" Go up ");
}
if (currentdepth < requireddepth){
Virt_thruster_adjust = Virt_thruster_adjust + 1; // Increase thruster speed
Serial.print (" Go Down ");
}
}
vertical_thruster = Vertical_Potentiometer + Virt_thruster_adjust;
if ( Vertical_Potentiometer > 88 && Vertical_Potentiometer < 92 ) { // Still in centre
tick = true; // DONT do this loop as Depth is OK
}
else{
tick = false; // go back to surface control as No longer in Depth maintain loop
Serial.print("tick = ");
Serial.print(tick); // Tick should be 0 here
vertical_thruster = Vertical_Potentiometer; // resets to centre/netual postition
Virt_thruster_adjust = 0; // remove anything here as its no longer wanted
}
if(vertical_thruster > 180) vertical_thruster = 180; // checks the range does not excide limmets
if(vertical_thruster < 0) vertical_thruster = 0;
Vertical_Thruster.write(vertical_thruster); //Continious rotation Servo in here for Testing
Serial.print(" Virtical Thruster Speed = ");
Serial.println(vertical_thruster);
delay(100);
}// ************************************************* END of MAIN LOOP ****************************************
Posted the code for comments on How best to format and code flow.
One area that needs work is the Part marked half way down the code.
Marked with :- ********** AREA here is still not skipping if currentdepth = requireddepth + or - 2..Not sure how to fix this.
Open to questions and corrections.
Regards Antony