Hii
I'm working on my final project for high school and my theme is model railway with locomotive on remote control.
I found this code somewhere on the internet and it works for 1 level crossing but I have 2 crossings.
I have 2 sensors which can output both digital and analog signals, I'm using digital ones.
The shape of tracks you can see on image 1.
Sensors are 1 and 2, level crossings are 3 and 4.
I'm going to control 1 level crossing with arduino uno and second one with dasduino core.
Issue I'm having is I can't take 2 outputs from 1 sensor so I was thinking of using some 2 pins on arduino as output but as input on dasduino.
It should work like this
Sensor 1 detects a locomotive, LEDs start to blink (2 LEDs), after 2/3 seconds servo motors close the gate and wait until sensor 2 detects that locomotive has passed that level crossing then servo motors open the gate, and LEDs stop blinking after servo motors have opened the gate. This code does all that. If I stop locomotive just after sensor 2 so level crossing 4 is active (LEDs blinking, servos closing the gate), and if I go backwards with locomotive the code should check are leds blinking or servos closing or have closed the gate on level crossing 4 and if it is true it should start procedure to open the gate and stop blinking when gate is open on level crossing 4, but it should check are LEDs blinking or servos closing/have closed the gate (they shouldn't blink, the gate should be open) but if sensor 2 detects a locomotive is going backwards then it should activate procedure to close the level crossing 1 if locomotive goes all the way through that level crossing 1 in reverse then sensor 1 detects locomotive has passed that crossing it should open the gate and stop blinking.
When sensor 2 detects a train LEDs start to blink on level crossing 4, after 2/3 seconds servos close the gate and its closed until sensor 1 detects that locomotive has passed that level crossing when servos open the gate and LEDs stop blinking.
And it should be able to go over and over but in both direction as I have explained for level crossing 1 because locomotive will be able to go backwards.
I hope you will be able to understand me, and I apologize for any language mistakes I might have made.
#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 6
#define SERVO2_PIN 7
#define LED1_PIN 10
#define LED2_PIN 11
#define LED3_PIN 12
#define LED4_PIN 13
#define SENSOR1_PIN 3
#define SENSOR2_PIN 4
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);
}