Loop Countdown Required Question; Traffic Light Sequencing

Hi, I am new to programming Arduinos and a workmate is wanting to build a working Traffic Light display, I made a simple list of codes that run different lighting sequences, and they follow through to the next. Modified an existing piece of code from online.

Currently I have a set of codes for running a single Traffic Light.
Green => Yellow => Red for 3 cycles, then
Flashing Yellow for 6 cycles (just used Yellow High/Low 6 times), back to Green, Yellow, Red, then
Flashing Red for 6 cycles, then back to the top, running a normal Traffic Light sequence.

So instead of repeating the lines multiple times, can I use a countdown for each?
Included is my attempt at coding.

int Red = 12;
int Yellow = 11;
int Green = 10;
void setup() {
 // put your setup code here, to run once:
pinMode(Red, OUTPUT);
pinMode(Yellow, OUTPUT);
pinMode(Green, OUTPUT);
}

void loop() {
 // put your main code here, to run repeatedly:
changelights();
delay(30000);
}
void changelights(){
 //Turn Green On for 7secs
 digitalWrite(Red, HIGH);
 digitalWrite(Yellow, HIGH);
 digitalWrite(Green, LOW);
 delay(7000);
 //green off, yellow on for 3 secs
 digitalWrite(Green, HIGH);
 digitalWrite(Yellow, LOW);
 digitalWrite(Red, HIGH);
 delay(3000);
 //turn off yellow, then turn red on for 5secs
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, LOW);
 delay(7000);
 //red and yellow on for 2secs (red is already on though)
 //digitalWrite(Yellow, HIGH);
 //delay(2000);
 //turn red and yellow off, then turn on green
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, HIGH);
 digitalWrite(Green, LOW);
 delay(7000);
 //green off, yellow on for 3 secs
 digitalWrite(Green, HIGH);
 digitalWrite(Yellow, LOW);
 digitalWrite(Red, HIGH);
 delay(3000);
 //turn off yellow, then turn red on for 5secs
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, LOW);
 delay(7000);
 //red and yellow on for 2secs (red is already on though)
 //digitalWrite(Yellow, HIGH);
 //delay(2000);
 //turn red and yellow off, then turn on green
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, HIGH);
 digitalWrite(Green, LOW);
 delay(3000);
 //Turn Yellow on for Faulty Light
 digitalWrite(Green, HIGH);
 digitalWrite(Yellow, LOW);
 delay(500);
 digitalWrite(Yellow,HIGH);
 delay(500);
 digitalWrite(Yellow, LOW);
 delay(500);
 digitalWrite(Yellow,HIGH);
 delay(500);
 digitalWrite(Yellow, LOW);
 delay(500);
 digitalWrite(Yellow,HIGH);
 delay(500);
 digitalWrite(Yellow, LOW);
 delay(500);
 digitalWrite(Yellow,HIGH);
 delay(500);
 digitalWrite(Yellow, LOW);
 delay(500);
 digitalWrite(Yellow,HIGH);
 delay(500);
 digitalWrite(Yellow, LOW);
 delay(500);
 digitalWrite(Yellow,HIGH);
 delay(500);
 digitalWrite(Red, LOW);
 delay(7000);
 //Turn Green On for 7secs
 digitalWrite(Red, HIGH);
 digitalWrite(Yellow, HIGH);
 digitalWrite(Green, LOW);
 delay(7000);
 //green off, yellow on for 3 secs
 digitalWrite(Green, HIGH);
 digitalWrite(Yellow, LOW);
 digitalWrite(Red, HIGH);
 delay(3000);
 //turn off yellow, then turn red on for 5secs
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, LOW);
 delay(7000);
 //red and yellow on for 2secs (red is already on though)
 //digitalWrite(Yellow, HIGH);
 //delay(2000);
 //turn red and yellow off, then turn on green
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, HIGH);
 digitalWrite(Green, LOW);
 delay(7000);
 //green off, yellow on for 3 secs
 digitalWrite(Green, HIGH);
 digitalWrite(Yellow, LOW);
 digitalWrite(Red, HIGH);
 delay(3000);
 //turn off yellow, then turn red on for 5secs
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, LOW);
 delay(7000);
 //red and yellow on for 2secs (red is already on though)
 //digitalWrite(Yellow, HIGH);
 //delay(2000);
 //turn red and yellow off, then turn on green
 digitalWrite(Yellow, HIGH);
 digitalWrite(Red, HIGH);
 digitalWrite(Green, LOW);
 delay(3000);
 //Turn Red on for Hazard, Stop
 digitalWrite(Green, HIGH);
 digitalWrite(Red, LOW);
 delay(500);
 digitalWrite(Red,HIGH);
 delay(500);
 digitalWrite(Red, LOW);
 delay(500);
 digitalWrite(Red,HIGH);
 delay(500);
 digitalWrite(Red, LOW);
 delay(500);
 digitalWrite(Red,HIGH);
 delay(500);
 digitalWrite(Red, LOW);
 delay(500);
 digitalWrite(Red,HIGH);
 delay(500);
 digitalWrite(Red, LOW);
 delay(500);
 digitalWrite(Red,HIGH);
 delay(500);
 digitalWrite(Red, LOW);
 delay(500);
 digitalWrite(Red,HIGH);
 delay(500);
 digitalWrite(Red, LOW);
}

Thanks for any help. Kevin

Yes, it's easy. Just make a table showing in rows, the current state of all lights. To write the program, you just write lines that change the lights that are required to transition from one row to the next. When you reach the end, start again from the beginning.

You have to explain your "countdown for each" concept. It doesn't suggest much. Countdown to what?

Hi,
So I have 3 sections, the first part is a normal "traffic light" seq, which I cycle through 2 times,
this then goes through a "Yellow hazard" seq, for 6 times,
back to a normal "traffic light" seq, and last,
through a "Red Stop Hazard" seq, for 6 cycles, and back to the top.

I wish to remove all the extra code (same details), if possible and have each seq countdown. So instead of 6 copied On/Off actions, I can put a countdown expression so when it reaches 6 loops it will go onto the next part of the code, which would be a normal traffic light seq, etc.

I am trying to read up on as much as I can, very new to Arduino use.
I am trying a few bits of code, and see what happens.
Regards

if you mean having a loop statement you could change for example this

 digitalWrite(Yellow, LOW);
  delay(500);
  digitalWrite(Yellow,HIGH);
  delay(500);
  digitalWrite(Yellow, LOW);
  delay(500);
  digitalWrite(Yellow,HIGH);
  delay(500);
  digitalWrite(Yellow, LOW);
  delay(500);
  digitalWrite(Yellow,HIGH);
  delay(500);
  digitalWrite(Yellow, LOW);
  delay(500);
  digitalWrite(Yellow,HIGH);
  delay(500);
  digitalWrite(Yellow, LOW);
  delay(500);
  digitalWrite(Yellow,HIGH);
  delay(500);
  digitalWrite(Yellow, LOW);
  delay(500);
  digitalWrite(Yellow,HIGH);
  delay(500);

into

for (byte i=0; i<6;i++) {
  digitalWrite(Yellow, LOW);
  delay(500);
  digitalWrite(Yellow,HIGH);
  delay(500);
}

And after you've mastered the for() loop presented by J-M-L you can make it more general by putting it - the loop - inside a function and passing it the output to be flashed and, possibly, the number of times to flash. This way both red and yellow could be flashed with a single line of code each.

Going further, a similar thing can be done with the green/yellow/red sequencing. Put it in a function to which you pass in a boolean state for each color and a delay time.

  //green off, yellow on for 3 secs
  digitalWrite(Green, HIGH);
  digitalWrite(Yellow, LOW);
  digitalWrite(Red, HIGH);
  delay(3000);

could become

 //green off, yellow on for 3 secs

//        grn  yel  red
gyrState(HIGH, LOW, HIGH, 3);

And so on.

consider (more data driven)

int Red    = 12;
int Yellow = 11;
int Green  = 10;

typedef struct {
    int           led;
    unsigned long msec;
} LedList_s ;

enum { OFF = HIGH, ON = LOW };

const unsigned long Flash =  200;
const unsigned long Short =  500;
const unsigned long Long  = 1000;

LedList_s gyr [] = {
    { Green,  Long },
    { Yellow, Short },
    { Red,    Long },
    { -1,     0 },
};

LedList_s yel [] = {
    { Yellow, Flash },
    { 0,      Flash },
    { -1,     0 },
};

// -----------------------------------------------------------------------------
void setup() {
    Serial.begin (9600);

    pinMode(Red, OUTPUT);
    pinMode(Yellow, OUTPUT);
    pinMode(Green, OUTPUT);
}


// -----------------------------------------------------------------------------
void
sequence (
    LedList_s  *s )
{
    digitalWrite (Red,    OFF);
    digitalWrite (Yellow, OFF);
    digitalWrite (Green,  OFF);

    for ( ; 0 <= s->led; s++)  {
        if (0 != s->led)
            digitalWrite (s->led, ON);

        delay (s->msec);

        if (0 != s->led)
            digitalWrite (s->led, OFF);
    }
}

// ---------------------------------------------------------
void loop() {
    sequence (gyr);

    for (int n = 10; n > 0; n--)
        sequence (yel);
}

Thanks all,
I have got this code in and working as I would like. It does help when you ask the right question.
I will look at the other code later in the day.
Regards and again a big thanks. Kevin.

@gcjr

Nice but

did you change your mind halfway through about what ends a sequence? That’s the only way I make sense just yet of your little “interpreter”.

a7

the end of a sequence, or an element of a sequence is when the led is turned off.

OK I was om the wrong trail there. Nothing new about that good thing I’m not an airline pilot.

a7

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