//Libraries used for the LCD
#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//LCD setup
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);
//Define ALL Leds, the button and the the buzzer (R= red, G= green, Y= yellow, PED = pedestrian)
#define LED_PIN_R 4
#define LED_PIN_Y 2
#define LED_PIN_G 15
#define LED_PIN_R_PED 13
#define LED_PIN_G_PED 12
#define Button 5
#define Sound 18
int counter=0 ;
//SETUP FUNCTION
void setup() {
Serial.begin(115200);
//SETUP FOR ALL DEVICES USED
pinMode(LED_PIN_R, OUTPUT);
pinMode(LED_PIN_G, OUTPUT);
pinMode(LED_PIN_Y, OUTPUT);
pinMode(LED_PIN_R_PED, OUTPUT);
pinMode(LED_PIN_G_PED, OUTPUT);
pinMode(Sound, OUTPUT);
pinMode(Button, INPUT);
//SETUP FOR THE LCD THAT PRINTS TIME LEFT FOR EACH STATE
LCD.init();
LCD.backlight();
LCD.setCursor(0,0);
LCD.print("PEDESTRIAN:");
LCD.setCursor(0,1);
LCD.print("AUTOMOBILE:");
}
//FUNCTION TO CLOSE ALL LCDs
void close() {
digitalWrite(LED_PIN_R, LOW);
digitalWrite(LED_PIN_G, LOW);
digitalWrite(LED_PIN_Y, LOW);
digitalWrite(LED_PIN_R_PED, LOW);
digitalWrite(LED_PIN_G_PED, LOW);
}
//MOVE FUNCTION THAT CHECKS WHETHER THE BUTTON WAS PRESSED OR NOT (ALSO RANDOMLY PRESSED). IF NOT PRESSED CONTINUES ROUTINE
void PedestrianCheck(int time)
{
if(digitalRead(Button)== HIGH or random(1,7200)<=100)
{
close();
routine();
digitalWrite(Button, LOW);
}
else
{
delay(time);
}
}
//FUNCTION THAT PLAYS THE SOUND
void playTone(int frequency, int duration) {
tone(Sound, frequency, duration);
delay(duration); // Add a small delay to separate the notes
noTone(Sound); // Stop the tone
}
void playBackgroundJingle() {
// Use the tone function to create a pleasant background jingle
tone(Sound, 523); // C5
delay(25);
tone(Sound, 587); // D5
delay(25);
tone(Sound, 659); // E5
delay(25);
tone(Sound, 698); // F5
delay(25);
noTone(Sound); // Stop the tone
}
//THE JINGLE USED FOR ANNOUNCING PEDESTRIAN GREEN
void Jingle1() {
playTone(784, 150); // G5
delay(50); // Short pause
playTone(698, 150); // F5
delay(50); // Short pause
playTone(659, 150); // E5
delay(50); // Short pause
playTone(698, 150); // F5
delay(50); // Short pause
playTone(784, 150); // G5
delay(50); // Short pause
playTone(880, 150); // A5
delay(50); // Short pause
playTone(784, 300); // G5
delay(150); // Longer pause
}
//FUNCTION THAT TURNS ON TRAFFIC RED AND PEDESTRIAN GREEN, THEN TURNS ON PEDESTRIAN RED
void red() {
Jingle1();
digitalWrite(LED_PIN_R, HIGH);
digitalWrite(LED_PIN_G, LOW);
digitalWrite(LED_PIN_Y, LOW);
digitalWrite(LED_PIN_G_PED, HIGH);
LCD.setCursor(12,0);
LCD.println(11);
LCD.setCursor(12,1);
LCD.println(15);
playBackgroundJingle();
for (int i=0; i<8; i++)
{
delay(1000);
LCD.setCursor(12,0);
LCD.println(11-i-1);
LCD.setCursor(12,1);
LCD.println(15-i-1);
playBackgroundJingle();
}
for (int i = 0; i < 6; i++) {
digitalWrite(LED_PIN_G_PED, LOW);
delay(250);
digitalWrite(LED_PIN_G_PED, HIGH);
delay(250);
if(i%2==0)
{
LCD.setCursor(12,0);
LCD.println(3-i/2-1);
LCD.setCursor(12,1);
LCD.println(7-i/2-1);
}
playTone(1000, 50); // Tick sound
}
digitalWrite(LED_PIN_G_PED, LOW);
digitalWrite(LED_PIN_R_PED, HIGH);
LCD.setCursor(12, 0);
LCD.print(23);
for(int i=0; i<2; i++)
{
PedestrianCheck(1000);
LCD.setCursor(12,0);
LCD.println(23-i-1);
LCD.setCursor(12,1);
LCD.println(4-i-1);
}
for (int i = 0; i < 4; i++) {
digitalWrite(LED_PIN_R, LOW);
PedestrianCheck(250);
digitalWrite(LED_PIN_R, HIGH);
PedestrianCheck(250);
if(i%2==1)
{
LCD.setCursor(12,0);
LCD.println(21-i/2-1);
LCD.setCursor(12,1);
LCD.println(2-i/2-1);
}
playTone(700, 50); // Tick sound
}
digitalWrite(LED_PIN_R, LOW);
}
//FUNCTION THAT TURNS ON TRAFFIC YELLOW
void yellow() {
digitalWrite(LED_PIN_R, LOW);
digitalWrite(LED_PIN_G, LOW);
digitalWrite(LED_PIN_Y, HIGH);
LCD.setCursor(12,1);
LCD.println(5);
for(int i=0; i<3; i++)
{
PedestrianCheck(1000);
LCD.setCursor(12,0);
LCD.println(19-i-1);
LCD.setCursor(12,1);
LCD.println(5-i-1);
}
for (int i = 0; i < 4; i++)
{
digitalWrite(LED_PIN_Y, LOW);
PedestrianCheck(250);
digitalWrite(LED_PIN_Y, HIGH);
PedestrianCheck(250);
if(i%2==1)
{
LCD.setCursor(12,0);
LCD.println(16-i/2-1);
LCD.setCursor(12,1);
LCD.println(2-i/2-1);
}
playTone(750, 50);
}
digitalWrite(LED_PIN_Y, LOW);
}
//FUNCTION THAT TURNS ON TRAFFIC GREEN, TURNS IT OFF, TURNS TRAFFIC RED ON AND TURNS OFF PEDESTRIAN RED
void green() {
digitalWrite(LED_PIN_R, LOW);
digitalWrite(LED_PIN_G, HIGH);
digitalWrite(LED_PIN_Y, LOW);
LCD.setCursor(12,1);
LCD.println(10);
for(int i=0; i<7; i++)
{
PedestrianCheck(1000);
LCD.setCursor(12,0);
LCD.println(14-i-1);
LCD.setCursor(12,1);
LCD.println(10-i-1);
}
for (int i = 0; i < 6; i++) {
digitalWrite(LED_PIN_G, LOW);
PedestrianCheck(250);
digitalWrite(LED_PIN_G, HIGH);
PedestrianCheck(250);
if(i%2==1)
{
LCD.setCursor(12,0);
LCD.println(7-i/2-1);
LCD.setCursor(12,1);
LCD.println(3-i/2-1);
}
playTone(700, 50);
}
digitalWrite(LED_PIN_G, LOW);
digitalWrite(LED_PIN_R, HIGH);
LCD.setCursor(12,1);
LCD.println(19);
PedestrianCheck(1000);
LCD.setCursor(12,0);
LCD.println(3);
LCD.setCursor(12,1);
LCD.println(18);
PedestrianCheck(500);
for (int i = 0; i < 5; i++) {
digitalWrite(LED_PIN_R_PED, LOW);
PedestrianCheck(250);
digitalWrite(LED_PIN_R_PED, HIGH);
PedestrianCheck(250);
if(i%2==0)
{
LCD.setCursor(12,0);
LCD.println(3-i/2-1);
LCD.setCursor(12,1);
LCD.println(18-i/2-1);
}
playTone(1000, 50);
}
digitalWrite(LED_PIN_R_PED, LOW);
}
//ROUTINE OF THE TRAFFIC LIGHT
void routine()
{
counter++;
red();
yellow();
green();
close();
loop();
}
//MAIN LOOP
void loop()
{
Serial.print("\n");
Serial.print("Welcome to Traffic simulator !!! The traffic lights works automatically. If you wish to cross the street, push the button for at most 1 sec.\n");
Serial.print("The program will also turn the pedestrian green on at random times.");
routine();
delay(5000);
}