Skip to content

Instantly share code, notes, and snippets.

@twitch0001
Created December 8, 2023 20:52
Show Gist options
  • Save twitch0001/0e2c9b35e61bb6e6dc28b72296fbbf8f to your computer and use it in GitHub Desktop.
Save twitch0001/0e2c9b35e61bb6e6dc28b72296fbbf8f to your computer and use it in GitHub Desktop.
#include <Servo.h>
// Different states of the system, are used within several functions to decide the sequencing
enum SYSTEM_STATE {
pedestrians_only, // Only pedestrians can cross
cars_only, // Only cars can proceed
gate_only,
none // neither can proceed
};
enum LIGHT_STATE {
proceed,
caution,
stop
};
enum GATE_STATE {
open,
closing,
closed
};
int GATE_WARN = 2;
int PED_GREEN = 6;
int PED_AMBER = 5;
int PED_RED = 4;
int CAR_GREEN = 8;
int CAR_AMBER = 9;
int CAR_RED = 10;
int EXIT_GREEN = 13;
int EXIT_AMBER = 12;
int EXIT_RED = 11;
int GATE_SERVO = 3;
int PEDESTRIAN_LDR1 = A0;
int PEDESTRIAN_LDR2 = A1;
int GATE_BUTTON = A2;
int SERVO_POS = 0;
Servo gate;
int pos = 0;
SYSTEM_STATE state = cars_only; // Start system with cars proceeding, pedestrians not
// State of the lights for pedestrians & cars
LIGHT_STATE pedestrians = stop;
LIGHT_STATE cars = stop;
LIGHT_STATE gate_exit = stop;
GATE_STATE gate_open = closed;
void setPedestrians(LIGHT_STATE new_state) {
int g;
int a;
int r;
switch (new_state) {
case stop:
g = LOW;
a = LOW;
r = HIGH;
break;
case proceed:
g = HIGH;
r = LOW;
break;
Serial.println("Setting green to HIGH");
};
digitalWrite(PED_GREEN, g);
digitalWrite(PED_AMBER, a);
digitalWrite(PED_RED, r);
pedestrians = new_state;
}
void setCars(LIGHT_STATE new_state) {
int cg = LOW;
int ca = LOW;
int cr = LOW;
switch (new_state) {
case stop:
Serial.println("Setting cars to stop");
cg = LOW;
ca = LOW;
cr = HIGH;
break;
case caution:
Serial.println("Setting cars to caution");
cg = LOW;
ca = HIGH;
cr = LOW;
break;
case proceed:
Serial.println("Setting cars to proceed");
cg = HIGH;
ca = LOW;
cr = LOW;
break;
};
digitalWrite(CAR_GREEN, cg);
digitalWrite(CAR_AMBER, ca);
digitalWrite(CAR_RED, cr);
cars = new_state;
}
void setGate(LIGHT_STATE new_state) {
int gg = LOW;
int ga = LOW;
int gr = LOW;
switch (new_state) {
case stop:
Serial.println("Setting gate to stop");
gg = LOW;
ga = LOW;
gr = HIGH;
break;
case caution:
Serial.println("Setting gate to caution");
gg = LOW;
ga = HIGH;
gr = LOW;
break;
case proceed:
Serial.println("Setting gate to proceed");
gg = HIGH;
ga = LOW;
gr = LOW;
break;
};
digitalWrite(EXIT_GREEN, gg);
digitalWrite(EXIT_AMBER, ga);
digitalWrite(EXIT_RED, gr);
gate_exit = new_state;
}
void setState(SYSTEM_STATE new_state) {
switch (new_state) {
case pedestrians_only:
if (cars != stop || cars != caution) {
setCars(caution);
delay(1000);
}
setCars(stop);
delay(1500);
setPedestrians(proceed);
break;
case none:
setGate(stop);
setCars(stop);
setPedestrians(stop);
break;
case cars_only:
setGate(stop);
setPedestrians(stop);
delay(500);
setCars(caution);
delay(1500);
setCars(proceed);
break;
case gate_only:
// SEQ; P:R, C:A (1s) C:R, G:WARN, G:G
setPedestrians(stop); // Just incase...
if (cars != stop || cars != caution) {
setCars(caution);
delay(1000);
}
setCars(stop);
int warn = 1;
for (pos=0; pos <= 90; pos++) {
gate.write(pos);
warn = (warn == 1) ? 0 : 1;
digitalWrite(GATE_WARN, warn);
delay(100);
}
setGate(caution);
delay(1000);
setGate(proceed);
delay(10000);
setGate(caution);
delay(1000);
setGate(stop);
delay(500); // Cars might try to jump the red.
gate.write(0); // close the gate
break;
}
state = new_state;
}
void setup() {
Serial.begin(9600); // Start serial monitor at 9600 Baud - used for debugging
pinMode(PED_GREEN, OUTPUT);
pinMode(PED_AMBER, OUTPUT);
pinMode(PED_RED , OUTPUT);
pinMode(CAR_GREEN, OUTPUT);
pinMode(CAR_AMBER, OUTPUT);
pinMode(CAR_RED , OUTPUT);
pinMode(EXIT_GREEN, OUTPUT);
pinMode(EXIT_AMBER, OUTPUT);
pinMode(EXIT_RED , OUTPUT);
pinMode(GATE_WARN , OUTPUT);
pinMode(PEDESTRIAN_LDR1, INPUT_PULLUP);
pinMode(PEDESTRIAN_LDR2, INPUT_PULLUP);
pinMode(GATE_BUTTON , INPUT_PULLUP);
gate.attach(GATE_SERVO);
gate.write(pos); // Set gate to position 0
setState(cars_only);
pinMode(0 , OUTPUT);
pinMode(1 , OUTPUT);
pinMode(7 , OUTPUT);
digitalWrite(0, LOW);
digitalWrite(1, LOW);
digitalWrite(7, HIGH);
}
void loop() {
int gate_button = digitalRead(GATE_BUTTON);
if (pedestrians == proceed) {
return; // Ignore all other inputs as pedestrian is in complete mode.
}
int ped_ldr = analogRead(PEDESTRIAN_LDR1);
int ped_ldr2 = analogRead(PEDESTRIAN_LDR2);
if (ped_ldr < 140 || ped_ldr2 < 85) {
Serial.println("Stopping traffic, setting to pedestrians");
setState(pedestrians_only);
delay(10000);
setState(cars_only);
}
if (gate_button == HIGH) { // PULL-UP
Serial.println("Gate will now open...");
setState(gate_only);
setState(cars_only);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment