/*
Solenoid cycle
activate output relay 1
Delay 500ms
Activate output relay 2
Delay 500ms
Activate output relay 3
Delay 1500ms
Deactivate output relay 3
Delay 2500ms
Deactivate output relay 2
The circuit:
pushbutton attached to the pin 2 and to the ground
solenoid #1 attached to pin 4
solenoid #2 attached to pin 5
solenoid #3 attached to pin 6
2022-12-06 https://forum.arduino.cc/t/activate-relays-in-sequence/1061969
older Version:
https://forum.arduino.cc/t/anyone-know-of-a-good-youtube-tutorial-on-how-to-make-a-code-repeat/1027637/3
*/
// constants won't change.
//const uint16_t solenoid_1_OffDelay = 0; not used
const uint16_t solenoid_2_OnDelay = 500;
const uint16_t solenoid_2_OffDelay = 2500;
const uint16_t solenoid_3_OnDelay = 500;
const uint16_t solenoid_3_OffDelay = 1500;
// set pin numbers:
const uint8_t buttonPin = 2; // the number of the pushbutton pin
const uint8_t solenoid1Pin = 4; // solenoid 1 pin
const uint8_t solenoid2Pin = 5; // solenoid 2 pin
const uint8_t solenoid3Pin = 6; // solenoid 3 pin
const uint8_t debounceDelay = 50; // the debounce time for switch; increase if the output flickers
uint8_t state = 0; // a global state for the state machine
uint32_t previousMillis = 0; // time management for the state machine
void start(uint32_t currentMillis = millis())
{
digitalWrite(solenoid1Pin, HIGH);
previousMillis = currentMillis;
state = 1;
}
void stop()
{
digitalWrite(solenoid1Pin, LOW);
digitalWrite(solenoid2Pin, LOW);
digitalWrite(solenoid3Pin, LOW);
state = 0;
}
void runFSM(uint32_t currentMillis = millis())
{
switch (state)
{
case 0 :
// idle - do nothing
break;
case 1:
if (currentMillis - previousMillis > solenoid_2_OnDelay)
{
previousMillis = currentMillis;
digitalWrite(solenoid2Pin, HIGH);
state++;
}
break;
case 2:
if (currentMillis - previousMillis > solenoid_3_OnDelay)
{
previousMillis = currentMillis;
digitalWrite(solenoid3Pin, HIGH);
state++;
}
break;
case 3:
if (currentMillis - previousMillis > solenoid_3_OffDelay)
{
previousMillis = currentMillis;
digitalWrite(solenoid3Pin, LOW);
state++;
}
break;
case 4:
if (currentMillis - previousMillis > solenoid_2_OffDelay)
{
previousMillis = currentMillis;
digitalWrite(solenoid2Pin, LOW);
state++;
}
break;
case 5:
// do nothing, just wait for switch off
break;
}
}
void readSwitch(uint32_t currentMillis = millis())
{
static uint32_t previousMillis = 0;
if (currentMillis - previousMillis > debounceDelay)
{
previousMillis = currentMillis;
if (state > 0 && digitalRead(buttonPin) == HIGH)
{
stop(); // switch is released, stop FSM
}
else if (state == 0 && digitalRead(buttonPin) == LOW )
{
start(); // switch is pressed, start FSM
}
}
}
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(solenoid1Pin, OUTPUT);
pinMode(solenoid2Pin, OUTPUT);
pinMode(solenoid3Pin, OUTPUT);
// set initial outputs state
digitalWrite(solenoid1Pin, LOW);
digitalWrite(solenoid2Pin, LOW);
digitalWrite(solenoid3Pin, LOW);
}
void loop() {
uint32_t currentMillis = millis();
readSwitch(currentMillis);
runFSM(currentMillis);
}