/*This is an improvement on the previous code for MultiTraffic Light
Changes Made:
Removed Redundant Comments: Most comments were either too verbose or unnecessary, so I removed them to make the code more readable.
Grouped Similar Operations: Grouped related operations together to avoid repeated function calls.
Extracted Repeated Code into Functions: Created separate functions for repetitive tasks such as handling traffic light cycles, walking signal, and emergency operations.
Simplified Conditional Checks: Streamlined the conditional logic within the loop function and callback.
Improved Readability: Used meaningful function names and variable names, ensuring that the code is self-explanatory without needing extensive comments.
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "test.mosquitto.org";
const int port = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int redLightNS = 14;
const int yellowLightNS = 12;
const int greenLightNS = 13;
const int redLightEW = 25;
const int yellowLightEW = 26;
const int greenLightEW = 27;
const int crossWalkButton = 19;
const int emergencyBlueLED = 16;
const int buzzerPin = 32;
int crossWalkButtonState = 1;
int iotControl = 0;
int secondsLeft;
char clientId[50];
void setup() {
Serial.begin(115200);
randomSeed(analogRead(0));
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println(WiFi.macAddress());
client.setServer(mqttServer, port);
client.setCallback(callback);
pinMode(crossWalkButton, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(crossWalkButton), buttonPressed, FALLING);
pinMode(redLightNS, OUTPUT);
pinMode(yellowLightNS, OUTPUT);
pinMode(greenLightNS, OUTPUT);
pinMode(redLightEW, OUTPUT);
pinMode(yellowLightEW, OUTPUT);
pinMode(greenLightEW, OUTPUT);
pinMode(emergencyBlueLED, OUTPUT);
pinMode(buzzerPin, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("=== CEIS-114 ===");
}
void wifiConnect() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
void mqttReconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
long r = random(1000);
sprintf(clientId, "clientId-%ld", r);
if (client.connect(clientId)) {
Serial.print(clientId);
Serial.println(" connected");
client.subscribe("LED");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* message, unsigned int length) {
String stMessage;
for (int i = 0; i < length; i++) {
stMessage += (char)message[i];
}
if (String(topic) == "LED") {
if (stMessage == "ON") {
iotControl = 1;
} else if (stMessage == "OFF") {
iotControl = 0;
}
}
}
void loop() {
if (!client.connected()) {
mqttReconnect();
}
if (iotControl == 0) {
normalOperation();
} else {
emergencyOperation();
}
client.loop();
}
void normalOperation() {
lcd.setCursor(0, 1);
lcd.print("= Do Not Walk! =");
Serial.println(" == Do Not Walk == ");
digitalWrite(emergencyBlueLED, LOW);
if (crossWalkButtonState == 0) {
startWalk();
} else {
trafficLightCycle();
}
}
void startWalk() {
turnOffAllLights();
lcd.setCursor(0, 1);
lcd.print(" == Walk! == ");
secondsLeft = 15;
while (secondsLeft > 0) {
if (secondsLeft >= 10) {
lcd.setCursor(14, 1);
lcd.print(secondsLeft);
} else {
lcd.setCursor(14, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
lcd.print(secondsLeft);
}
blinkRedLights();
secondsLeft--;
client.loop();
if (iotControl == 1) break;
}
crossWalkButtonState = 1;
}
void trafficLightCycle() {
lightSequence(redLightNS, yellowLightNS, greenLightNS, redLightEW, yellowLightEW, greenLightEW);
delay(1000);
lightSequence(redLightEW, yellowLightEW, greenLightEW, redLightNS, yellowLightNS, greenLightNS);
delay(2000);
}
void lightSequence(int red1, int yellow1, int green1, int red2, int yellow2, int green2) {
digitalWrite(red1, HIGH);
digitalWrite(yellow1, LOW);
digitalWrite(green1, LOW);
digitalWrite(red2, HIGH);
digitalWrite(yellow2, LOW);
digitalWrite(green2, LOW);
}
void blinkRedLights() {
digitalWrite(redLightNS, HIGH);
digitalWrite(redLightEW, HIGH);
delay(500);
digitalWrite(redLightNS, LOW);
digitalWrite(redLightEW, LOW);
delay(500);
}
void turnOffAllLights() {
digitalWrite(yellowLightNS, LOW);
digitalWrite(greenLightNS, LOW);
digitalWrite(yellowLightEW, LOW);
digitalWrite(greenLightEW, LOW);
}
void emergencyOperation() {
lcd.setCursor(0, 1);
lcd.println("= Emergency! =");
Serial.println("= Emergency! =");
turnOffAllLights();
digitalWrite(redLightNS, HIGH);
digitalWrite(redLightEW, HIGH);
digitalWrite(emergencyBlueLED, HIGH);
digitalWrite(buzzerPin, HIGH);
delay(500);
digitalWrite(emergencyBlueLED, LOW);
digitalWrite(buzzerPin, LOW);
delay(500);
}
void buttonPressed() {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 20) {
crossWalkButtonState = 0;
}
lastInterruptTime = interruptTime;
}
Loading
esp32-devkit-c-v4
esp32-devkit-c-v4
led1:A
led1:C
led2:A
led2:C
led3:A
led3:C
led4:A
led4:C
led5:A
led5:C
led6:A
led6:C
led7:A
led7:C
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
bz1:1
bz1:2
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL