0% found this document useful (0 votes)
32 views11 pages

ESP32 MQTT Sensor System

The document is a code for an IoT system using an ESP32 microcontroller that connects to WiFi and MQTT for sensor data transmission. It integrates various sensors including DHT for temperature and humidity, MQ-2 for gas detection, and ultrasonic for distance measurement, along with an OLED display and a 7-segment display. The system allows for user interaction through serial input and button presses to control LED states, display graphs, and unlock functionality with a password.

Uploaded by

pmdinh26
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views11 pages

ESP32 MQTT Sensor System

The document is a code for an IoT system using an ESP32 microcontroller that connects to WiFi and MQTT for sensor data transmission. It integrates various sensors including DHT for temperature and humidity, MQ-2 for gas detection, and ultrasonic for distance measurement, along with an OLED display and a 7-segment display. The system allows for user interaction through serial input and button presses to control LED states, display graphs, and unlock functionality with a password.

Uploaded by

pmdinh26
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 11

#include <WiFi.

h>
#include <PubSubClient.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <TM1637Display.h>
#include <ESP32Servo.h>

// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// MQTT configuration
const char* mqtt_broker = "broker.emqx.io";
const char* mqtt_user = "emqx";
const char* mqtt_pass = "public";
const int mqtt_port = 1883;

// Pin and constant definitions


#define DHTPIN 13
#define DHTTYPE DHT22
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDRESS 0x3C
#define CLK 16
#define DIO 17
#define PIN_LED 14
#define PIN_SUCCESS_LED 23
#define BUTTON_PIN 0
#define BUZZER_PIN 2
#define GAS_DOUT 34
#define GAS_AOUT 35
#define LIGHT_PIN 32
#define TRIG_PIN 18
#define ECHO_PIN 19
#define SERVO_PIN 5

// Password
const char* correctPassword = "1234";

// Initialize objects
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE);
Adafruit_SSSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
TM1637Display display7seg(CLK, DIO);
Servo servo;

// Global variables
float temperature, humidity;
bool gasDetected;
int gasValue;
int lightValue;
int tm1637Value = 0;
String inputPassword = "";
unsigned long lastUpdate = 0;
const long updateInterval = 100;
unsigned long lastSensorUpdate = 0;
const long sensorUpdateInterval = 5000;
bool lastButtonState = HIGH;
unsigned long lastButtonPress = 0;
const long debounceDelay = 200;
bool ledSwitchState = false;
bool showOLEDGasGraph = false;
bool showOLEDLightGraph = false;
unsigned long lastNotificationTime = 0;
const long notificationInterval = 60000;
float distance = 0;
bool doorState = false; // Track door state (open/closed)

// Light history for graph


#define MAX_POINTS 50
int lightHistory[MAX_POINTS];
int lightIndex = 0;

// Function declarations
void setupWiFi();
void setupMQTT();
void reconnectMQTT();
void callback(char* topic, byte* payload, unsigned int length);
void setupDHT();
void readDHT(float &temperature, float &humidity);
void setupOLED();
void setup7Segment();
void setupLED();
void updateLED(float temperature);
void setupBuzzerButton();
void checkButton();
void setupGasSensor();
void readGasSensor(bool &gasDetected, int &gasValue);
void readLightSensor(int &lightValue);
void processPassword(String password);
void resetPasswordInput();
void updateBuzzer(int gasValue, bool gasDetected);
void updateSerialPlotter();
void drawGasBarGraph(int gasValue);
void drawLightLineGraphOLED(int lightValue);
void setupServo();
void setupUltrasonic();
void readUltrasonic(float &distance);

void setup() {
Serial.begin(115200);
Serial.println("System starting");
Serial.println("Enter password, TM1637 value (0-1000), ON/OFF, OLED_GRAPH, or
OLED_LIGHT:");
Serial.println("Temperature\tHumidity\tGas\tTM1637\tGasDetected\tLight\
tDistance");

// Initialize components
setupWiFi();
setupMQTT();
setupDHT();
setupOLED();
setup7Segment();
setupLED();
setupBuzzerButton();
setupGasSensor();
setupServo();
setupUltrasonic();

// Initialize light history


for (int i = 0; i < MAX_POINTS; i++) {
lightHistory[i] = 0;
}
}

void loop() {
// Reconnect WiFi if disconnected
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected, reconnecting...");
setupWiFi();
}

// Reconnect MQTT if disconnected


if (!client.connected()) {
reconnectMQTT();
}
client.loop();

unsigned long currentMillis = millis();

// Handle Serial input


if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
Serial.print("Debug: Input = [");
Serial.print(input);
Serial.println("]");

if (input.toInt() >= 0 && input.toInt() <= 1000 && input ==


String(input.toInt())) {
tm1637Value = input.toInt();
client.publish("topic/tm1637", String(tm1637Value).c_str());
Serial.println("-------------------");
Serial.print("TM1637 value (Serial): ");
Serial.println(tm1637Value);
Serial.println("-------------------");
} else if (input == "ON" || input == "OFF") {
ledSwitchState = (input == "ON");
client.publish("topic/led_switch", ledSwitchState ? "1" : "0");
Serial.println("-------------------");
Serial.print("Switch Serial: ");
Serial.println(input);
Serial.println("-------------------");
} else if (input == "OLED_GRAPH") {
showOLEDGasGraph = !showOLEDGasGraph;
showOLEDLightGraph = false;
Serial.println("-------------------");
Serial.print("OLED gas graph display: ");
Serial.println(showOLEDGasGraph ? "ON" : "OFF");
Serial.println("-------------------");
if (!showOLEDGasGraph) resetPasswordInput();
} else if (input == "OLED_LIGHT") {
showOLEDLightGraph = !showOLEDLightGraph;
showOLEDGasGraph = false;
Serial.println("-------------------");
Serial.print("OLED light graph display: ");
Serial.println(showOLEDLightGraph ? "ON" : "OFF");
Serial.println("-------------------");
if (!showOLEDLightGraph) resetPasswordInput();
} else {
inputPassword = input;
Serial.println("-------------------");
Serial.print("Processing password (Serial): ");
Serial.println(inputPassword);
processPassword(inputPassword);
Serial.println("-------------------");
}
Serial.println("Enter password, TM1637 value (0-1000), ON/OFF, OLED_GRAPH, or
OLED_LIGHT:");
}

// Update sensors, LED, buzzer, TM1637


if (currentMillis - lastUpdate >= updateInterval) {
display7seg.showNumberDec(tm1637Value, false);
readDHT(temperature, humidity);
readGasSensor(gasDetected, gasValue);
readLightSensor(lightValue);
readUltrasonic(distance);
updateLED(temperature);
updateBuzzer(gasValue, gasDetected);
checkButton();

// Control servo based on distance


if (distance >= 99 && distance <= 101) {
servo.write(180);
Serial.println("Servo: Rotated to 180° due to distance ~100cm");
} else {
servo.write(0);
Serial.println("Servo: Rotated to 0°");
}

// Update OLED display


if (showOLEDGasGraph) {
drawGasBarGraph(gasValue);
} else if (showOLEDLightGraph) {
drawLightLineGraphOLED(lightValue);
}
lastUpdate = currentMillis;
}

// Publish sensor data to MQTT


if (currentMillis - lastSensorUpdate >= sensorUpdateInterval) {
if (!isnan(temperature) && !isnan(humidity)) {
client.publish("topic/temperature", String(temperature, 2).c_str());
client.publish("topic/humidity", String(humidity, 2).c_str());
Serial.println("MQTT Debug: Published Temperature=" + String(temperature) +
", Humidity=" + String(humidity));
} else {
Serial.println("DHT Debug: Not publishing due to invalid values");
client.publish("topic/temperature", "0");
client.publish("topic/humidity", "0");
Serial.println("MQTT Debug: Published default Temperature=0, Humidity=0");
}
if (lightValue >= 0 && lightValue <= 4095) {
client.publish("topic/gas", String(gasValue).c_str());
client.publish("topic/light", String(lightValue).c_str());
client.publish("topic/tm1637", String(tm1637Value).c_str());
client.publish("topic/led_switch", ledSwitchState ? "1" : "0");
client.publish("topic/distance", String(distance, 2).c_str());
client.publish("topic/door_state", doorState ? "Open" : "Closed");
Serial.println("MQTT Debug: Published Gas=" + String(gasValue) +
", Light=" + String(lightValue) +
", Distance=" + String(distance));
} else {
Serial.println("Light Sensor Debug: Invalid light value: " +
String(lightValue));
client.publish("topic/light", "0");
Serial.println("MQTT Debug: Published default Light=0");
}

lastSensorUpdate = currentMillis;
}
}

void setupWiFi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}

void setupMQTT() {
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
reconnectMQTT();
// Subscribe to control topics
client.subscribe("topic/password");
client.subscribe("topic/led_switch");
client.subscribe("topic/tm1637");
}

void reconnectMQTT() {
while (!client.connected()) {
String clientId = "esp32-" + String(WiFi.macAddress());
Serial.print("Attempting MQTT connection...");
if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {
Serial.println("connected");
// Re-subscribe to topics
client.subscribe("topic/password");
client.subscribe("topic/led_switch");
client.subscribe("topic/tm1637");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
String msg;
for (unsigned int i = 0; i < length; i++) {
msg += (char)payload[i];
}
Serial.print("Message received on ");
Serial.print(topic);
Serial.print(": ");
Serial.println(msg);

if (strcmp(topic, "topic/password") == 0) {
inputPassword = msg;
inputPassword.trim();
Serial.println("-------------------");
Serial.print("Processing password (MQTT): ");
Serial.println(inputPassword);
processPassword(inputPassword);
Serial.println("-------------------");
} else if (strcmp(topic, "topic/led_switch") == 0) {
ledSwitchState = (msg == "1" || msg == "ON");
Serial.println("-------------------");
Serial.print("Switch MQTT: ");
Serial.println(ledSwitchState ? "ON" : "OFF");
Serial.println("-------------------");
} else if (strcmp(topic, "topic/tm1637") == 0) {
int value = msg.toInt();
if (value >= 0 && value <= 1000) {
tm1637Value = value;
Serial.println("-------------------");
Serial.print("TM1637 MQTT: ");
Serial.println(tm1637Value);
Serial.println("-------------------");
}
}
}

void setupDHT() {
dht.begin();
Serial.println("DHT22 initialized");
}

void readDHT(float &temperature, float &humidity) {


humidity = dht.readHumidity();
temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
temperature = humidity = 0;
} else {
Serial.print("DHT22 Debug: Temperature=");
Serial.print(temperature);
Serial.print(" C, Humidity=");
Serial.print(humidity);
Serial.println(" %");
}
}

void setupOLED() {
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
Serial.println(F("SSD1306 initialization failed"));
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Enter your password:");
display.display();
Serial.println("OLED initialized");
}

void setup7Segment() {
display7seg.setBrightness(0x0f);
Serial.println("TM1637 initialized");
}

void setupLED() {
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_SUCCESS_LED, OUTPUT);
analogWrite(PIN_LED, 0);
digitalWrite(PIN_SUCCESS_LED, LOW);
Serial.println("LED initialized");
}

void updateLED(float temperature) {


int brightness = ledSwitchState ? 255 : 0;
analogWrite(PIN_LED, brightness);
Serial.print("LED Debug: Switch=");
Serial.print(ledSwitchState ? "ON" : "OFF");
Serial.print(", Brightness=");
Serial.println(brightness);
}

void setupBuzzerButton() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
noTone(BUZZER_PIN);
Serial.println("Buzzer and Button initialized");
}

void checkButton() {
bool currentButtonState = digitalRead(BUTTON_PIN);
if (currentButtonState == LOW && lastButtonState == HIGH &&
millis() - lastButtonPress > debounceDelay) {
Serial.println("Button Debug: Pressed, resetting password input");
resetPasswordInput();
showOLEDGasGraph = false;
showOLEDLightGraph = false;
lastButtonPress = millis();
}
lastButtonState = currentButtonState;
}

void setupGasSensor() {
pinMode(GAS_DOUT, INPUT);
Serial.println("MQ-2 gas sensor initialized");
}
void readGasSensor(bool &gasDetected, int &gasValue) {
gasDetected = digitalRead(GAS_DOUT) == LOW;
gasValue = analogRead(GAS_AOUT);
Serial.print("MQ-2 Debug: Detected=");
Serial.print(gasDetected ? "Yes" : "No");
Serial.print(", Value=");
Serial.println(gasValue);
}

void readLightSensor(int &lightValue) {


lightValue = analogRead(LIGHT_PIN);
Serial.print("Light Sensor Debug: Light=");
Serial.println(lightValue);
lightHistory[lightIndex] = lightValue;
lightIndex = (lightIndex + 1) % MAX_POINTS;
}

void processPassword(String password) {


Serial.println("Debug: processPassword called");
if (showOLEDGasGraph || showOLEDLightGraph) {
Serial.println("Debug: OLED graph active, ignoring password");
return;
}
Serial.println("-------------------");
Serial.print("Displaying password: ");
Serial.println(password);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Password: ");
display.println(password);
display.setCursor(0, 20);
if (password == correctPassword) {
display.println("Unlock successful");
display.setCursor(0, 30);
display.print("Temp: ");
display.print(temperature);
display.println(" C");
display.setCursor(0, 40);
display.print("Humidity: ");
display.print(humidity);
display.println(" %");
Serial.println("Password correct");
digitalWrite(PIN_SUCCESS_LED, HIGH);
doorState = true;
client.publish("topic/door_state", "Open");
Serial.println("MQTT Debug: Door state = Open");
} else {
display.println("Wrong password");
Serial.println("Password incorrect");
digitalWrite(PIN_SUCCESS_LED, LOW);
doorState = false;
client.publish("topic/door_state", "Closed");
Serial.println("MQTT Debug: Door state = Closed");
}
display.display();
Serial.println("-------------------");
}
void resetPasswordInput() {
inputPassword = "";
digitalWrite(PIN_SUCCESS_LED, LOW);
doorState = false;
client.publish("topic/door_state", "Closed");
if (showOLEDGasGraph || showOLEDLightGraph) return;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Enter your password:");
display.display();
Serial.println("Password input reset");
Serial.println("Enter password, TM1637 value (0-1000), ON/OFF, OLED_GRAPH, or
OLED_LIGHT:");
}

void updateBuzzer(int gasValue, bool gasDetected) {


if (gasDetected) {
int frequency = map(gasValue, 0, 4095, 500, 2000);
tone(BUZZER_PIN, frequency);
Serial.print("Buzzer Debug: Gas value=");
Serial.print(gasValue);
Serial.print(", Frequency=");
Serial.println(frequency);

unsigned long currentMillis = millis();


if (currentMillis - lastNotificationTime >= notificationInterval) {
String alert = "Alert: Gas detected! Value: " + String(gasValue);
client.publish("topic/gas_alert", alert.c_str());
Serial.println("Published gas alert: " + alert);
lastNotificationTime = currentMillis;
}
} else {
noTone(BUZZER_PIN);
Serial.println("Buzzer Debug: No gas detected, buzzer off");
}
}

void updateSerialPlotter() {
Serial.print(temperature);
Serial.print("\t");
Serial.print(humidity);
Serial.print("\t");
Serial.print(gasValue);
Serial.print("\t");
Serial.print(tm1637Value);
Serial.print("\t");
Serial.print(gasDetected ? 1 : 0);
Serial.print("\t");
Serial.print(lightValue);
Serial.print("\t");
Serial.println(distance);
}

void drawGasBarGraph(int gasValue) {


display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Gas Value Graph");
const int graphHeight = 32;
const int graphWidth = 100;
const int graphX = 10;
const int graphY = SCREEN_HEIGHT - graphHeight - 5;
int barWidth = 10;
int maxGas = 4095;
int barHeight = map(gasValue, 0, maxGas, 0, graphHeight);
display.fillRect(graphX, graphY + (graphHeight - barHeight), barWidth, barHeight,
SSD1306_WHITE);
display.setCursor(graphX, graphY - 10);
display.print("Gas: ");
display.print(gasValue);
display.display();
}

void drawLightLineGraphOLED(int lightValue) {


display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Light Graph");

const int graphHeight = 32;


const int graphWidth = 100;
const int graphX = 10;
const int graphY = SCREEN_HEIGHT - graphHeight - 5;
int maxLight = 4095;

display.drawLine(graphX, graphY, graphX + graphWidth, graphY, SSD1306_WHITE);


display.drawLine(graphX, graphY, graphX, graphY - graphHeight, SSD1306_WHITE);

for (int i = 1; i < MAX_POINTS; i++) {


int x0 = graphX + (i - 1) * graphWidth / (MAX_POINTS - 1);
int x1 = graphX + i * graphWidth / (MAX_POINTS - 1);
int y0 = graphY - map(lightHistory[(lightIndex - MAX_POINTS + i - 1 +
MAX_POINTS) % MAX_POINTS], 0, maxLight, 0, graphHeight);
int y1 = graphY - map(lightHistory[(lightIndex - MAX_POINTS + i + MAX_POINTS) %
MAX_POINTS], 0, maxLight, 0, graphHeight);
display.drawLine(x0, y0, x1, y1, SSD1306_WHITE);
}

display.setCursor(graphX, graphY - 10);


display.print("Light: ");
display.print(lightValue);
display.display();
}

void setupServo() {
servo.attach(SERVO_PIN);
servo.write(0);
Serial.println("Servo initialized");
}

void setupUltrasonic() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.println("HC-SR04 ultrasonic sensor initialized");
}

void readUltrasonic(float &distance) {


digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
distance = duration * 0.034 / 2;
if (distance < 2 || distance > 400) {
distance = 0;
Serial.println("HC-SR04 Debug: Invalid distance");
} else {
Serial.print("HC-SR04 Debug: Distance=");
Serial.print(distance);
Serial.println(" cm");
}
}

You might also like