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.
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?
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.
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.
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);
}
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.
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.
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.
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.