/*
Sketch: AuCP_4-Traffic-Light.ino
Created: 17-Apr-2023
Author: MicroBeaut (μB)
*/
#include "FiniteState.h"
#define rC1 12
#define yC1 11
#define gC1 10
#define rC2 9
#define yC2 8
#define gC2 7
#define rC3 A2
#define yC3 A1
#define gC3 A0
#define rC4 6
#define yC4 5
#define gC4 4
uint8_t lightCross1[] = {rC1, gC1, yC1}; // Define an array of light pins.
const uint8_t numberOfLightCross1 = sizeof(lightCross1) / sizeof(uint8_t); // Calculate the number of lights.
uint8_t lightCross2[] = {rC2, gC2, yC2}; // Define an array of light pins.
const uint8_t numberOfLightCross2 = sizeof(lightCross2) / sizeof(uint8_t); // Calculate the number of lights.
uint8_t lightCross3[] = {rC3, gC3, yC3}; // Define an array of light pins.
const uint8_t numberOfLightCross3 = sizeof(lightCross3) / sizeof(uint8_t); // Calculate the number of lights.
uint8_t lightCross4[] = {rC4, gC4, yC4}; // Define an array of light pins.
const uint8_t numberOfLightCross4 = sizeof(lightCross4) / sizeof(uint8_t); // Calculate the number of lights.
typedef struct {
unsigned long delayTime;
unsigned long startTime;
} Timer;
Timer delayTimeCross1[] = {
{3000}, // RED Delay Time 5 seconds
{5000}, // GREEN Delay Time 10 seconds
{1000}, // YELLOW Delay Time 3 seconds
};
Timer delayTimeCross2[] = {
{3000}, // RED Delay Time 5 seconds
{5000}, // GREEN Delay Time 10 seconds
{1000}, // YELLOW Delay Time 3 seconds
};
Timer delayTimeCross3[] = {
{3000}, // RED Delay Time 5 seconds
{5000}, // GREEN Delay Time 10 seconds
{1000}, // YELLOW Delay Time 3 seconds
};
Timer delayTimeCross4[] = {
{3000}, // RED Delay Time 5 seconds
{5000}, // GREEN Delay Time 10 seconds
{1000}, // YELLOW Delay Time 3 seconds
};
bool inputCross1(id_t id); // Predicate (Input)
void EventCross1(EventArgs e); // Event State
bool inputCross2(id_t id); // Predicate (Input)
void EventCross2(EventArgs e); // Event State
bool inputCross3(id_t id); // Predicate (Input)
void EventCross3(EventArgs e); // Event State
bool inputCross4(id_t id); // Predicate (Input)
void EventCross4(EventArgs e); // Event State
Transition transitionMain[] = {
{inputCross1, 0, 1, nullptr, EventCross1},
{inputCross1, 1, 2, nullptr, EventCross1},
{inputCross1, 2, 3, nullptr, EventCross1},
{inputCross2, 3, 4, nullptr, EventCross2},
{inputCross2, 4, 5, nullptr, EventCross2},
{inputCross2, 5, 6, nullptr, EventCross2},
{inputCross3, 6, 7, nullptr, EventCross3},
{inputCross3, 7, 8, nullptr, EventCross3},
{inputCross3, 8, 9, nullptr, EventCross3},
{inputCross4, 9, 10, nullptr, EventCross4},
{inputCross4, 10, 11, nullptr, EventCross4},
{inputCross4, 11, 0, nullptr, EventCross4}
};
const uint8_t numberOfTransitionMains = sizeof(transitionMain) / sizeof(Transition); // Calculate the number of transitions.
FiniteState fsmMain(transitionMain, numberOfTransitionMains); // Define Finite-State Object
uint8_t crossIndex = 0;
uint8_t lightIndex = 0;
void setup() {
Serial.begin(115200);
for (uint8_t index = 0; index < numberOfLightCross1; index ++) {
pinMode(lightCross1[index], OUTPUT); // Set Pin Mode
digitalWrite(lightCross1[index], LOW); // Set Light with the LOW state.
pinMode(lightCross2[index], OUTPUT); // Set Pin Mode
digitalWrite(lightCross2[index], LOW); // Set Light with the LOW state.
pinMode(lightCross3[index], OUTPUT); // Set Pin Mode
digitalWrite(lightCross3[index], LOW); // Set Light with the LOW state.
pinMode(lightCross4[index], OUTPUT); // Set Pin Mode
digitalWrite(lightCross4[index], LOW); // Set Light with the LOW state.
}
fsmMain.begin(0); // FSM begins with Initial Transition Id 0
}
void loop() {
fsmMain.execute(); // Execute the FSM
}
bool inputCross1(id_t id) {
return (millis() - delayTimeCross1[id].startTime >= delayTimeCross1[id].delayTime); // Determine Time Delay
}
void EventCross1(EventArgs e) {
switch (e.event) {
case ENTRY:
delayTimeCross1[e.id].startTime = millis();
LightControl(lightCross1, e.id);
LightControl(lightCross2, 0);
LightControl(lightCross3, 0);
LightControl(lightCross4, 0);
break;
}
}
bool inputCross2(id_t id) {
id = id - 3;
return (millis() - delayTimeCross2[id].startTime >= delayTimeCross2[id].delayTime); // Determine Time Delay
}
void EventCross2(EventArgs e) {
e.id = e.id - 3;
switch (e.event) {
case ENTRY:
delayTimeCross2[ e.id].startTime = millis();
LightControl(lightCross1, 0);
LightControl(lightCross2, e.id);
LightControl(lightCross3, 0);
LightControl(lightCross4, 0);
break;
}
}
bool inputCross3(id_t id) {
id = id - 6;
return (millis() - delayTimeCross3[id].startTime >= delayTimeCross3[id].delayTime); // Determine Time Delay
}
void EventCross3(EventArgs e) {
e.id = e.id - 6;
switch (e.event) {
case ENTRY:
delayTimeCross3[ e.id].startTime = millis();
LightControl(lightCross1, 0);
LightControl(lightCross2, 0);
LightControl(lightCross3, e.id);
LightControl(lightCross4, 0);
break;
}
}
bool inputCross4(id_t id) {
id = id - 9;
return (millis() - delayTimeCross4[id].startTime >= delayTimeCross4[id].delayTime); // Determine Time Delay
}
void EventCross4(EventArgs e) {
e.id = e.id - 9;
switch (e.event) {
case ENTRY:
delayTimeCross4[e.id].startTime = millis();
LightControl(lightCross1, 0);
LightControl(lightCross2, 0);
LightControl(lightCross3, 0);
LightControl(lightCross4, e.id);
break;
}
}
void LightControl(uint8_t *pins, uint8_t id) {
for (uint8_t index = 0; index < 3; index++) {
digitalWrite(pins[index], LOW); // Write a value to LED.
}
digitalWrite(pins[id], HIGH); // Write a value to LED.
}