Air or hydraulic cylinder return after limit switch contact

Hi, I need to return a cylinder back to fully retracted position after it extends and triggers a limit switch. The cylinder will be part of a state machine code, so the cylinder will only operate at a certain part of the code. Once it is retracted, it will have to stay in place until it is called again later on. This will be an automatic process, so no user buttons or switches. It will be controlled by an electronic hydraulic solenoid with spring return to extend and retract the rod. Coding the relay to control the solenoid is not a problem, but I cannot use a delay function like "digitalWrite(Relay , High); delay(2000,); digitalWrite(Relay, LOW), because the amount of time to extend the rod might change depending on the object it is moving. I just don't know how to change the state of the relay using the limit switch.

Any ideas ?

Cheers,
TT

void doTheMove(){
  digitalWrite(Relay , HIGH); 
  while( digitalRead( SwitchPin ) != active );
  digitalWrite(Relay, LOW);
}

Yes it is doable. First you need to post all of the code. Post an annotated schematic showing exactly how you wired it, include links on each of the parts. Post a link to the valve or if there are more then one post both links. Is this hydraulic or air, that makes a difference in response. How do you sense that the cylinder retracted?

1 Like

How do you know it is retracted? You mention a limit switch for fully extended but nothing for fully retracted. It would seem you need a second limit switch there as well.

Then, when you detect fully extended, start your retraction motion and monitor it until you detect the fully retracted limit switch and then turn it off.

1 Like

You are using a hydraulic valve to operate a pneumatic cylinder? Describe that valve, post a datasheet.

The solenoid valve has a fluid return line back to the tank (If I go with hydraulic as apposed to an air ram). When the power to the solenoid is turned off the spring moves the spool to the return position and the hydraulic pressure pushes back the ram until the end of it's stroke. Therefor I don't need to monitor the return part. There will be other hydraulic functions going on while this ram is waiting for it's next travel. When I energize the solenoid again the ram will extend. So I need the limit switch to let the program know that it has been triggered. The part I am not sure about is that when the ram starts to retract, the limit switch will become untriggered, and how will that affect the program ? Or what statement(s) are required to reset things for the next extension process, that will happen in approx 40 seconds. I see kolaha has written a small program to do this. (Thank you kolaha) I will give it a try and see what happens.

Only if you keep the oil filter clean!

I am building a small proof of concept model version of the machine in question. I am presently using 12 volt linear actuators to represent the hydraulic rams, and using delay functions to simulate the moves. This is the code that I am using to operate this particular ram. This portion of code is part of a larger state machine coded compilation.
But like I mentioned, I cannot use "Delays" in the real life machine.

 
      if (expired(1000)) {
        newState(RELAY1HIGH); 
      }
      break;
    case RELAY1HIGH:  
      if (isFirst()) {
        Serial.println("RELAY1HIGH");  
        digitalWrite (Relay1, HIGH);
        
      }
      
      if (expired(1900)) {
        newState(RELAY1LOW);  
      }
      break;
    case RELAY1LOW:  
      if (isFirst()) {
        Serial.println("RELAY1LOW");
        digitalWrite(Relay1, LOW); 
         
      }
      

By the time you are done, you will see why you need to know when the ram has retracted!

What will happen?

Logic problems will be made so much simpler when your program actually knows it can begin a new cycle.

Oh, OK thanks for the reply.

I think you just need to understand some basic programming logic -

if
And
Or

And maybe while() loops or other conditional loops & conditional logic.

Your program has to know what it's doing, and not simply re-trigger whenever you're not at the limit. It should only "trigger" when it's supposed to trigger.

...The two most important and useful concepts in programming are conditional execution and loops, usually conditional looping.

Consider how many million times your code will be executed before the ram returns to the beginning position.

What you need is a finite state machine, consisting of at least these states:

  • ram extending
  • ram touching limit switch
  • ram retracting
  • ram idle

Something like this:

enum RamState {
  EXTENDING,
  LIMIT,
  RETRACTING,
  IDLE} ramState;

void setup() {
  ramState = IDLE; // Assuming it's actually retracted - which without sensor we don't know
}

void loop() {
  if (digitalRead(limitSwitch) == LOW &&
    ramState != RETRACTING) { // switch touched
    ramState = LIMIT;
  }

  switch (ramState) {
    case IDLE:
      if (commandToExtend) {
        ramState = EXTENDING;
      }
    break;

    case EXTENDING: 
       // switch relay to extending
     break;
 

    case LIMIT:
      ramState = RETRACTING
      break;

    case RETRACTING:
      // switch relay to retracting.
      if (retracted) {
        ramState = IDLE;
      }
    break;
  }
}

You will really need a sensor to see whether your piston has retracted - not just to see whether your retracting phase has completed, but also to know when you start up whether you're actually retracted or not.

Thanks everyone for your help with this. It is greatly appreciated. :+1:

Contrary to other posts, do you need to know when the ram if fully retracted? What happens if you start the next cycle when the ram is only partially retracted? Is that bad/harmful to your system? At the very least, you could record the time when you started the retraction and not start the next cycle for at least X amount of time.

All in all, I'd still vote for another limit switch.

Agreed 100 percent. Timing is not possible because the oil heats and becomes MORE fluid and the cylinder seals slide easier.

I believe the state machine program needs to know when the ram is retracted, so that it can proceed to the next state. After the first ram retracts, the object it moved will be in another place where another ram will do it's job. Once that job is complete, the conveyor will start up, and bring another object to where the first ram will do it's job. The state machine starts with the conveyor action, then the first ram, then the second ram, and then the conveyor starts again, for the conveyor to bring the next item forward. If the first ram doesn't retract all the way, it will be in the way of the approaching object.
This is a multiple state "State Machine". Each separate action from first to last must work one after the other, for it to work properly.

Once I figure out the ram issue, I then need to figure out how to measure different heights of various objects, which shouldn't be too hard.

Then you definitely need another sensor in your system.