Hi
Here is the code that worked for me.
#define GATE_SPEED 70 // [ms] lower number is higher servo speed
#define GATE_DELAY 3000 // [ms] delay time before gate closes
#define GATE_OPEN 0 // servo angle
#define GATE_CLOSED 90 // servo angle
#define BLINK_SPEED 500 // [ms] smaller number is faster blinking
#define SERVO1_PIN 7
#define SERVO2_PIN 8
#define LED1_PIN 2
#define LED2_PIN 3
#define LED3_PIN 4
#define LED4_PIN 6
#define SENSOR1_PIN 9
#define SENSOR2_PIN 10
byte state = 1, transition;
byte led1, led2, led3, led4, blink_enabled;
byte angle = GATE_OPEN;
byte setpoint = GATE_OPEN;
unsigned long time_to_blink;
unsigned long time_to_close_gate;
unsigned long time_for_servo;
#include <Servo.h>
Servo gate_servo1, gate_servo2;
void setup() {
pinMode(SENSOR1_PIN, INPUT_PULLUP);
pinMode(SENSOR2_PIN, INPUT_PULLUP);
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(LED3_PIN, OUTPUT);
pinMode(LED4_PIN, OUTPUT);
gate_servo1.attach(SERVO1_PIN);
gate_servo2.attach(SERVO2_PIN);
gate_servo1.write(angle);
gate_servo2.write(angle);
Serial.begin(9600);
Serial.println("Railway Crossing Control Ready");
Serial.println();
Serial.println("Waiting for train");
}
void loop() {
switch(state) {
case 1: // idle
if(digitalRead(SENSOR1_PIN) == LOW) transition = 12;
break;
case 2: // blinking, gate still open
if (millis() > time_to_close_gate) transition = 23;
break;
case 3: // blinking, gate closing
if(digitalRead(SENSOR2_PIN) == LOW) transition = 34;
break;
case 4: // blinking, gate opening
if(angle == GATE_OPEN) transition = 41;
break;
}
switch(transition) {
case 12: //
Serial.println("Train detected, start blinking");
blink_enabled = 1;
time_to_close_gate = millis() + (unsigned long)GATE_DELAY;
transition = 0;
state = 2;
break;
case 23: //
Serial.println("Time to close the gate");
gate_servo1.attach(SERVO1_PIN);
gate_servo2.attach(SERVO2_PIN);
setpoint = GATE_CLOSED;
transition = 0;
state = 3;
break;
case 34:
Serial.println("Train detected, open the gate");
gate_servo1.attach(SERVO1_PIN);
gate_servo2.attach(SERVO2_PIN);
setpoint = GATE_OPEN;
transition = 0;
state = 4;
break;
case 41:
Serial.println("Gate is open, stop blinking");
Serial.println();
Serial.println("Waiting for train");
blink_enabled = 0;
led1 = 0;
led2 = 0;
led3 = 0;
led4 = 0;
gate_servo1.detach(); // to avoid servo flutter
gate_servo2.detach();
transition = 0;
state = 1;
break;
}
if (millis() > time_for_servo) {
time_for_servo = millis() + (unsigned long)GATE_SPEED;
if (angle < setpoint) angle++;
if (angle > setpoint) angle--;
gate_servo1.write(angle);
gate_servo2.write(angle);
}
if(blink_enabled == 1) {
if(millis() > time_to_blink) {
time_to_blink = millis() + (unsigned long)BLINK_SPEED;
led1 = !led1;
led2 = !led1;
led3 = !led3;
led4 = !led3;
}
}
digitalWrite(LED1_PIN, led1);
digitalWrite(LED2_PIN, led2);
digitalWrite(LED3_PIN, led3);
digitalWrite(LED4_PIN, led4);
}