Programming arduino to control railroad level crossing

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);
}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.