Restarting a loop with interrupts- traffic light

I'm trying to work out the logic for an Arduino project that I am doing.

This is a remix of the classic traffic light problem with two pushbuttons for pedestrian crossing. Basically what it should do is:

  1. green light for 10 seconds
  2. yellow light for 2 seconds
  3. red light for 5 seconds with solid blue crossing lights
  4. red light for 5 seconds with flashing blue crossing lights warning pedestrians to hurry
  5. at any time one of two push buttons (either side of the street) can be used to tell the program that pedestrians are going to cross

The light change bit I have working, but the crossing sequence is giving me trouble.

The pushbuttons are connected to digital pins 2 and 3 and use interrupts to start the crossing sequence, which looks like this.
a) if the light is green, delay for 2 seconds for traffic, then turn yellow and red
b) if the light is yellow, do nothing since the crossing sequence is about to start anyway
c) if the light is red, restart the red sequence to give pedestrians more time to cross

The problem that I am having is this: when using interrupts the code will return to the same place where it was before the interrupt happened after the interrupt code finished. This means that if you pressed the interrupt during the green cycle, it would go to the yellow and red cycles, then return to the same spot and go right back to yellow and red. I would like it to go back to the beginning of the code and restart the green cycle after the crossing cycle is finished.

From what I've read, the goto statement is evil and wouldn't work anyway since the interrupt function is outside of the scope of the main loop. Any help with the logic/ programming structures would be very helpful!

trafficLight.ino (1.71 KB)

So ultimately the problem is the fact that you are using a delay() in the color cycle functions. Once initiated you can't break out of that. You could have a more granular delay cycle checking for button presses. Something like a for loop iterating 100 times with a check and a delay(10) assuming the original was 1000. (remember to use volatile vars for the interrupt vars). Or each of those functions could return bools that told the system to restart if needed. But like most programming problems, there are a lot of different solutions.

Welcome,

Yes your problem is that you are using delays and while loops. Those are blocking your code.

You can do traffic lights without any blocking code, just using some if/else and a few variables. In fact, the best structure you could use is a state machine.

@azsparky , sparcnz is also working on traffic lights and has a really similar name. You two might want to collaborate.
https://forum.arduino.cc/index.php?topic=734973.0

Also, you don't need to use interrupts for this application.

Thanks- I'll try using some if/ else and the millis() function for a timer.

Thanks for the tip about removing the delay(). I was able to use the millis() function to create a timer and controlled it with some if statements. A little simpler than a state machine, maybe that can be the next project.

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