#define LED 3 // LED COUNTS FOR EACH TRAFFIC LIGHT
#define LIGHTS 4 // TOTAL TRAFIC LIGHTS
#define STATUS 8 // TOTAL STATUS FOR ALL TRAFFIC LIGHTS
// =========================================
// DEFINE TRAFFIC LIGHT BASIC SPECIFICATIONS
// =========================================
typedef struct {
byte gre; // REFERENCE FOR GREEN LED
byte yel; // REFERENCE FOR YELLOW LED
byte red; // REFERENCE FOR RED LED
} TRAFFIC_LIGHT;
// ========================================================================
// ARRAY OF STRUCT WITH DEFAULT SETTINGS FOR EACH JUNCTION OF TRAFFIC LIGHT
// ========================================================================
TRAFFIC_LIGHT traffic_light[LIGHTS] = {
{ .gre = 11, .yel = 12, .red = 13, },
{ .gre = 8, .yel = 9, .red = 10, },
{ .gre = 5, .yel = 6, .red = 7, },
{ .gre = 2, .yel = 3, .red = 4, },
};
// ============================================================================
// ARRAY TO HOLD ALL AVAILABLE EACH TRAFFIC LIGHT STATUS ( 0 - LOW , 1 - HIGH )
// ============================================================================
byte LIGHT_STATUS_ARRAY[STATUS][LIGHTS][LED] = {
// JUNCTION 1 WHEN GREEN
{ {0, 0, 1}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0} },
// JUNCTION 1 CHANGING TO JUNCTION 2
{ {0, 1, 0}, {0, 1, 0}, {1, 0, 0}, {1, 0, 0} },
// JUNCTION 2 WHEN GREEN
{ {1, 0, 0}, {0, 0, 1}, {1, 0, 0}, {1, 0, 0} },
// JUNCTION 2 CHANGING TO JUNCTION 3
{ {1, 0, 0}, {0, 1, 0}, {0, 1, 0}, {1, 0, 0} },
// JUNCTION 3 WHEN GREEN
{ {1, 0, 0}, {1, 0, 0}, {0, 0, 1}, {1, 0, 0} },
// JUNCTION 3 CHANGING TO JUNCTION 4
{ {1, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 1, 0} },
// JUNCTION 4 WHEN GREEN
{ {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {0, 0, 1} },
// JUNCTION 4 CHANGING TO JUNCTION 1
{ {0, 1, 0}, {1, 0, 0}, {1, 0, 0}, {0, 1, 0} },
};
byte current_state = 0; // STATE CURRENT SITUATION OF TRAFFIC SEQUENCE
const int TIMEOUT_LOOP = 100;
const int TIMEOUT_GREEN = 3000;
const int TIMEOUT_YELLO = 500;
void change_traffic_signal(byte); // FUNC PROTOTYPE FOR UPDATE TRAFFIC SIGNAL
void setup() {
// MAKE ALL TRAFFIC LEDS PIN MODE AS OUTPUT
for (int i = 0; i < LIGHTS; i++) {
pinMode(traffic_light[i].gre, OUTPUT);
pinMode(traffic_light[i].yel, OUTPUT);
pinMode(traffic_light[i].red, OUTPUT);
}
}
void loop() {
current_state = current_state % STATUS; // CALCULATE CURRENT STATE
change_traffic_signal(current_state); // UPDATE SIGNAL
current_state++; // INCREMENT CURRENT STATE COUNT
delay(TIMEOUT_LOOP);
}
void change_traffic_signal(byte state) {
// UPDATE ALL TRAFFIC LEDS USING CURRENT STATE
for (int lgt = 0; lgt < LIGHTS; lgt++) {
digitalWrite(traffic_light[lgt].red, LIGHT_STATUS_ARRAY[state][lgt][0]);
digitalWrite(traffic_light[lgt].yel, LIGHT_STATUS_ARRAY[state][lgt][1]);
digitalWrite(traffic_light[lgt].gre, LIGHT_STATUS_ARRAY[state][lgt][2]);
}
if ((state + 1) % 2 != 0) // WHEN YELLOW NOT WORKS DELAY TIMEOUT_GREEN milliseconds
delay(TIMEOUT_GREEN);
else
delay(TIMEOUT_YELLO);
}