#include <LiquidCrystal.h>
#include <Servo.h>
const int TopRed = 3;
const int TopYellow = 2;
const int TopGreen = 1;
const int BottomRed = 13;
const int BottomYellow = 12;
const int BottomGreen = 11;
const int PedestrianButton = 8;
const int PedestrianStop = 4;
const int PedestrianWait = 5;
const int PedestrianGo = 6;
const int Beeper = 10;
const int TrafficMeasurer = A0;
const int LowTraffic = 341;
const int NormalTraffic = 682;
const int LCDContrastPin = 7;
const int LCDContrast = 10;
int DelayModifier;
int Rotation = 0;
bool PedestrianButtonPressed;
bool PedestrianWaiting = false;
LiquidCrystal lcd (A5, A4, A3, A2, A1, 0);
Servo TrafficDirection;
void setup () {
pinMode (TopGreen, OUTPUT);
pinMode (TopYellow, OUTPUT);
pinMode (TopRed, OUTPUT);
pinMode (BottomGreen, OUTPUT);
pinMode (BottomYellow, OUTPUT);
pinMode (BottomRed, OUTPUT);
pinMode (PedestrianGo, OUTPUT);
pinMode (PedestrianWait, OUTPUT);
pinMode (PedestrianStop, OUTPUT);
pinMode (PedestrianButton, INPUT);
pinMode (Beeper, OUTPUT);
analogWrite (LCDContrastPin, LCDContrast);
lcd.begin (16, 2);
pinMode (TrafficMeasurer, INPUT);
TrafficDirection.attach (9);
}
void CrossingCountdown () {
lcd.clear ();
digitalWrite (PedestrianGo, LOW);
for (int Countdown = 4; Countdown >= 1; Countdown--) {
lcd.clear ();
lcd.print (Countdown);
if (Countdown == 1) {
lcd.print (" second left");
} else {
lcd.print (" seconds left");
}
if (Countdown == 4 || Countdown == 2) {
digitalWrite (PedestrianStop, HIGH);
} else {
digitalWrite (PedestrianStop, LOW);
}
Beeping (500, 500);
}
digitalWrite (PedestrianGo, LOW);
}
void TwentyBeeps () {
for (int Beeps = 0; Beeps < 20; Beeps++) {
Beeping (100, 100);
}
}
void DoubleRedPedestrianCheck () {
PedestrianButtonPressed = digitalRead (PedestrianButton);
if (PedestrianButtonPressed == true || PedestrianWaiting == true) {
digitalWrite (PedestrianStop, LOW);
digitalWrite (PedestrianGo, HIGH);
lcd.clear ();
lcd.print ("GO!");
TwentyBeeps ();
CrossingCountdown ();
PedestrianWaiting = false;
} else {
lcd.clear ();
lcd.print ("Don't Walk");
digitalWrite (PedestrianStop, HIGH);
delay (DelayModifier * 2);
}
}
void PedestrianCheck () {
PedestrianButtonPressed = digitalRead (PedestrianButton);
if (PedestrianButtonPressed == true || PedestrianWaiting == true) {
digitalWrite (PedestrianStop, LOW);
digitalWrite (PedestrianWait, HIGH);
lcd.clear ();
lcd.print ("Wait");
Beeping (100, 900);
digitalWrite (PedestrianWait, LOW);
PedestrianWaiting = true;
} else {
lcd.clear ();
lcd.print ("Don't Walk");
digitalWrite (PedestrianWait, LOW);
digitalWrite (PedestrianStop, HIGH);
delay (DelayModifier);
}
}
void ChangeLights (int FirstLight, int SecondLight) {
digitalWrite (FirstLight, LOW);
digitalWrite (SecondLight, HIGH);
}
void Beeping (int FirstDelay, int SecondDelay) {
tone (Beeper, 1000);
delay (FirstDelay);
noTone (Beeper);
delay (SecondDelay);
}
void TrafficCheck () {
int TrafficAmount = analogRead (TrafficMeasurer);
if (TrafficAmount <= LowTraffic) {
DelayModifier = 500;
} else if (TrafficAmount <= NormalTraffic) {
DelayModifier = 1000;
} else {
DelayModifier = 1500;
}
}
void StartOfCode () {
digitalWrite (BottomRed, HIGH);
digitalWrite (TopRed, HIGH);
digitalWrite (PedestrianStop, HIGH);
lcd.print ("Don't Walk");
}
// Main loop
void loop () {
StartOfCode ();
TrafficCheck ();
DoubleRedPedestrianCheck ();
for (Rotation = 90; Rotation >= 0; Rotation -= 10) {
TrafficDirection.write (Rotation);
delay (15);
}
ChangeLights (BottomRed, BottomGreen);
for (int Checks = 0; Checks < 4; Checks++) {
PedestrianCheck ();
}
ChangeLights (BottomGreen, BottomYellow);
for (int Checks = 0; Checks < 2; Checks++) {
PedestrianCheck ();
}
ChangeLights (BottomYellow, BottomRed);
TrafficCheck ();
DoubleRedPedestrianCheck ();
for (Rotation = 0; Rotation <= 90; Rotation += 10) {
TrafficDirection.write (Rotation);
delay (15);
}
ChangeLights (TopRed, TopGreen);
for (int Checks = 0; Checks < 4; Checks++) {
PedestrianCheck ();
}
ChangeLights (TopGreen, TopYellow);
for (int Checks = 0; Checks < 2; Checks++) {
PedestrianCheck ();
}
ChangeLights (TopYellow, TopRed);
}