PID control of dual acting cylinder

Hello and Thank you for reading this. I am making a very cool project using a pneumatic dual acting cylinder to rock a flight simulator. I am trying to adapt the “basic” PID program to control a dual acting air cylinder. Unfortunately the example is written to control a PWM motor. Our air cylinder extends or retracts at various speeds. Two relays and valves control the proper direction. A third proportional valve feeds air at various pressures through the correct direction relay/valve when needed.

My problem right now is my cylinder only has Output when input<setpoint (the cylinder retracts). When Input>Setpoint there is no Output(the cylinder does not extend). Could someone offer a few pearls of wisdom for me??

#include <PID_v1.h>

 * PID Basic Example
 * Reading analog input 0 to control analog PWM output 3

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

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,1,5,1, DIRECT);//0 -10????  middle one adj. from .5 to 10....  (Kp,Ki,Kd,)

void setup()
 pinMode(2,OUTPUT);//  relay RETRACT
 pinMode(3,OUTPUT);//  relay EXTEND 

  //initialize the variables we're linked to

  //turn the PID on

void loop()
 double RawInput = analogRead(A0);    //read the position potentiometer on air cylinder
 double RawSetpoint = analogRead(A2); //read the joystick potentiometer
Input=map(RawInput,0,1024,0,255);     //needed to change raw variables to a range the PID program accepts

myPID.Compute(); //starts the PID program

analogWrite(6,Output);//write to pin 6 where a solenoid varies air pressure from off (0) to full pressure (255)

if(Input<Setpoint){digitalWrite(2,LOW);digitalWrite(3,HIGH);}   //turn on relay 2 that retracts double acting cylinder
if(Input>Setpoint){digitalWrite(2,HIGH);digitalWrite(3,LOW);}   //turn on relay 3 that extends the double acting cylinder
//analogWrite(3,Output); this is the original command to control a PWM electric motor

The Output of your PID will vary from a "fully retract" to a "fully expand" value, with a neutral "stay" value in between. You'll have to split that single value into the direction info "retract" or "expand", and a gradual info between "stay" and "fully".

In the easy case, where "stay" is zero, the absolute value of Output will be the gradual info for the PWM signal, and the sign of Output will indicate retract or expand.

If "stay" is not zero, subtract that constant value from Output, to convert it into the easy case.

To make a PID controller you need to know where the cylinder is at every point. Can you fit eg a potentiometer to give this information?



To make a PID controller you need to know where the cylinder is at every point. Can you fit eg a potentiometer to give this information?



PID does require feedback of the process, not really the device being controlled.
there are lots of examples of balancing a ball on a bar. start there.
a potentiometer, a range finder, an encoder. depends if you want to measure the rotary angle of some point, or the distance from some point, or even use level and angles.

your flight simulator setpoint will be the desired angle for banks and turns.
not sure how you will handle turbulance, but once you have the simple things figured and working, the rest should just be tweeking.

Thank you guys your awesome. I will digest the info and gives me a direction to go. The cylinders are controlled by joysticks and pots on the cylinders FYI.

I dont quite understand Dr.D’s suggestion. I get varying output 0-255 when joysticks pot > cylinder pot but zero output when cylinder pot<joystick pot. Shouldn’t the output go negative when pot<joystick??? Its not really a control loop if it can’t follow in both directions. Isn’t the error in the library itself??? I am not sure what to change.

Thank you. Please come back later and track my feeble progress!!!

Map the raw analog value from 0,1024 into the desired range, e.g. -255,255 or whatever applies to your cylinder. The same for the setpoint.

You may need SetOutputLimits() to the full output ränge, i.e. -255,255. See the PID tutorial page for configuration.

sweet. thank you Doc!!! :)

RawInput=analog Read (A0); Setpoint=0; Input=map (RawInput,0,1024,-255,255); myPID.compute (); Serial.print (Output);

Does this look right????

Ok the above code does not work as suggested:

Whenever my Setpoint is greater than the Input the Output is always zero. Is this always true with PID programs?????

I don't know how to get any Output when the Input is greater than the Setpoint.

See reply #5