/* Prac Test 2 (DEEC1)
* Name: [WEE XIN ING]
* Room: [06-03-04]
* Date: 25-July-2025
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
unsigned long previousMillis = 0;
int interval = 2000;
int redLedState = LOW;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* hostname = "broker.hivemq.com";
const int portnum = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
const char* espClientName = "<1657276R>";
// State variables for voltage limit handling
bool voltageExceeded85 = false;
bool voltageDroppedBelow83 = false;
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println();
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("Given IP by the router to ESP32 is ");
Serial.println(WiFi.localIP());
}
void connectMQTT() {
while (!client.connected()) {
Serial.println("Connecting to MQTT ...");
if (client.connect(espClientName)) {
Serial.println("Connected");
MQTTSubscribe();
} else {
Serial.print("Failed with state ");
Serial.print(client.state());
delay(2000);
}
}
}
void callback(const char* topic, byte* payload, unsigned int length) {
String message;
Serial.print("Message received in topic: ");
Serial.print(topic);
Serial.print(" length is: ");
Serial.println(length);
Serial.print("Data received from broker: ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
message += (char)payload[i];
}
Serial.println();
// Handle MQTT messages for yellow LED control
if (String(topic) == "1657276R/LED") { // TODO 1a: check for received topic
// TODO 1b: Turn on/off the yellow LED based on payload
if (message == "High") {
digitalWrite(18, HIGH);
}
else if (message == "Low") {
digitalWrite(18, LOW);
}
}
}
void MQTTSubscribe() {
client.subscribe("1657276R/LED"); // TODO 2a: Subscribe topic
}
void setup_MQTT() {
client.setServer(hostname, portnum); // TODO 2b: Setup MQTT broker and port
client.setCallback(callback); // TODO 2c: Setup callback
}
void setup() {
Serial.begin(115200);
// Pin configuration
pinMode(18, OUTPUT); // Yellow LED
pinMode(19, OUTPUT); // Red LED
pinMode(36, INPUT); // Potentiometer (VP)
// Initialize WiFi and MQTT
setup_wifi();
setup_MQTT();
}
void loop() {
if (!client.connected()) {
connectMQTT();
}
client.loop();
// Perform all actions every 2 seconds
unsigned long currentMillis = millis(); // TODO 3a: Get current milliseconds
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMilli; // TODO 3b: Update previousMillis
if (redLedState == LOW) {
redLedState = HIGH;
digitalWrite(19, HIGH); // Turn on red LED
} else {
redLedState = LOW;
digitalWrite(19, LOW); // Turn off red LED
}
int adcValue = analogRead(36);
float voltage = (adcValue / 4095) * val; // TODO 4a: Convert ADC value to voltage
char voltageStr[10];
dtostrf(voltage, 1, 2, voltageStr); // Convert float to string with 2 decimal places
client.publish("1657276R/VAL", voltageStr); // TODO 4b: Publish the voltage
float maxVoltage = 5.0; // Maximum voltage (5V)
float threshold85 = 0.85 * maxVoltage; // 85% of maximum voltage
float threshold83 = 0.83 * maxVoltage; // 83% of maximum voltage
if (voltage > threshold85 && !voltageExceeded85) {
client.publish("1657276R/VAL/LIMIT", "App"); // TODO 5a: limit violation alarm
voltageExceeded85 = true;
voltageDroppedBelow83 = false; // Reset the drop state
} else if (voltage < threshold83 && !voltageDroppedBelow83) {
client.publish("1657276R/VAL/LIMIT", "Dis); // TODO 5b: limit violation alarm
voltageDroppedBelow83 = true;
voltageExceeded85 = false; // Reset the exceed state
}
}
}