Quick question for the experts

I am building a G scale railroad crossing signal with gates. I have all the wiring, coding, signals, leds... and EVERYTHING ready to go and working fine. Except one thing.... I need to have the led light on the end of the crossing gates to stay solid while all the others blink.

I am still new to this coding thing... I think there is a simple answer but cannot figure it out. I am using an UNO R3 and a bread board.

Here is the coding I have. It all works perfectly... Just was wondering if there is an adjustment I can make to the code? I have a few other pins available on the UNO.

// Example Level Crossing Control Driving Common Cathode LEDs
// Version 1.4  Geoff Bunza 2018
//
#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 = 5;   // IR sensor pin Assumption== Pin goes LOW when train detected
int sensor2 = 6;   // IR sensor pin Assumption== Pin goes LOW when train detected
int led1 = 10;      // Led 1 pin first alternating flasher
int led2 = 11;      // 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 gatelow = 15;        // variable to store the servo low gate stop position
int gatehigh = 110;    // variable to store the servo high gate stop position
int gateposition = 110;    // variable to store the servo gateposition
int entering_sensor = 5;       //this will tell which sensor was triggered first
int leaving_sensor = 6;        // this will tell which sensor shows train leaving
int gates_started = 0;         // this says if the crossing is active
int flash_state = 0;
long flash_time = 0;
long  flash_interval = 700;    // time in milliseconds between alternating flashes
int sensor_count = 0;
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(sensor2, 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();
}
void loop()
{
  if ((digitalRead (sensor1)==LOW)&& (gates_started==0)) {
    gates_started = 1;
    leaving_sensor = sensor2;
    starting_sequence();
  }
  if ((digitalRead (sensor2)==LOW)&& (gates_started==0)) {
    gates_started = 1;
    leaving_sensor = sensor1;
    starting_sequence();
  }
  if (gates_started) flash_leds();   //gates are down continue flashing
  if ((digitalRead(leaving_sensor)==LOW)&&(gates_started==1)) {   //train is starting to leave
   
  //as long as the leaving sensor is active the train is still in the crossing
  while (gates_started==1)  {   //now check if train is REALLY gone
    sensor_count = 0;
    for (int i=1; i< 40; i++)  {
      if (digitalRead(leaving_sensor)==LOW) sensor_count++;
          delay (40);
                  flash_leds();
                  }
    if (sensor_count==0) gates_started=0;
    flash_leds();
    }
    // we only get here if the train has really left the crossing
                ending_sequence();
  }
}
void starting_sequence()  {
  long wait_time;
  flash_time = millis();
  wait_time = millis()+3000;
  while (wait_time> millis())  flash_leds();  //flash before dropping gates
  for(gateposition = gatehigh; gateposition> gatelow; gateposition-=1)  // goes from gatehigh degrees to gatelow 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(80);                       // waits 40ms to slow servo
  }
}
void ending_sequence()  {
    for(gateposition = gatelow; gateposition< gatehigh; gateposition++)   // goes from gatelow degrees to gatehigh 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(80);                       // waits 40ms to slow servo
  }
  digitalWrite(led1, LOW);  //  flashers completely off
  digitalWrite(led3, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led4, LOW); 
  delay(10000);             // 30 second delay to account for the train passing the starting entry sensor
}
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;
}

Any help would be greatly appreciated. Thank you for all answers in advance, Daniel Edwards

Post your code correctly so it can be read

Take a few minutes to read the forum rules

Please edit your post, select all code and click the <CODE/> button; next save your post.

This will apply code tags which make the code easier to read and copy and the forum software will display it correctly.

Which LED in your code will that be?

Format your code.

Post a picture to see how we can help.

p.s.

I took a quick look at the sketch.

I noticed that the sketch uses delay() and while() functions that block the expected real-time processing of the sketch.

My tip:

Make a redesign of the programme and use objects with appropriate services for the servos and LEDs. This makes programming and maintaining the sketch much easier.

Have a nice day and enjoy coding in C++.

which LED is the one at the end of the crossing?

shouldn't it always be turned ON in flash_leds() and OFF otherwise

Yes there is :slight_smile:

Declare a new variable and give it the right pin number

int led_gate_end  = 99;            // Led at the end of the gate

In setup(), add

pinMode (led_gate_end , OUTPUT);

In starting_sequence, add

 digitalWrite(led_gate_end, HIGH);

at the point you want the LED to turn on. I guess before the flashing lights?

and in ending_sequence, add

 digitalWrite(led_gate_end, LOW);

Thank you for letting me know. Sorry about that/

Thank you so much!!!

Yes, the LED at the end of the crossing gate should be on only while the others are flashing. It should stop at the same time the others stop and go off.

yes.
which LED? which pin #?

I plugged the wire into pin 7 if that helps

  • where do you define a variable for pin 7?
  • where do you try to turn that pin ON?

give me one sec and I will get the information for you. Thank you so much for helping....

int led_gate_end = 7; is what I am trying to use to define the veriable. I would like the light to come on and stay on only when the other lights are flashing.

Instead of an internet search: what's the difference between G and H0 ?

yes. understood

where is this in your code?
please post code showing this

G scale is 1/29th scale, HO is 1/87th scale. G scale is the largest model railroad scale, Most larger G scale locomotives weigh about 17 pounds or more. They are much larger than HO.

// Example Level Crossing Control Driving Common Cathode LEDs
// Version 1.4  Geoff Bunza 2018
//
#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 = 5;   // IR sensor pin Assumption== Pin goes LOW when train detected
int sensor2 = 6;   // IR sensor pin Assumption== Pin goes LOW when train detected
int led1 = 10;      // Led 1 pin first alternating flasher
int led2 = 11;      // 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 led_gate_end = 7;            // Led at the end of the gate
int gatelow = 15;        // variable to store the servo low gate stop position
int gatehigh = 110;    // variable to store the servo high gate stop position
int gateposition = 110;    // variable to store the servo gateposition
int entering_sensor = 5;       //this will tell which sensor was triggered first
int leaving_sensor = 6;        // this will tell which sensor shows train leaving
int gates_started = 0;         // this says if the crossing is active
int flash_state = 0;
long flash_time = 0;
long  flash_interval = 700;    // time in milliseconds between alternating flashes
int sensor_count = 0;
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(sensor2, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);  
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode (led_gate_end , OUTPUT);
  digitalWrite(led1, LOW);  // Start with all flashers off
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
  digitalWrite(led_gate_end, HIGH);
  flash_time = millis();
}
void loop()
{
  if ((digitalRead (sensor1)==LOW)&& (gates_started==0)) {
    gates_started = 1;
    leaving_sensor = sensor2;
    starting_sequence();
  }
  if ((digitalRead (sensor2)==LOW)&& (gates_started==0)) {
    gates_started = 1;
    leaving_sensor = sensor1;
    starting_sequence();
  }
  if (gates_started) flash_leds();   //gates are down continue flashing
  if ((digitalRead(leaving_sensor)==LOW)&&(gates_started==1)) {   //train is starting to leave
   
  //as long as the leaving sensor is active the train is still in the crossing
  while (gates_started==1)  {   //now check if train is REALLY gone
    sensor_count = 0;
    for (int i=1; i< 40; i++)  {
      if (digitalRead(leaving_sensor)==LOW) sensor_count++;
          delay (40);
                  flash_leds();
                  }
    if (sensor_count==0) gates_started=0;
    flash_leds();
    }
    // we only get here if the train has really left the crossing
                ending_sequence();
  }
}
void starting_sequence()  {
  long wait_time;
  flash_time = millis();
  wait_time = millis()+3000;
  while (wait_time> millis())  flash_leds();  //flash before dropping gates
  for(gateposition = gatehigh; gateposition> gatelow; gateposition-=1)  // goes from gatehigh degrees to gatelow 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(80);                       // waits 40ms to slow servo
  }
}
void ending_sequence()  {
    for(gateposition = gatelow; gateposition< gatehigh; gateposition++)   // goes from gatelow degrees to gatehigh 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(80);                       // waits 40ms to slow servo
  }
  digitalWrite(led1, LOW);  //  flashers completely off
  digitalWrite(led3, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led4, LOW);
  digitalWrite(led_gate_end, LOW); 
  delay(10000);             // 30 second delay to account for the train passing the starting entry sensor
}
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);
  digitalWrite(led_gate_end, LOW);
  flash_time = millis()+flash_interval;
}

type or paste code here

Ok, the one where you can sit on top of the cars, or where you sit inside?