// === Susan Brown ====
// Module #7 project
//setup libraries to use MQTT
#include <WiFi.h> // WiFi header file
#include <PubSubClient.h> // MQTT publish and subscribe header file
//setup libraries to use LCD
#include <Wire.h> // I2C header file
#include <LiquidCrystal_I2C.h> //lcd
const char* ssid = "Wokwi-GUEST"; // This is the access point to your wireless network.
const char* password = ""; // This is the password to the SSID. For the smart mini router
const char* mqttServer = "test.mosquitto.org"; // This is the free MQTT broker we will use.
int port = 1883; // MQTT brokers listen to port 1883 by default
String stMac; // C string used for convenience of comparisons.
char mac[50]; // C char array used to hold the MAC address of your ESP32 microconroller
char clientId[50]; // This client ID is used to identify the user accessing the MQTT broker.
// For our test.mosquitto.org broker, we just generate a random user client ID
WiFiClient espClient; // instantiate the WiFi client object
PubSubClient client(espClient); // instantiate the publish subscribe client object
//setup to use LCD
LiquidCrystal_I2C lcd(0x27,16,2);
//North South LEDs pin configuration
const int red_LED1 = 14; // The red LED1 is wired to ESP32 board pin GPIO14
const int yellow_LED1 =12; // The yellow LED1 is wired to ESP32 board pin GPIO12
const int green_LED1 = 13; // The green LED1 is wired to ESP32 board pin GPIO13
//East West LEDs pin configuration
const int red_LED2 = 25; // The red LED2 is wired to Mega board pin GPIO25
const int yellow_LED2 = 26; // The yellow LED2 is wired to Mega board pin GPIO 26
const int green_LED2 = 27; // The green LED2 is wired to Mega board pin GPIO 27
//setup crosswalk value and button variables
const int Xw_button = 19; //Cross Walk button
bool Xw_value = false; //flag
//setup buzzer pin assignment
const int bzr=32; // GPIO32 to connect the Buzzer
//setup Blue LED
const int emergencyBlueLED = 16; // The blue LED is wired to ESP32 board pin GPIO 16
bool iotControl = false; // Variable will be used to switch between emergency and normal operations of
//Define what happens when interrupt is activated
void IRAM_ATTR crosswalkB()
{ // Cross Walk button interrupt handler
Xw_value = true;
}
void wifiConnect()
{
WiFi.mode(WIFI_STA); // set WiFi mode to STA
WiFi.begin(ssid, password); // connect WiFi using SSID and password
while (WiFi.status() != WL_CONNECTED)
{ // As long as WiFi connection is not established
delay(500); // wait half a second
Serial.print("."); // display period on serial monitor
}
}//End of wifiConnect
void mqttReconnect()
{ // If connection to MQTT broker is lost. Call this function
while (!client.connected())
{ // As long as connection is not established
Serial.print("Attempting MQTT connection..."); // Display message attempting MQTT connection
long r = random(1000); // Generate a long integer
sprintf(clientId, "clientId-%ld", r); // display client ID
if (client.connect(clientId))
{ // Is connection to MQTT broker is established
Serial.print(clientId); // Display client ID on serial monitor
Serial.println(" connected"); // Display connected message on serial monitor
client.subscribe("LED"); // Subscribe to topic LED.
}
else
{ // If connection to MQTT broker has failed
Serial.print("failed, rc="); // Display failed
Serial.print(client.state()); // Display client ID for failed connection
Serial.println(" try again in 5 seconds"); // Display message try again in 5 seconds
delay(5000); // Wait 5 seconds
}
}
}//End of mqttReconnect
void IRAM_ATTR callback(char* topic, byte* message, unsigned int length)
{ // Callback function for handling MQTT
String stMessage; // Create C string object
for (int i = 0; i < length; i++)
{ // Run a loop that will process all the characters of the MQTT message
stMessage += (char)message[i]; // Add character to the C string one at a time
}
// Check if the topic received is LED
if (String(topic) == "LED")
{
// Check if the message is ON
while (stMessage != "OFF")
{
client.loop(); // Check if new MQTT messages have been published
lcd.setCursor(0,1); // set the cursor to column 1, line 2
lcd.println("= Emergency! =");
Serial.println("= Emergency! =");
digitalWrite(yellow_LED1 , LOW); // This should turn off the Yellow LED NS
digitalWrite(green_LED1, LOW); // This should turn off the Green LED NS
digitalWrite(yellow_LED2 , LOW); // This should turn off the Yellow LED EW
digitalWrite(green_LED2, LOW); // This should turn off the Yellow LED EW
digitalWrite(red_LED1, HIGH); // This should turn on the RED LED NS
digitalWrite(red_LED2, HIGH); // This should turn on the RED Yellow LED NS
digitalWrite(emergencyBlueLED, HIGH); // This should turn on the Emergency blue LED
tone(bzr, 250); // This should turn on the active buzzer
delay(500);
digitalWrite(emergencyBlueLED, LOW); // This should turn off the Emergency blue LED
tone(bzr, 0); // This should turn off the active buzzer
delay(500);
client.loop(); // Check if new MQTT messages have been published
//Recheck for the message
//Check if the message is OFF
if (stMessage == "OFF")
{
digitalWrite(emergencyBlueLED, LOW); // This should turn off the Emergency blue LED
tone(bzr, 0); // This should turn off the active buzzer
break;
}
}//End of while ON
//Check if the message is OFF
if (stMessage == "OFF")
{
client.loop(); // Check if new MQTT messages have been published
digitalWrite(emergencyBlueLED, LOW); // This should turn off the Emergency blue LED
tone(bzr, 0); // This should turn off the active buzzer
}
} //End of if
}// End of callback interrupt
// the setup function runs once when you press reset or power the board
void setup()
{
//setup crosswalk button as input and attach the Interrupt
pinMode(Xw_button, INPUT_PULLUP); // 0=pressed, 1 = unpressed button
attachInterrupt(Xw_button, crosswalkB, RISING);
//setup Emergency button as input and attach the Interrupt
//attachInterrupt(callback, emergencyBlueLED, RISING);
//setup serial speed
Serial.begin(115200);
randomSeed(analogRead(0)); // seed the random() function
delay(10); // wait 10 milliseconds
Serial.println(); // start by skipping a line on the serial monitor
Serial.print("Connecting to "); // display message connection to
Serial.println(ssid); // display SSID name
wifiConnect(); // initiate connection to WiFi access point
Serial.println(""); // Skip a line on serial monitor
Serial.println("WiFi connected"); // display message WiFi connected
Serial.println("IP address: "); // display message IP Address
Serial.println(WiFi.localIP()); // display local IP address
Serial.println(WiFi.macAddress()); // display MAC address
stMac = WiFi.macAddress(); // copy MAC address
stMac.replace(":", "_"); // replace the underscores with colons
Serial.println(stMac); // display the cleaned up MAC address
client.setServer(mqttServer, port); // Connect to MQTT server test.mosquitto.org
client.setCallback(callback); // set callback function for handling MQTT messages
pinMode(emergencyBlueLED, OUTPUT); // initialize digital pin 16 (Blue emergency LED) as an output.
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.setCursor(0,0); //
lcd.print(" === CEIS114 ===");
//buzzer set to output
pinMode(bzr,OUTPUT);
tone(bzr, 0);
// NS pin direction set to output
pinMode(red_LED1, OUTPUT); // initialize digital pin 14 (Red LED1) as an output.
pinMode(yellow_LED1, OUTPUT); // initialize digital pin 12 (yellow LED1) as an output.
pinMode(green_LED1, OUTPUT); // initialize digital pin 13 (green LED1) as an output.
//EW pin direction set to output
pinMode(red_LED2, OUTPUT); // initialize digital pin 25(Red LED2) as an output.
pinMode(yellow_LED2, OUTPUT); // initialize digital pin 26 (yellow LED2) as an output.
pinMode(green_LED2, OUTPUT); // initialize digital pin 27 (green LED2) as an output.
}// end of setup
// this loop function runs over and over again forever – keeps the main program always running
void loop()
{
if (!client.connected())
{ // If the client is not connected to MQTT broker
mqttReconnect(); // Try reconnecting
}
else
{
//while Crosswalk button pressed
while (Xw_value == true )
{ // if crosswalk button (X-button) pressed
delay(500);
digitalWrite(yellow_LED1 , LOW); // This should turn off the YELLOW LED1
digitalWrite(green_LED1, LOW); // This should turn off the GREEN LED1
digitalWrite(yellow_LED2 , LOW); // This should turn off the YELLOW LED2
digitalWrite(green_LED2, LOW); // This should turn off the GREEN LED2
for (int i=10; i>0; i--)
{
//message to Serial Monitor
Serial.print(" Count = ");
Serial.print(i);
Serial.println(" == Walk == ");
//message to LCD
lcd.setCursor(0,1); // set the cursor to column 1, line 2
lcd.print(" == Walk == "); // Walk characters to the LCD.
lcd.print(i); // Print the count to the LCD
lcd.print(" ="); // Walk characters to the LCD.
//flash led during walk countdown
digitalWrite(red_LED1, HIGH); // This should turn on the RED LED1
digitalWrite(red_LED2, HIGH); // This should turn on the RED LED2
tone(bzr, 200);
delay(500); //wait 0.5 seconds
digitalWrite(red_LED1, LOW); // This should turn off the RED LED1
digitalWrite(red_LED2, LOW); // This should turn off the RED LED2
tone(bzr, 250);
delay(500); //wait 0.5 seconds
} // End of counter
tone(bzr, 0);
//reset before leaving the loop
Xw_value = false;
} // End of while Crosswalk Button pressed
//while Crosswalk button is not pressed
while (Xw_value == false)
{
lcd.setCursor(0,1); // set the cursor to column 1, line 2
lcd.print(" = Do Not Walk ="); // Do Not Walk characters to the LCD.
Serial.println(" == Do Not Walk == ");
// The next three lines of code turn on the red LED1
digitalWrite(red_LED1, HIGH); // This should turn on the RED LED1
digitalWrite(yellow_LED1 , LOW); // This should turn off the YELLOW LED1
digitalWrite(green_LED1, LOW); // This should turn off the GREEN LED1
delay(1000); //Extended time for Red light#1 before the Green of the other side turns ON
client.loop(); // Check if new MQTT messages have been published
// The next three lines of code turn on the red LED2
digitalWrite(red_LED2, LOW); // This should turn off the RED LED2
digitalWrite(yellow_LED2 , LOW); // This should turn off the YELLOW LED2
digitalWrite(green_LED2, HIGH); // This should turn on the GREEN LED2
delay(1000); // wait for 1 second
client.loop(); // Check if new MQTT messages have been published
// The next three lines of code turn on the red LED1
digitalWrite(red_LED1, HIGH); // This should turn on the RED LED1
digitalWrite(yellow_LED1 , LOW); // This should turn off the YELLOW LED1
digitalWrite(green_LED1, LOW); // This should turn off the GREEN LED1
// The next three lines of code turn on the red LED2
digitalWrite(red_LED2, LOW); // This should turn off the RED LED2
digitalWrite(yellow_LED2 , HIGH); // This should turn on the YELLOW LED2
digitalWrite(green_LED2, LOW); // This should turn off the GREEN LED2
delay(1000); // wait for 1 second
client.loop(); // Check if new MQTT messages have been published
// The next three lines of code turn on the red LED2
digitalWrite(red_LED2, HIGH); // This should turn on the RED LED2
digitalWrite(yellow_LED2 , LOW); // This should turn off the YELLOW LED2
digitalWrite(green_LED2, LOW); // This should turn off the GREEN LED2
delay(1000); //Extended time for Red light#2 before the Green of the other side turns
client.loop(); // Check if new MQTT messages have been published
// The next three lines of code turn on the yellow LED1
digitalWrite(red_LED1, LOW); // This should turn off the RED LED1
digitalWrite(yellow_LED1 , LOW); // This should turn off the YELLOW LED1
digitalWrite(green_LED1, HIGH); // This should turn on the GREEN LED1
delay(1000); // wait for 1 second
client.loop(); // Check if new MQTT messages have been published
// The next three lines of code turn on the yellow LED1
digitalWrite(red_LED1, LOW); // This should turn off the RED LED1
digitalWrite(yellow_LED1 , HIGH); // This should turn on the YELLOW LED1
digitalWrite(green_LED1, LOW); // This should turn off the GREEN LED1
// The next three lines of code turn on the red LED2
digitalWrite(red_LED2, HIGH); // This should turn on the RED LED2
digitalWrite(yellow_LED2 , LOW); // This should turn off the YELLOW LED2
digitalWrite(green_LED2, LOW); // This should turn off the GREEN LED2
delay(1000); // wait for 1 second
client.loop(); // Check if new MQTT messages have been published
}//End of While NOT Crosswalk
} //End of else
}//End of program