#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT Broker settings
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_user = "";
const char* mqtt_password = "";
const char* client_id = "ESP32_Industrial_IoT_M2";
// Device ID for MQTT topics
const char* device_id = "industrial_iot_m2";
// Pin definitions
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define DS18B20_PIN 5
#define PRESSURE_PIN A0 // GPIO36 - Potentiometer 1
#define FLOW_RATE_PIN A3 // GPIO39 - Potentiometer 2
#define VIBRATION_PIN A6 // GPIO34 - Potentiometer 3
#define LIGHT_PIN A7 // GPIO35 - LDR sensor
#define MOTION_PIN 13
#define BUZZER_PIN 19
#define EMERGENCY_BTN_PIN 15
#define START_BTN_PIN 32
// Relay pins
#define MOTOR_RELAY_PIN 25
#define PUMP_RELAY_PIN 26
#define VALVE_RELAY_PIN 27
#define COOLING_RELAY_PIN 14
// LED pins
#define SYSTEM_LED_PIN 2
#define ALERT_LED_PIN 16
#define PROCESS_LED_PIN 17
#define POWER_LED_PIN 18
// Sensor objects
DHT dht(DHT_PIN, DHT_TYPE);
OneWire oneWire(DS18B20_PIN);
DallasTemperature ds18b20(&oneWire);
// Initialize LCD with correct I2C address for Wokwi (usually 0x27)
LiquidCrystal_I2C lcd(0x27, 16, 2);
WiFiClient espClient;
PubSubClient client(espClient);
// System state variables
struct SystemState {
bool systemOnline = false;
bool emergencyStop = false;
bool motorRunning = false;
bool pumpRunning = false;
bool valveOpen = false;
bool coolingActive = false;
bool alertActive = false;
unsigned long lastSensorUpdate = 0;
unsigned long lastStatusUpdate = 0;
unsigned long lastDisplayUpdate = 0;
unsigned long lastPageChange = 0;
int displayPage = 0;
} systemState;
// Sensor data structure
struct SensorData {
float envTemperature = 24.5; // Default values for testing
float envHumidity = 65.0;
float processTemperature = 28.3;
float systemPressure = 45.2;
float flowRate = 12.8;
float vibrationLevel = 15.4;
int lightLevel = 78;
bool motionDetected = false;
} sensorData;
// MQTT Topics
const char* TOPICS_SENSOR_ENV_TEMP = "industrial/sensors/environment/temperature";
const char* TOPICS_SENSOR_ENV_HUM = "industrial/sensors/environment/humidity";
const char* TOPICS_SENSOR_PROCESS_TEMP = "industrial/sensors/process/temperature";
const char* TOPICS_SENSOR_PRESSURE = "industrial/sensors/system/pressure";
const char* TOPICS_SENSOR_FLOW = "industrial/sensors/system/flowrate";
const char* TOPICS_SENSOR_VIBRATION = "industrial/sensors/system/vibration";
const char* TOPICS_SENSOR_LIGHT = "industrial/sensors/environment/light";
const char* TOPICS_SENSOR_MOTION = "industrial/sensors/security/motion";
const char* TOPICS_CONTROL_MOTOR = "industrial/control/motor/command";
const char* TOPICS_CONTROL_PUMP = "industrial/control/pump/command";
const char* TOPICS_CONTROL_VALVE = "industrial/control/valve/command";
const char* TOPICS_CONTROL_COOLING = "industrial/control/cooling/command";
const char* TOPICS_CONTROL_SYSTEM = "industrial/control/system/command";
const char* TOPICS_STATUS_SYSTEM = "industrial/status/system";
const char* TOPICS_STATUS_ALERTS = "industrial/status/alerts";
const char* TOPICS_STATUS_RELAYS = "industrial/status/relays";
const char* TOPICS_DASHBOARD_DATA = "industrial/dashboard/data";
// LCD Display status
bool lcdInitialized = false;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("=== Industrial IoT System Starting ===");
// Initialize pins
initializePins();
// Initialize LCD FIRST with improved method
initializeLCD();
// Show startup message on LCD
if (lcdInitialized) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Industrial IoT");
lcd.setCursor(0, 1);
lcd.print("Starting...");
delay(2000);
}
// Initialize sensors
dht.begin();
ds18b20.begin();
// Check DS18B20 sensor detection
Serial.print("Checking DS18B20 sensor...");
int deviceCount = ds18b20.getDeviceCount();
if (deviceCount == 0) {
Serial.println("ERROR: No DS18B20 sensors found!");
Serial.println("Check wiring and pull-up resistor (4.7kΩ)");
} else {
Serial.println("Found " + String(deviceCount) + " DS18B20 sensor(s)");
}
// Connect to WiFi
connectToWiFi();
// Setup MQTT
client.setServer(mqtt_server, mqtt_port);
client.setCallback(mqttCallback);
// Connect to MQTT
connectToMQTT();
// Subscribe to control topics
subscribeToControlTopics();
// Initialize system
systemState.systemOnline = true;
systemState.motorRunning = true; // Set motor ON for testing
digitalWrite(SYSTEM_LED_PIN, HIGH);
digitalWrite(POWER_LED_PIN, HIGH);
digitalWrite(MOTOR_RELAY_PIN, HIGH);
digitalWrite(PROCESS_LED_PIN, HIGH);
if (lcdInitialized) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Online");
lcd.setCursor(0, 1);
lcd.print("Ready for Ops");
delay(2000);
}
Serial.println("Industrial IoT System Initialized");
Serial.println("LCD Status: " + String(lcdInitialized ? "OK" : "FAILED"));
}
void loop() {
// Maintain MQTT connection
if (!client.connected()) {
connectToMQTT();
}
client.loop();
// Check emergency button
checkEmergencyButton();
// Check start button
checkStartButton();
// Read sensors (every 2 seconds)
if (millis() - systemState.lastSensorUpdate > 2000) {
readAllSensors();
publishSensorData();
systemState.lastSensorUpdate = millis();
}
// Update system status (every 5 seconds)
if (millis() - systemState.lastStatusUpdate > 5000) {
publishSystemStatus();
publishDashboardData();
systemState.lastStatusUpdate = millis();
}
// Update LCD display (every 1 second) - CRITICAL FIX
if (millis() - systemState.lastDisplayUpdate > 1000) {
updateDisplay();
systemState.lastDisplayUpdate = millis();
}
// Process system logic
processSystemLogic();
delay(100);
}
// IMPROVED LCD INITIALIZATION
void initializeLCD() {
Serial.println("Initializing LCD...");
// Try multiple I2C addresses commonly used in Wokwi
byte addresses[] = {0x27, 0x3F, 0x26, 0x20};
for (int i = 0; i < 4; i++) {
Serial.print("Trying LCD I2C address: 0x");
Serial.println(addresses[i], HEX);
// Reinitialize LCD object with current address
lcd = LiquidCrystal_I2C(addresses[i], 16, 2);
// Initialize LCD
lcd.init();
delay(100);
lcd.backlight();
delay(100);
// Test LCD with simple display
lcd.clear();
delay(50);
lcd.setCursor(0, 0);
lcd.print("Testing LCD...");
delay(500);
// If we reach here without crashes, assume it's working
lcdInitialized = true;
Serial.println("LCD initialized successfully at address 0x" + String(addresses[i], HEX));
// Show success message
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LCD Found!");
lcd.setCursor(0, 1);
lcd.print("Addr: 0x" + String(addresses[i], HEX));
delay(2000);
lcd.clear();
return;
}
if (!lcdInitialized) {
Serial.println("ERROR: LCD not found at any I2C address");
Serial.println("Check wiring: SDA->D21, SCL->D22, VCC->3.3V, GND->GND");
Serial.println("In Wokwi: Make sure LCD pins attribute is set to 'i2c'");
}
}
void initializePins() {
// Input pins
pinMode(EMERGENCY_BTN_PIN, INPUT_PULLUP);
pinMode(START_BTN_PIN, INPUT_PULLUP);
pinMode(MOTION_PIN, INPUT);
// Output pins
pinMode(MOTOR_RELAY_PIN, OUTPUT);
pinMode(PUMP_RELAY_PIN, OUTPUT);
pinMode(VALVE_RELAY_PIN, OUTPUT);
pinMode(COOLING_RELAY_PIN, OUTPUT);
pinMode(SYSTEM_LED_PIN, OUTPUT);
pinMode(ALERT_LED_PIN, OUTPUT);
pinMode(PROCESS_LED_PIN, OUTPUT);
pinMode(POWER_LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initialize outputs to OFF
digitalWrite(MOTOR_RELAY_PIN, LOW);
digitalWrite(PUMP_RELAY_PIN, LOW);
digitalWrite(VALVE_RELAY_PIN, LOW);
digitalWrite(COOLING_RELAY_PIN, LOW);
digitalWrite(SYSTEM_LED_PIN, LOW);
digitalWrite(ALERT_LED_PIN, LOW);
digitalWrite(PROCESS_LED_PIN, LOW);
digitalWrite(POWER_LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
}
void connectToWiFi() {
if (lcdInitialized) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Connecting WiFi");
}
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Connected to WiFi. IP address: ");
Serial.println(WiFi.localIP());
if (lcdInitialized) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi Connected");
lcd.setCursor(0, 1);
lcd.print(WiFi.localIP());
delay(2000);
}
}
void connectToMQTT() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect(client_id, mqtt_user, mqtt_password)) {
Serial.println("connected");
// Publish connection status
String statusMsg = "{\"status\":\"connected\",\"timestamp\":" + String(millis()) + "}";
client.publish(TOPICS_STATUS_SYSTEM, statusMsg.c_str());
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void subscribeToControlTopics() {
client.subscribe(TOPICS_CONTROL_MOTOR);
client.subscribe(TOPICS_CONTROL_PUMP);
client.subscribe(TOPICS_CONTROL_VALVE);
client.subscribe(TOPICS_CONTROL_COOLING);
client.subscribe(TOPICS_CONTROL_SYSTEM);
Serial.println("Subscribed to control topics");
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println("MQTT Message received [" + String(topic) + "]: " + message);
// Parse JSON command
DynamicJsonDocument doc(256);
deserializeJson(doc, message);
String command = doc["command"];
bool state = doc["state"];
// Process control commands
if (String(topic) == TOPICS_CONTROL_MOTOR) {
controlMotor(state);
} else if (String(topic) == TOPICS_CONTROL_PUMP) {
controlPump(state);
} else if (String(topic) == TOPICS_CONTROL_VALVE) {
controlValve(state);
} else if (String(topic) == TOPICS_CONTROL_COOLING) {
controlCooling(state);
} else if (String(topic) == TOPICS_CONTROL_SYSTEM) {
if (command == "start") {
startSystem();
} else if (command == "stop") {
stopSystem();
} else if (command == "emergency_stop") {
emergencyStop();
}
}
}
void readAllSensors() {
// Read DHT22 (Environment)
float tempReading = dht.readTemperature();
float humReading = dht.readHumidity();
if (!isnan(tempReading)) sensorData.envTemperature = tempReading;
if (!isnan(humReading)) sensorData.envHumidity = humReading;
// Read DS18B20 (Process Temperature)
ds18b20.requestTemperatures();
float processTemp = ds18b20.getTempCByIndex(0);
if (processTemp != DEVICE_DISCONNECTED_C && processTemp != -127.0) {
sensorData.processTemperature = processTemp;
}
// Read analog sensors (mapped to appropriate ranges)
sensorData.systemPressure = map(analogRead(PRESSURE_PIN), 0, 4095, 0, 1000) / 10.0; // 0-100 bar
sensorData.flowRate = map(analogRead(FLOW_RATE_PIN), 0, 4095, 0, 500) / 10.0; // 0-50 L/min
sensorData.vibrationLevel = map(analogRead(VIBRATION_PIN), 0, 4095, 0, 1000) / 10.0; // 0-100 Hz
sensorData.lightLevel = map(analogRead(LIGHT_PIN), 0, 4095, 0, 100); // 0-100%
// Read digital sensors
sensorData.motionDetected = digitalRead(MOTION_PIN);
// Debug output for sensor values
Serial.println("=== Sensor Readings ===");
Serial.println("Env Temp: " + String(sensorData.envTemperature, 1) + "°C");
Serial.println("Env Humidity: " + String(sensorData.envHumidity, 0) + "%");
Serial.println("Process Temp: " + String(sensorData.processTemperature, 1) + "°C");
Serial.println("Pressure: " + String(sensorData.systemPressure, 1) + " bar");
Serial.println("Flow Rate: " + String(sensorData.flowRate, 1) + " L/min");
Serial.println("Vibration: " + String(sensorData.vibrationLevel, 1) + " Hz");
Serial.println("Light Level: " + String(sensorData.lightLevel) + "%");
Serial.println("Motion: " + String(sensorData.motionDetected ? "Detected" : "None"));
Serial.println("========================");
}
void publishSensorData() {
// Publish individual sensor readings
client.publish(TOPICS_SENSOR_ENV_TEMP, String(sensorData.envTemperature, 2).c_str());
client.publish(TOPICS_SENSOR_ENV_HUM, String(sensorData.envHumidity, 2).c_str());
client.publish(TOPICS_SENSOR_PROCESS_TEMP, String(sensorData.processTemperature, 2).c_str());
client.publish(TOPICS_SENSOR_PRESSURE, String(sensorData.systemPressure, 2).c_str());
client.publish(TOPICS_SENSOR_FLOW, String(sensorData.flowRate, 2).c_str());
client.publish(TOPICS_SENSOR_VIBRATION, String(sensorData.vibrationLevel, 2).c_str());
client.publish(TOPICS_SENSOR_LIGHT, String(sensorData.lightLevel).c_str());
client.publish(TOPICS_SENSOR_MOTION, sensorData.motionDetected ? "true" : "false");
}
void publishSystemStatus() {
DynamicJsonDocument doc(512);
doc["system_online"] = systemState.systemOnline;
doc["emergency_stop"] = systemState.emergencyStop;
doc["motor_running"] = systemState.motorRunning;
doc["pump_running"] = systemState.pumpRunning;
doc["valve_open"] = systemState.valveOpen;
doc["cooling_active"] = systemState.coolingActive;
doc["alert_active"] = systemState.alertActive;
doc["timestamp"] = millis();
String output;
serializeJson(doc, output);
client.publish(TOPICS_STATUS_SYSTEM, output.c_str());
}
void publishDashboardData() {
DynamicJsonDocument doc(1024);
// Sensor data
doc["sensors"]["env_temperature"] = sensorData.envTemperature;
doc["sensors"]["env_humidity"] = sensorData.envHumidity;
doc["sensors"]["process_temperature"] = sensorData.processTemperature;
doc["sensors"]["system_pressure"] = sensorData.systemPressure;
doc["sensors"]["flow_rate"] = sensorData.flowRate;
doc["sensors"]["vibration_level"] = sensorData.vibrationLevel;
doc["sensors"]["light_level"] = sensorData.lightLevel;
doc["sensors"]["motion_detected"] = sensorData.motionDetected;
// System status
doc["status"]["system_online"] = systemState.systemOnline;
doc["status"]["emergency_stop"] = systemState.emergencyStop;
doc["status"]["motor_running"] = systemState.motorRunning;
doc["status"]["pump_running"] = systemState.pumpRunning;
doc["status"]["valve_open"] = systemState.valveOpen;
doc["status"]["cooling_active"] = systemState.coolingActive;
doc["status"]["alert_active"] = systemState.alertActive;
doc["timestamp"] = millis();
String output;
serializeJson(doc, output);
client.publish(TOPICS_DASHBOARD_DATA, output.c_str());
}
void controlMotor(bool state) {
if (!systemState.emergencyStop && systemState.systemOnline) {
systemState.motorRunning = state;
digitalWrite(MOTOR_RELAY_PIN, state ? HIGH : LOW);
digitalWrite(PROCESS_LED_PIN, state ? HIGH : LOW);
Serial.println("Motor " + String(state ? "ON" : "OFF"));
// Publish relay status
publishRelayStatus();
}
}
void controlPump(bool state) {
if (!systemState.emergencyStop && systemState.systemOnline) {
systemState.pumpRunning = state;
digitalWrite(PUMP_RELAY_PIN, state ? HIGH : LOW);
Serial.println("Pump " + String(state ? "ON" : "OFF"));
publishRelayStatus();
}
}
void controlValve(bool state) {
if (!systemState.emergencyStop && systemState.systemOnline) {
systemState.valveOpen = state;
digitalWrite(VALVE_RELAY_PIN, state ? HIGH : LOW);
Serial.println("Valve " + String(state ? "OPEN" : "CLOSED"));
publishRelayStatus();
}
}
void controlCooling(bool state) {
if (!systemState.emergencyStop && systemState.systemOnline) {
systemState.coolingActive = state;
digitalWrite(COOLING_RELAY_PIN, state ? HIGH : LOW);
Serial.println("Cooling " + String(state ? "ON" : "OFF"));
publishRelayStatus();
}
}
void publishRelayStatus() {
DynamicJsonDocument doc(256);
doc["motor"] = systemState.motorRunning;
doc["pump"] = systemState.pumpRunning;
doc["valve"] = systemState.valveOpen;
doc["cooling"] = systemState.coolingActive;
doc["timestamp"] = millis();
String output;
serializeJson(doc, output);
client.publish(TOPICS_STATUS_RELAYS, output.c_str());
}
void checkEmergencyButton() {
static bool lastEmergencyState = HIGH;
bool currentState = digitalRead(EMERGENCY_BTN_PIN);
if (lastEmergencyState == HIGH && currentState == LOW) {
emergencyStop();
}
lastEmergencyState = currentState;
}
void checkStartButton() {
static bool lastStartState = HIGH;
bool currentState = digitalRead(START_BTN_PIN);
if (lastStartState == HIGH && currentState == LOW) {
if (systemState.emergencyStop) {
resetEmergencyStop();
} else {
startSystem();
}
}
lastStartState = currentState;
}
void emergencyStop() {
systemState.emergencyStop = true;
systemState.systemOnline = false;
// Turn off all relays
digitalWrite(MOTOR_RELAY_PIN, LOW);
digitalWrite(PUMP_RELAY_PIN, LOW);
digitalWrite(VALVE_RELAY_PIN, LOW);
digitalWrite(COOLING_RELAY_PIN, LOW);
// Update states
systemState.motorRunning = false;
systemState.pumpRunning = false;
systemState.valveOpen = false;
systemState.coolingActive = false;
// Activate alert
systemState.alertActive = true;
digitalWrite(ALERT_LED_PIN, HIGH);
digitalWrite(SYSTEM_LED_PIN, LOW);
// Sound buzzer
for (int i = 0; i < 5; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
delay(200);
}
Serial.println("EMERGENCY STOP ACTIVATED");
// Publish emergency status
String alertMsg = "{\"type\":\"emergency_stop\",\"active\":true,\"timestamp\":" + String(millis()) + "}";
client.publish(TOPICS_STATUS_ALERTS, alertMsg.c_str());
publishSystemStatus();
}
void resetEmergencyStop() {
systemState.emergencyStop = false;
systemState.alertActive = false;
digitalWrite(ALERT_LED_PIN, LOW);
Serial.println("Emergency stop reset");
String alertMsg = "{\"type\":\"emergency_stop\",\"active\":false,\"timestamp\":" + String(millis()) + "}";
client.publish(TOPICS_STATUS_ALERTS, alertMsg.c_str());
}
void startSystem() {
if (!systemState.emergencyStop) {
systemState.systemOnline = true;
digitalWrite(SYSTEM_LED_PIN, HIGH);
Serial.println("System started");
publishSystemStatus();
}
}
void stopSystem() {
systemState.systemOnline = false;
// Turn off all relays
controlMotor(false);
controlPump(false);
controlValve(false);
controlCooling(false);
digitalWrite(SYSTEM_LED_PIN, LOW);
digitalWrite(PROCESS_LED_PIN, LOW);
Serial.println("System stopped");
publishSystemStatus();
}
void processSystemLogic() {
// Auto-cooling based on process temperature
if (sensorData.processTemperature > 50.0 && !systemState.coolingActive && systemState.systemOnline) {
controlCooling(true);
} else if (sensorData.processTemperature < 45.0 && systemState.coolingActive) {
controlCooling(false);
}
// Alert conditions
bool alertCondition = (sensorData.processTemperature > 60.0) ||
(sensorData.systemPressure > 80.0) ||
(sensorData.vibrationLevel > 80.0);
if (alertCondition && !systemState.alertActive && !systemState.emergencyStop) {
systemState.alertActive = true;
digitalWrite(ALERT_LED_PIN, HIGH);
// Publish alert
String alertMsg = "{\"type\":\"system_alert\",\"active\":true,\"timestamp\":" + String(millis()) + "}";
client.publish(TOPICS_STATUS_ALERTS, alertMsg.c_str());
} else if (!alertCondition && systemState.alertActive) {
systemState.alertActive = false;
digitalWrite(ALERT_LED_PIN, LOW);
String alertMsg = "{\"type\":\"system_alert\",\"active\":false,\"timestamp\":" + String(millis()) + "}";
client.publish(TOPICS_STATUS_ALERTS, alertMsg.c_str());
}
}
// FIXED AND IMPROVED DISPLAY FUNCTION
void updateDisplay() {
// i am checking if LCD is initialized
if (!lcdInitialized) {
Serial.println("LCD not initialized, skipping display update");
return;
}
// Changing display page every 3 seconds
if (millis() - systemState.lastPageChange > 3000) {
systemState.displayPage = (systemState.displayPage + 1) % 4;
systemState.lastPageChange = millis();
Serial.println("Switching to display page: " + String(systemState.displayPage));
}
// Clear display and update based on current page
lcd.clear();
delay(10); // Small delay after clear
switch (systemState.displayPage) {
case 0: // Environmental Data
lcd.setCursor(0, 0);
lcd.print("Env: " + String(sensorData.envTemperature, 1) + "C " + String(sensorData.envHumidity, 0) + "%");
lcd.setCursor(0, 1);
lcd.print("Proc: " + String(sensorData.processTemperature, 1) + "C");
Serial.println("LCD Page 0: Environmental Data");
break;
case 1: // System Parameters
lcd.setCursor(0, 0);
lcd.print("Press: " + String(sensorData.systemPressure, 1) + " bar");
lcd.setCursor(0, 1);
lcd.print("Flow: " + String(sensorData.flowRate, 1) + " L/min");
Serial.println("LCD Page 1: System Parameters");
break;
case 2: // Analysis Data
lcd.setCursor(0, 0);
lcd.print("Vib: " + String(sensorData.vibrationLevel, 1) + " Hz");
lcd.setCursor(0, 1);
lcd.print("Light: " + String(sensorData.lightLevel) + "%");
Serial.println("LCD Page 2: Analysis Data");
break;
case 3: // System Status
lcd.setCursor(0, 0);
lcd.print(systemState.systemOnline ? "System: ONLINE" : "System: OFFLINE");
lcd.setCursor(0, 1);
if (systemState.emergencyStop) {
lcd.print("EMERGENCY STOP!");
} else {
lcd.print("M:" + String(systemState.motorRunning ? "ON" : "OFF") +
" P:" + String(systemState.pumpRunning ? "ON" : "OFF"));
}
Serial.println("LCD Page 3: System Status");
break;
}
// Debug output
Serial.println("Display updated - Page " + String(systemState.displayPage));
}🏭 INDUSTRIAL IoT PROCESS CONTROL & ANALYTICS 🏭
📊 SENSOR ARRAY
⚙️ CONTROL SYSTEMS
🚦 STATUS INDICATORS
DHT22
🌡️ Environment
Temp/Humidity
DS18B20
🔥 Process
Temperature
⚡ System
Pressure
💧 Flow Rate
Monitor
📳 Vibration
Analyzer
☀️ Light
Sensor
🚶 Motion
Detector
🔧 Motor
Controller
⛽ Pump
System
🚰 Valve
Control
🌀 Cooling
System
✅ System
Online
⚠️ Alert
Status
🔄 Process
Active
⚡ Power
Status
🛑 Emergency
Stop
▶️ System
Start
🚨 Alarm
Buzzer
🖥️ SYSTEM DISPLAY