UK type Level Crossing Lights - stuck doing the yellow once!

Hi All,

A bit of background first - im posting on behalf of my son, who is learning to code. Im an experienced RF engineer, but hopeless at programming (havent done any since the Spectrum in my youth)

We started with what we thought would be a simple task - simulate a UK type set of railway level crossing lights. This is essentially a case of turning on a yellow LED for a few seconds, then switching to alternating Reds.

We can make the yellow turn on, and off, and can alternate the reds, all well and good. What we cant figure out though, is how to have the yellow come on for a few seconds, then switch to the alternating reds (ie how to do the yellow once then into the loop for the reds). What we get is yellow, red1, red2, then back to yellow as we hit the end of the main loop!

Weve tried playing with do while to try and use a variable to 'count' the steps and jump us out, but that didnt work. Im sure there must be a simple technique!

Can anyone suggest something?

As I say, my programming knowledge is all but non existent!

Cheers Martin

It's hard to help without seeing your code in code tags.

While there is no code my guess is you need a flag. I'm going to say that the yellow lights are a warning and create a warned flag. Something like this.

boolean warned = false; // create our flag

// then in the code (probably loop())

if (!warned)
    // display the yellow lights
    warned = true; // set the flag to true, very important
// now your yellow lights won't come on unless warned is reset to false.

The reason I use that particular syntax in the if() is that it reads "If NOT warned".

Thanks for the input,

Wasnt able to attach the code as was on a different machine, it wouldnt have helped at that stage anyway - it was just a list of on and off commands and delays!

Managed to work it out, it was all about coming to grips with how the program executes and the best was of implementing decision making. We got it working with a simple counter (N=N+1 etc), and have now progressed to a pushbutton input to simulate a train present needing the level crossing lights to be active. Its very crude but works!

const int RED1 = 12; // Left hand RED led
const int RED2 = 13; // Right hand RED led
const int YELLOW = 11; // Amber LED
const int TRACK = 8; //track interlock (train sensor)
int button = 0; //variable for reading track interlock input

void setup() 
pinMode (RED1, OUTPUT);
pinMode (RED2, OUTPUT);
pinMode (TRACK, INPUT);

void loop() 

do {
  button = digitalRead(TRACK);  //read port 8 pushbutton
} while (button == LOW); // loop back whilst button is not pressed

 digitalWrite(YELLOW, HIGH); //put amber warning LED on for 3 sec
 delay (3000);
 digitalWrite(YELLOW, LOW);

 do {                         // Alternating RED LED sequence
 digitalWrite(RED1, HIGH);
 digitalWrite(RED1, LOW);
 digitalWrite(RED2, HIGH);
 digitalWrite(RED2, LOW);

 button = digitalRead(TRACK);  //read port 8 pushbutton
 } while (button == HIGH); //repeat while button is pressed
 delay (100); //wait 100 msec

While ever the button is not pressed, all lamps are off. Once pressed, the AMBER light comes on for 3sec (warning of impending barrier closure!) followed by the alternating RED lamps. The red lamps will now continue to flash for as long as the button is pressed.

Now do it without delays. Actually this is one of those sketches where using delay() isn't the worst thing. The only issue being that there might be as long as a five second gap from when the switch is released until it is read and reacted to. If the switch is released just as the yellow comes on it will display the yellow and one sequence of blinking red. To instantly respond to the switch you need to do all this without using the delay() function.

In this case, the continuation of the sequence through yellow and a couple of red even if the switch is immediately released is actually in accord with the fail safe features of the real level crossing systems, which for obvious reasons cannot fail to indicate if the sensor itself fails immediately after activation!

But, yes, the use of the delays is far from ideal (the delay command seems to have the same stigma to it that GOTO had in BASIC!)

Its not a bad start though considering total coding time spent on this device so far is about 3h!

But, yes, the use of the delays is far from ideal (the delay command seems to have the same stigma to it that GOTO had in BASIC!)

Almost but not quite. Your sketch is fine with delay() and I've done sketches with delay() where I did actually want to block. It has its uses. In C you can also use a goto but it is highly frowned upon and I've never ever had to use one myself. I'm sure there are probably legitimate uses for it.

delay() messes up some newer programmers because it blocks and can really effect the responsiveness of switches. In some cases, like yours, it doesn't matter.

The demo Several Things at a Time illustrates how to flash LEDs using millis() to manage the timing without blocking.

You may also find something useful in Planning and Implementing a Program