// Pins for NORTH-SOUTH traffic light
#define NS_RED_LED_PIN 2
#define NS_YELLOW_LED_PIN 3
#define NS_GREEN_LED_PIN 4
// Pins for EAST-WEST traffic light
#define EW_RED_LED_PIN 5
#define EW_YELLOW_LED_PIN 6
#define EW_GREEN_LED_PIN 7
// Pin for NORTH-SOUTH button
#define NS_BUTTON_PIN 8
// Pin for EAST-WEST button
#define EW_BUTTON_PIN 9
// Time for yellow light
#define SEMAPHORE_PREP_TIME 2000
// Delay time for switching after button press
#define SEMAPHORE_SWITCH_TIME 1000
// Baud rate for serial communication
#define SERIAL_BAUD_RATE 9600
/*
Automata.state - state to be executed
Automata.nextState:
* 0 - for no button pressed
* 1 - for NS button pressed
* 2 - for EW button pressed
* 3 - for both buttons pressed
*/
struct Automata {
void (*state)();
int nextState[4];
};
void prep_delay();
void NS_go();
void EW_prep();
void EW_go();
void NS_prep();
int getNextState();
// Automata rules for traffic light
Automata automata[] = {
{NS_go, {0, 0, 1, 1}},
{prep_delay, {2, 2, 2, 2}},
{EW_prep, {3, 3, 3, 3}},
{EW_go, {3, 4, 3, 4}},
{prep_delay, {5, 5, 5, 5}},
{NS_prep, {0, 0, 0, 0}}
};
// Function for delay
void prep_delay(){
delay(SEMAPHORE_SWITCH_TIME);
}
// Function for NS green
void NS_go(){
digitalWrite(NS_RED_LED_PIN, LOW);
digitalWrite(NS_YELLOW_LED_PIN, LOW);
digitalWrite(NS_GREEN_LED_PIN, HIGH);
digitalWrite(EW_RED_LED_PIN, HIGH);
digitalWrite(EW_YELLOW_LED_PIN, LOW);
digitalWrite(EW_GREEN_LED_PIN, LOW);
}
// Function for EW prepation to green
void EW_prep(){
digitalWrite(NS_RED_LED_PIN, LOW);
digitalWrite(NS_YELLOW_LED_PIN, HIGH);
digitalWrite(NS_GREEN_LED_PIN, LOW);
digitalWrite(EW_RED_LED_PIN, HIGH);
digitalWrite(EW_YELLOW_LED_PIN, HIGH);
digitalWrite(EW_GREEN_LED_PIN, LOW);
delay(SEMAPHORE_PREP_TIME);
}
// Function for EW green
void EW_go(){
digitalWrite(NS_RED_LED_PIN, HIGH);
digitalWrite(NS_YELLOW_LED_PIN, LOW);
digitalWrite(NS_GREEN_LED_PIN, LOW);
digitalWrite(EW_RED_LED_PIN, LOW);
digitalWrite(EW_YELLOW_LED_PIN, LOW);
digitalWrite(EW_GREEN_LED_PIN, HIGH);
}
// Function for NS prepation to green
void NS_prep(){
digitalWrite(NS_RED_LED_PIN, HIGH);
digitalWrite(NS_YELLOW_LED_PIN, HIGH);
digitalWrite(NS_GREEN_LED_PIN, LOW);
digitalWrite(EW_RED_LED_PIN, LOW);
digitalWrite(EW_YELLOW_LED_PIN, HIGH);
digitalWrite(EW_GREEN_LED_PIN, LOW);
delay(SEMAPHORE_PREP_TIME);
}
// Function for getting next state based on button press
int getNextState(){
if(digitalRead(NS_BUTTON_PIN) == HIGH && digitalRead(EW_BUTTON_PIN) == HIGH){
return 3;
}else if(digitalRead(NS_BUTTON_PIN) == HIGH){
return 1;
}else if(digitalRead(EW_BUTTON_PIN) == HIGH){
return 2;
}else{
return 0;
}
}
// Setup function
void setup(){
Serial.begin(SERIAL_BAUD_RATE);
pinMode(NS_RED_LED_PIN, OUTPUT);
pinMode(NS_YELLOW_LED_PIN, OUTPUT);
pinMode(NS_GREEN_LED_PIN, OUTPUT);
pinMode(EW_RED_LED_PIN, OUTPUT);
pinMode(EW_YELLOW_LED_PIN, OUTPUT);
pinMode(EW_GREEN_LED_PIN, OUTPUT);
pinMode(NS_BUTTON_PIN, INPUT);
pinMode(EW_BUTTON_PIN, INPUT);
}
// Loop function
void loop(){
// Current state index
static int currentState = 0;
// Execute current state function
automata[currentState].state();
// Get button press state
int nextState = getNextState();
// Change state based on button press
currentState = automata[currentState].nextState[nextState];
delay(100);
}