Balance beam using peristaltic pump for RC Boats;

Dear All, I need help with a little project of mine that supposes to level/trim a rc boat to the proper/desired waterline using two installed ballast tanks, one in stern and on the bow section.
The pump moves water from one syringe to another until it reaches 0 degrees setpoint, using PID.

For this purpose I have create a prototype using the following components:

  1. Peristaltic pump - Kamoer 6V, 5W;
  2. Adafruit DRV8871;
  3. IMU 6050;
  4. Battery 2xLion 18650 3,7V
  5. Arduino UNO R3;
  6. Lego.

Picture here:

This project serves as a base/playground for further development of my RC submarine that will use 2 gear pumps and drives 2 pistons used for both diving and trimming.

Code:

// Include Wire Library for I2C
#include <Wire.h>
#include <PID_v1.h>
#include <MPU6050_tockn.h>

MPU6050 mpu6050(Wire);

//Declare motor direction pins
#define MotorPowerForward 5
#define MotorPowerBackward 6

//declare direction variable for motor function
int dir;

//the angle where the boat is level
double Setpoint = 0;

double Input, Output;


//PID controllers
double Kp = 10;
double Kd = 15;
double Ki = 0;

//instance of class PID
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, REVERSE);


double angle_pitch_output;


void setup() {

  //setting the motors pinmodes
  pinMode(MotorPowerForward, OUTPUT);
  pinMode(MotorPowerBackward, OUTPUT);

 //Starts with motors off
  digitalWrite(MotorPowerForward, LOW);
  digitalWrite(MotorPowerBackward, LOW);

  //setting PID parameters
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(-255, 255);
  myPID.SetSampleTime(20);
  

  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);

  
  // Start Serial Monitor                                                 
  Serial.begin(9600);
  
}

void loop(){
  

 mpu6050.update();
 angle_pitch_output=mpu6050.getAngleX();
  
 Input = angle_pitch_output;
 myPID.Compute();



if (Output > 0) {

      dir = 1;
      setMotor(dir,abs(Output),MotorPowerForward,MotorPowerBackward);
    }
    else if (Output < 0) {
 
      dir = -1;
      setMotor(dir,abs(Output),MotorPowerForward,MotorPowerBackward);
    }


 //Serial.print("Angle:");
 //Serial.println(angle_pitch_output);
 Serial.print("\tPID_Input:");
 Serial.print(Input);
 Serial.print("\tPID_Setpoint:");
 Serial.print(Setpoint);
 Serial.print("\tPID_Output:");
 Serial.print(Output);
 Serial.println();

    
}//void loop

//Function for running the motor/pump
void setMotor(int dir, int pwmVal, int in1, int in2){
  if (pwmVal<128){
    
    pwmVal=127;
    
    }
  if(dir == 1){
      
      analogWrite(in1, pwmVal);
      analogWrite(in2, LOW);
    }
  else {

      analogWrite(in1, LOW);
      analogWrite(in2, pwmVal);
    }
 
}

Symptoms: When reaching the setpoint, the pump never stops and hunts for target position.

Video here: Pump hunting for target position.

It was a challenge to find the kp,kd and ki constants, maybe an autopid library will help but I find it difficult to grasp. Why autopid? The prototype now run in the air but finally it will run in water, different medium all together, I guess the constants will need to be adjusted again.
Please help me improve my code and reach target/setpoint but in the same time stop the pump and save battery. Some say that I need to add deadband to the code but I do not know where and how.

Thank you.

Bogdan

Isn't a PID overkill for this application? Wouldn't a simple bang-bang feedback loop with hysteresis work better? There is almost no inertia in the system, so overshoot is not likely to be unmanageable.

Hi, first of all thank you for ur reply. Please help me with this bang-bang feedback loop, do you have some examples to follow?

A thermostat.

How do you empty a tank using that one pump?

I’d say PID is an over kill too - just switch the pump off when you reach the desired value .
PID. Values need to be tuned to produce stable control . Google this adoect

No need at this point, this is just a trimming project, the pump only moves the ballast and keep the "beam"/boat level to the desired waterline. Please reread the post, I added more info.

Hammy, thank you. I added more info to the post, I need PID because this code will be futher developed for more complex operation: diving a submarine to the periscope depth, trimming which will not be possible without PID.

Got it, i know now what you mean. The truth is that I need PID, this code will be used/ajusted to automatically drive an RC submarine and maybe keep it level at a periscope depth.

Not just adjusted. You will be starting all over, upon moving the control system to a submersible vehicle in water.

The viscosity of the water and mass of the vehicle will dramatically damp and reduce the frequency of oscillations.

When I started like this, I was betting that if working in the air, for sure will perform acceptable in the water.

I would probably not make that bet. The two systems are very different. I say this with some experience (see example autonomous PID navigation, video below).

Please let us know what happens when you build the sub and try it out!

2 Likes

impressive! :+1:

So what is in place to cover normal pitch and roll...??

Yeah, I can see how that would require some careful balancing.

Just as a point of forum order, it's best not to edit posts that have already been commented on. It makes the replies seem out of place.

Hi,
If you want to stop "hunting" around the set point, you will need to introduce some hysteresis.

Have your setpoint tolerance be say -1 degree to +1 degree.
Each time your craft "bobs" around your equaliser would respond, so some time base and hysteresis would be ideal.

Simple bang-bang code would probably be the best.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

This project only reads and controls the pitch.

I will add it to the code and post the results. Thank you.

I would agree that on/off control is the way to go , you can always revive at a later date .
I though the front fins were used to stabilise the depth .

Have you thought about having a weight driven back and forth on a thread to do your trimming - easier to control precisely and avoids it goi g horribly wrong if you have a leak.
Just have a single tank for diving

Hi Hammy, there are two rc submarine operation modes:

  1. Dynamic diving which can make use of the movement to level the boat by using so called pitch controller by controlling the stern dive planes and manually adjust the depth using the bow dive planes.

  2. Static diving meaning that the submarine will dive by increasing the ballast weight stationary. This is indeed harder to achieve because I need to keep it level during the entire operations with pump controller which is what I want to realize with this prototype. This is the desired behavior for mine.