Railway level crossing lights and boom gates

I am trying to adapt this code;
Example Level Crossing Control
// Version 1 John Cornell 2015.
I am trying to adapt this code to my circumstance. I have one track. light sensor at one end and another at the other end. When Right sensor is activated it starts the level crossing sequence, Bell starts/lights flash/boom gate goes down. Once the boom gate is down the lights and bell should continue until Left sensor is activated (train has left crossing) or train has been in crossing and reversed out back over R sensor (Boom gates go up, lights stop and bell stops.)
John has just used one sensor which is limiting. The code works with lights going and the servo (boom gate) moving smoothy to position with lights maintaining the flashing however the problem I have been trying to work out is that the servo moves to the down position but then goes straight back up even when the sensor is covered. (Just like in the sweep example) I need to keep the servo at (pos 30) until it is required to return to pos 120. Here is the code that is within the starting sequence function.

void starting_sequence() {
 long wait_time;
// flash_time = millis(); was this wrong?
 wait_time = millis()+3000; 
 while (wait_time > millis()) flash_leds(); //flash before dropping gates
 for(gateposition = 120; gateposition>30; gateposition-=1) // goes from 120 degrees to 30 degrees
 { 
 gate1servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition'
 gate2servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition'
 flash_leds(); // keep flashing leds
 delay(40); // waits 40ms to slow servo
 }
}

Here is the full code I am working with.

// Example Level Crossing Control
// Version 1 John Cornell 2015
// Uses software servo Library
//
  
#include <Servo.h>
  
Servo gate1servo; // create servo object to control crossing gate 1
 //ASSUMPTION Gate is down at position 30 and up at position 120
Servo gate2servo; // create servo object to control crossing gate 2
 //ASSUMPTION Gate is down at position 30 and up at position 120
int sensor1 = A0;; // IR sensor pin Assumption== Pin goes LOW when train detected
 
int led1 = 33; // Led 1 pin first alternating flasher
int led2 = 35; // Led 2 pin first alternating flasher
int led3 = 12; // Led 3 pin second alternating flasher
int led4 = 13; // Led 4 pin second alternating flasher
int gateposition = 120; // variable to store the servo gateposition
 
 
int gates_started = 0; // this says if the crossing is active
int flash_state = 0;
long flash_time = 0;
long flash_interval = 900; // time in milliseconds between alternating flashes
 
  
void setup()
{
 gate1servo.attach(3); // attaches the servo on pin 3 to the servo object
 gate2servo.attach(4); // attaches the servo on pin 4 to the servo object
 gate1servo.write(gateposition); //start assuming no train
 gate2servo.write(gateposition); //start assuming no train
 //pinMode(sensor1, INPUT); 
 
 pinMode(led1, OUTPUT);
 pinMode(led2, OUTPUT); 
 pinMode(led3, OUTPUT);
 pinMode(led4, OUTPUT);
 digitalWrite(led1, LOW); // Start with all flashers off
 digitalWrite(led2, LOW);
 digitalWrite(led3, LOW);
 digitalWrite(led4, LOW); 
 flash_time = millis(); // time since sketch started
}
  
void loop()
{
 if ((analogRead (sensor1) < 100)&& (gates_started==0)) {
 gates_started = 1;
 starting_sequence();
 }
 if (gates_started) flash_leds(); //gates are down continue flashing
 if ((analogRead(sensor1)>100)&&(gates_started==1)) { //Train has left
 ending_sequence();
 }
}
  
void starting_sequence() {
 long wait_time;
// flash_time = millis(); was this wrong?
 wait_time = millis()+3000; 
 while (wait_time > millis()) flash_leds(); //flash before dropping gates
 for(gateposition = 120; gateposition>30; gateposition-=1) // goes from 120 degrees to 30 degrees
 { 
 gate1servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition'
 gate2servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition'
 flash_leds(); // keep flashing leds
 delay(40); // waits 40ms to slow servo
 }
}
  
void ending_sequence() {
 for(gateposition = 30; gateposition<120; gateposition++) // goes from 30 degrees to 120 degrees
 { 
 gate1servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition'
 gate2servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition'
 flash_leds(); // keep flashing leds
 delay(40); // waits 40ms to slow servo
 }
 gates_started = 0; // gates are open
 digitalWrite(led1, LOW); // flashers completely off
 digitalWrite(led3, LOW);
 digitalWrite(led2, LOW);
 digitalWrite(led4, LOW);
}
  
void flash_leds() {
 if (flash_time > millis()) return;
 flash_state = ~flash_state;
 digitalWrite(led1, flash_state); // Alternate flashers
 digitalWrite(led3, flash_state);
 digitalWrite(led2, ~flash_state);
 digitalWrite(led4, ~flash_state);
 flash_time = millis()+flash_interval;
}

What condition(s) causes that? I want to be sure.

A schematic would be welcome.

Are your sensors looking diagonally across the track so they can't see the gap between cars?

Blockquote

What condition(s) causes that? I want to be sure.

Blockquote
At the moment I am using a mega attached to a bread board for testing. When the light sensor goes low <100 (I place my hand over it). The code jumps to void starting_sequence() { long wait_time; // flash_time = millis(); was this wrong? wait_time = millis()+3000; while (wait_time > millis()) flash_leds(); //flash before dropping gates for(gateposition = 120; gateposition>30; gateposition-=1) // goes from 120 degrees to 30 degrees { gate1servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition' gate2servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition' flash_leds(); // keep flashing leds delay(40); // waits 40ms to slow servo } }
As long as my hands stays over the sensor the code runs expected except of course that the servo sweeps back and forth. The servo moves to its end position then as the loop starts again the code sends it back to the start position. If I remove my hand the (sensor >100) the code jumps to void ending_sequence() { for(gateposition = 30; gateposition<120; gateposition++) // goes from 30 degrees to 120 degrees { gate1servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition' gate2servo.write(gateposition); // tell servo to go to gateposition in variable 'gateposition' flash_leds(); // keep flashing leds delay(40); // waits 40ms to slow servo } gates_started = 0; // gates are open digitalWrite(led1, LOW); // flashers completely off digitalWrite(led3, LOW); digitalWrite(led2, LOW); digitalWrite(led4, LOW); }

Good point! At the moment the sensor is in a bread board and I am holding my hand over it to represent the locomotive and carriages. I can see how the gap between the carriages would sent the sensor low to high per carriage crossing sending the code back and forth to quickly for anything to happen! The sensor will be under the track facing up to the lighting. I need some way for the program to stop reading the sensor after it has been activated but then if the train reverses back over it the program will not recognize it! Some logic definitely need!

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