Pneumatic Cylinder position Control. Need feedback on my Structured Text code

nearxos

Member
Join Date
Aug 2020
Location
Cyprus
Posts
13
I am looking for different solution on controlling a pneumatic Cylinder move at preset positions.

One of the solutions is to use 5 magnetic switches on the cylinder for close , 1/4 , 1/2, 3/4, 4/4 positions

I did write the code in structure text and it's working at list on codesys simulation.

Since I am fairly new to the PLC word I would like some feedback on what I have done.

If anybody is willing to have a look and comment i can share the code
 
I wasn't sure if I could post the code in here.

See bellow the code I 've written

Code:
// GOT TO 0% POSITION

IF BTN.HMI_0 OR BTN.Main_0 OR BTN.Operator_0 THEN
	index := 1;
	
 	IF position_25 OR position_50 OR position_75 OR position_100 THEN
		Valve_A := TRUE;
		Valve_B := FALSE; 
		ELSE
		Valve_A := FALSE;
		Valve_B := FALSE; 	
		END_IF
END_IF

// GOT TO 25% POSITION

IF BTN.HMI_25 OR BTN.Main_25 OR BTN.Operator_25 THEN
	index :=2;
 	IF position_50 OR position_75 OR position_100 THEN
		Valve_A := TRUE;
		Valve_B := FALSE; 
	ELSIF position_0 THEN
			Valve_A := FALSE;
			Valve_B := TRUE; 	
 	END_IF
END_IF

// GOT TO 50% POSITION

IF BTN.HMI_50 OR BTN.Main_50 OR BTN.Operator_50 THEN
	index :=3;
	
 	IF position_75 OR position_100  THEN
		Valve_A := TRUE;
		Valve_B := FALSE; 
	ELSIF position_0 OR position_25 THEN
			Valve_A := FALSE;
			Valve_B := TRUE; 	
 	END_IF
END_IF

// GOT TO 75% POSITION

IF BTN.HMI_75 OR BTN.Main_75 OR BTN.Operator_75 THEN
	index := 4;
 	IF position_100   THEN
		Valve_A := TRUE;
		Valve_B := FALSE; 
	ELSIF position_0 OR position_25 OR position_75 THEN
			Valve_A := FALSE;
			Valve_B := TRUE; 	
 	END_IF
END_IF


// GOT TO 100% POSITION

IF BTN.HMI_100 OR BTN.Main_100 OR BTN.Operator_100 THEN
	index := 5;
 	IF  position_0 OR position_25 OR position_50 OR position_75  THEN
		Valve_A := FALSE;
		Valve_B := TRUE; 
		ELSE
		Valve_A := FALSE;
		Valve_B := FALSE; 	
		END_IF
END_IF

// index position to stop Cylinder

IF (index =1 AND position_0) OR
 (index = 2 AND position_25) OR 
(index = 3 AND position_50) OR 
(index =4 AND position_75) OR
(index= 5 AND position_100)  THEN
		Valve_A := FALSE;
		Valve_B := FALSE; 
END_IF
 
Last edited:
I can see the idea behind the code.

Not knowing how the switches function mechanically, I have to wonder what happens if none of the switches are actuated when a button is pressed? It doesn’t seem like there will be any motion. Likewise, If the cylinder is between switches how will you know which way to go when a button is pressed?

Is this a real system or just for simulation? I would want a linear transducer for a real system. This way you would know where the cylinder is at all times.

Using directional valves to stop a cylinder you can only get very coarse position accuracy. Do you have a requirement for position accuracy or repeatability?
 
I can see the idea behind the code.

Not knowing how the switches function mechanically, I have to wonder what happens if none of the switches are actuated when a button is pressed? It doesn’t seem like there will be any motion. Likewise, If the cylinder is between switches how will you know which way to go when a button is pressed?

Is this a real system or just for simulation? I would want a linear transducer for a real system. This way you would know where the cylinder is at all times.

Using directional valves to stop a cylinder you can only get very coarse position accuracy. Do you have a requirement for position accuracy or repeatability?

The switches we are gonna use are magnet switches

It will be a real system.
you got a point there. if the Cylinder is between positions. i guess i could solved that by storing the previous position and using that to know where to go next.

if not a switch is activated in a given time i will get an alarm. i haven't include that part in the code above.
 
If you have five sensors i.e. 0,25,50,75,100 Then just mask move the sensor status i.e. 00100 (50%) into a word and depending on the button pressed mask move the equivalent of the buttons into another word and do two compares.
so for example if the cylinder was at 50% (4 in the mask) and the button 0 (1) in the button word was pressed then it is less, so moves cylinder back until the masked sensor word equals the button pressed
So
Current position = 1 (0%) button pressed = 3 50% (4) then it energises the forward solenoid until the current position = the required position.
Just for clarity if you copy the sensor positions into a word variable then it will = 1, 2, 4, 8, 16 If you copy the buttons into the required word it would = 1,2,4,8,16. You do two compares so if button pressed > actual position then it sets the FWD Sol, if < It sets the REV Sol.
When the two equal reset both solenoids.
One other thing you would need to check for no sensors made in that situation probably alarm.
 
I don't know if OP has ELSIF or not, and I like @parky's bit-wise idea better because if you can easily tie the proxes and buttons to the bits of INTs then the code reduces to about half a dozen lines, but this is a hamfisted implementation based on @parky's idea:

Code:
VAR
  index  : INT =  101;  (* Last-measured position *)
  target : INT =    0;  (* Last-commanded position *)
END_VAR

   IF BTN.HMI_0   OR BTN.Main_0   OR BTN.Operator_0   THEN target := 0;
ELSIF BTN.HMI_25  OR BTN.Main_25  OR BTN.Operator_25  THEN target := 25;
ELSIF BTN.HMI_50  OR BTN.Main_50  OR BTN.Operator_50  THEN target := 50;
ELSIF BTN.HMI_75  OR BTN.Main_75  OR BTN.Operator_75  THEN target := 75;
ELSIF BTN.HMI_100 OR BTN.Main_100 OR BTN.Operator_100 THEN target := 100;
END_IF;

   IF position_0   THEN index := 0;
ELSIF position_25  THEN index := 25;
ELSIF position_50  THEN index := 50;
ELSIF position_75  THEN index := 75;
ELSIF position_100 THEN index := 100;
ELSIF LO_HARD_STOP THEN index := -1;
ELSIF HI_HARD_STOP THEN index := 101;
END_IF;

VALVE_A := index < target;
VALVE_B := index > target;
Caveats

  • syntax errors are OP's problem ;)
  • this handles the case when the cylinder is between position sensors
  • on startup the cylinder should home to position 0 unless interrupted by a button press
    • if the cylinder is between sensors then it will be commanded to move backward until either a position or hard stop is detected
  • assumes the position sensors are wide (long in duration) with respect to the speed of the cylinder.
  • assumes there are hard stops
    • hard stop tests should probably go before position tests
    • they are infinitely wide in their respective directions i.e. the cylinder can never go past a hard stop detection
    • hard stop are not needed if positions sensors 0 and 100 meet these criteria
  • using those ELSIFs means the first coded test to match will override later tests e.g. BTN.HMI_0 will override BTN.Operator_25
    • HMI bits should be set-and-forget:
      • the HMI assigns a 1
      • the PLC assigns a 0 whenever the 1 is detected
 
Last edited:
I don't see how this is going to work.

LOL you don't need to say that. Your signature is adequate by itself ;)


Anyway, neither do I; I was only trying to post a cleaner version of the OP's approach that also handled the in-between case. I figure the process issues will become apparent once the code is clear.
 
Here is one but no error checking i.e. if a sensor fails or is not on one it still tries to go to a position, you could check that the sensor word is >< 0 i.e. a sensor is on or not. to disable the solenoids & alarm.

ST Position.png
 
Anyway, neither do I
So why waste the time?
Norm is right about having a linear transducer.


The concept if flawed! When a valve closes the piston will not stop until the pressure equalizes so the force on the other side of the piston can slow the piston down. There must be a net negative force to decelerate. So how far will the piston move after the valve is off.



BTW, this is how you do it.
https://deltamotion.com/peter/Videos/PneuMove2.mp4
I don't like pneumatic systems because dirty air fouls the cylinders and makes them sticky so they become hard to control. We test with pneumatics because it is difficult and if you can control pneumatics then you can control hydraulics easily.


There are too many times when the OP will ask how to do the wrong thing. That is why I always like to know what the application is and what they are trying to achieve.
In motion control I always want to know the mass, distance and time of motion as a minimum and we don't know anything.
 
The only system I ever saw to position a pneumatic cylinder with discrete inputs for feedback that worked somewhat well used an air operated rod lock (brake) on the cylinder rod end to hold it in position when not at the end of travel.

I have seen an attempt to do it without a rod lock and using a cylinder with double rods, which in theory, gives equal area on both ends, but in reality, with wear and even the tiniest leakage or external force applied to it, it was not very reliable either. Use a servo controller like Peter recommends or a rod lock cylinder.
 

Similar Topics

Hey everyone i know this is somewhat unrelated to PLC discussion but I couldnt find anything online to answer my question. My cylinders are...
Replies
19
Views
5,639
I need to ramp up the psi on a pnuematic cylinder until the force on the piston, measured by a load cell, is met. Then I need the air pressure to...
Replies
9
Views
4,551
Hello All, I am no expert in valves, Cylinders, or any sort of Pneumatic controls, and in need of some help as to type of control valve that is...
Replies
9
Views
4,921
Hello All, I have a pneumatics question for the group; I need the behavior of a single-acting cylinder with spring return, but I need more force...
Replies
27
Views
8,972
There seems to be plenty of different manufacturers of pneumatic cylinders with 4-20mA position indication. I need one with 2" bore, 24" stroke...
Replies
3
Views
3,554
Back
Top Bottom