I've been working on a project involving a traffic light sequence using timing rather than delay so that I may mesh together several programs.
This code currently has the traffic light loops and a bridge strobe light loop.
I'm having a hard time with the sequence of the traffic lights, the bridge light operates as desired.
I would like for the LED outputs to work in relation to each other rather than the time since the program began running.
If I only program one traffic light, meaning one of each red, yellow and green, I am fine. It is when I try to add a traffic light for the other direction, which would need to operate opposite of the first traffic light, that I have trouble.
The timing I have figured gives me a good traffic light pattern, however the way I have it programmed is wrong; i need the timing to occur in sequence not all at once.
I also would like the Red leds to overlap as they do in a prototypical traffic light so I can't get the opposite traffic light to function with just the wiring (I wish it were that simple)
I've been learning how to use the millis function but am not quite to the point of solving this timing issue.
My questions are;
Am I correct in using millis for this project or should I be using an array or some other functions in conjunction?
If I am using the right function, is there a way to use the previousMillis function to compare the time elapsed to that of another action rather than the currentMillis? Maybe by using an if statement?
To help myself I have played with the blink without delay example and the multiple things at once example as well as reading another similar post on this forum and trial and error with millis and programming the Arduino in general. I've also looked at and played with programming created by others to help me learn how millis works.
// This program controls all the traffic lights at one intersection as well as
// a single red strobe light on top of a bridge
// program assumes common Anode LED configuration
// --------CONSTANTS (won't change)---------------
#define ledON LOW
#define ledOFF HIGH
const int NSG = 2; // the pin numbers for the LEDs
const int NSY = 3;
const int NSR = 4;
const int EWG = 5;
const int EWY = 6;
const int EWR = 9;
const int bridgelight = 8;
const int bridgelight_off_time = 1000; // How long the bridge light is off
const int bridgelight_on_time = 25; // how long the bridge light is on
const int NSG_on_time = 10000; // How long the northsouth green LED is on
const int NSG_off_time = 18000; // How long the northsouth Green LED is off
const int NSY_on_time = 2000; // northsouth yellow
const int NSY_off_time = 26000; //northsouth yellow
const int NSR_on_time = 16000; //northsouth red on
const int NSR_off_time = 12000; //northsouth red off
const int EWG_on_time = 10000; // same as above, but ewastwest leds
const int EWG_off_time = 180000;
const int EWY_on_time = 2000;
const int EWY_off_time = 26000;
const int EWR_on_time = 16000;
const int EWR_off_time = 12000;
//------------ VARIABLES (will change)---------------------
byte NSG_State = ledON; // used to record whether the LEDs are on or off
byte NSY_State = ledOFF;
byte NSR_State = ledOFF;
byte EWG_State = ledOFF; // used to record whether the LEDs are on or off
byte EWY_State = ledOFF;
byte EWR_State = ledON;
byte bridgelight_State = ledOFF;
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long NSG_previousMillis = 0; // will store last time the LED was updated for each iteration of loop
unsigned long NSR_previousMillis = 0;
unsigned long EWG_previousMillis = 0; // will store last time the LED was updated for each iteration of loo
unsigned long EWR_previousMillis = 0;
unsigned long NSY_previousMillis = 0;
unsigned long EWY_previousMillis = 0;
unsigned long bridge_previousMillis = 0;
void setup() {
Serial.begin(9600);
// set the Led pins as output:
pinMode(NSG, OUTPUT);
pinMode(NSY, OUTPUT);
pinMode(NSR, OUTPUT);
pinMode(EWG, OUTPUT);
pinMode(EWY, OUTPUT);
pinMode(EWR, OUTPUT);
pinMode(bridgelight,OUTPUT);
}
void loop() {
currentMillis = millis();
NSG_update();
NSY_update();
NSR_update();
EWG_update();
EWY_update();
EWR_update();
switchLeds();
bridgeflash();
}
void NSG_update() {
if (NSG_State == ledOFF) {
// if the Led is off, we must wait for the interval to expire before turning it on
if (currentMillis - NSG_previousMillis >= NSG_off_time) {
NSG_State = ledON;
NSG_previousMillis += NSG_off_time;
}
}
else {
if (currentMillis - NSG_previousMillis >= NSG_on_time) {
NSG_State = ledOFF;
NSG_previousMillis += NSG_on_time;
}
}
}
void NSY_update() {
if (NSY_State == ledOFF) {
// if the Led is off, we must wait for the interval to expire before turning it on
if (currentMillis - NSY_previousMillis >= NSY_off_time) {
NSY_State = ledON;
NSY_previousMillis += NSY_off_time;
}
}
else {
if (currentMillis - NSY_previousMillis >= NSY_on_time) {
NSY_State = ledOFF;
NSY_previousMillis += NSG_on_time;
}
}
}
void NSR_update() {
if (NSR_State == ledOFF) {
if (currentMillis - NSR_previousMillis >= NSR_off_time) {
NSR_State = ledON;
NSR_previousMillis += NSR_off_time;
}
}
else {
if (currentMillis - NSR_previousMillis >= NSR_on_time) {
NSR_State = ledOFF;
NSR_previousMillis += NSR_on_time;
}
}
}
void EWG_update() {
if (EWG_State == ledOFF) {
// if the Led is off, we must wait for the interval to expire before turning it on
if (currentMillis - EWG_previousMillis >= EWG_off_time) {
EWG_State = ledON;
EWG_previousMillis += EWG_off_time;
}
}
else {
if (currentMillis - EWG_previousMillis >= EWG_on_time) {
EWG_State = ledOFF;
EWG_previousMillis += EWG_on_time;
}
}
}
void EWY_update() {
if (EWY_State == ledOFF) {
// if the Led is off, we must wait for the interval to expire before turning it on
if (currentMillis - EWY_previousMillis >= EWY_off_time) {
EWY_State = ledON;
EWY_previousMillis += EWY_off_time;
}
}
else {
if (currentMillis - EWY_previousMillis >= EWY_on_time) {
EWY_State = ledOFF;
EWY_previousMillis += EWY_on_time;
}
}
}
void EWR_update() {
if (EWR_State == ledOFF) {
if (currentMillis - EWR_previousMillis >= EWR_off_time) {
EWR_State = ledON;
EWR_previousMillis += EWR_off_time;
}
}
else {
if (currentMillis - EWR_previousMillis >= EWR_on_time) {
EWR_State = ledOFF;
EWR_previousMillis += EWR_on_time;
}
}
}
void bridgeflash()
{
if (bridgelight_State == ledOFF) {
if (currentMillis - bridge_previousMillis >= bridgelight_off_time) {
bridgelight_State = ledON;
bridge_previousMillis += bridgelight_off_time;
}
}
else {
if (currentMillis - bridge_previousMillis >= bridgelight_on_time) {
bridgelight_State = ledOFF;
bridge_previousMillis += bridgelight_on_time;
}
}
}
void switchLeds() {
// this is the code that actually switches the LEDs on and off
digitalWrite(NSG, NSG_State);
digitalWrite(NSY, NSY_State);
digitalWrite(NSR, NSR_State);
digitalWrite(EWG, EWG_State);
digitalWrite(EWY, EWY_State);
digitalWrite(EWR, EWR_State);
digitalWrite(bridgelight, bridgelight_State);
}