#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <Adafruit_Sensor.h>
// Wi-Fi credentials
const char* ssid = "husam";
const char* password = "18002859";
// MQTT broker
const char* mqtt_server = "broker.hivemq.com";
const char* topic = "sensor/data";
// DHT22 settings
#define DHTPIN 33 // DHT22 pin
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// MQ-135 settings
#define MQ135_PIN 34 // MQ-135 pin
// Calibration values (from the datasheet curve)
#define RZERO 76.63 // Clean air resistance ratio
// Dust sensor settings
#define DUST_PIN 36 // DSM501A pin
WiFiClient espClient;
PubSubClient client(espClient);
/**
* This function sets up the WiFi connection.
* It initializes the serial communication, prints the SSID of the WiFi network,
* connects to the WiFi network, and waits until the connection is established.
* Then it prints the IP address of the ESP32.
*/
void setup_wifi() {
// Delay for 10 milliseconds to allow the serial communication to stabilize
delay(10);
// Initialize the serial communication with a baud rate of 921600
Serial.begin(921600);
// Print a new line character to separate the previous output
Serial.println();
// Print the message "Connecting to " followed by the SSID of the WiFi network
Serial.print("Connecting to ");
Serial.println(ssid);
// Connect to the WiFi network using the provided SSID and password
WiFi.begin("Wokwi-GUEST");
// Wait until the connection is established
while (WiFi.status() != WL_CONNECTED) {
// Delay for 500 milliseconds before checking the connection status again
delay(500);
// Print a dot character to show the progress of the connection attempt
Serial.print(".");
}
// Print a new line character to separate the previous output
Serial.println("");
// Print the message "WiFi connected" to indicate that the connection is established
Serial.println("WiFi connected");
// Print the message "IP address: " followed by the IP address of the ESP32
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
/**
* This function attempts to reconnect to the MQTT broker until it succeeds or
* until the user cancels the operation.
*
* The function loops until the client is connected, trying to connect each time
* by calling `client.connect("ESP32Client")`. If the connection is successful,
* it prints the message "connected". If the connection fails, it prints the
* message "failed, rc=XXX try again in 5 seconds", where XXX is the error code
* returned by `client.state()`. After each failed attempt it waits for 5
* seconds before trying again.
*
* The function is called in the `loop()` function to attempt to reconnect the
* client if it is not connected.
*/
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP32Client")) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
/**
* This function is called once when the ESP32 starts up.
* It sets up the serial communication at a baud rate of 115200,
* sets up the WiFi connection, sets up the MQTT client, and
* initializes the DHT22 sensor.
*/
void setup() {
// Initialize the serial communication at a baud rate of 115200
Serial.begin(921600);
// Set up the WiFi connection
setup_wifi();
// Set up the MQTT client to connect to the specified server on port 1883
client.setServer(mqtt_server, 1883);
// Initialize the DHT22 sensor
dht.begin();
}
void loop() {
// Check if the MQTT client is not connected
if (!client.connected()) {
// Attempt to reconnect to the MQTT broker
reconnect();
}
// Keep the MQTT client connected by calling its loop function
client.loop();
// Read temperature and humidity from the DHT22 sensor
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// Read gas concentration from the MQ-135 sensor
int mq135_raw = analogRead(MQ135_PIN);
float r0 = RZERO; // Calibrate with clean air
float rs = ((1023.0 * 5.0 / mq135_raw) - 1.0) * 10000.0;
float ratio = rs / r0;
float ppm = pow(10, ((log10(ratio) - 0.45) / -0.37)); // Derived from the datasheet curve
// Read dust concentration from the DSM501A sensor
int dust_value = pulseIn(DUST_PIN, LOW);
float concentration = 0.001915 * dust_value + 0.09522; // Example calibration
// Create a JSON payload with the sensor data
String payload = "{\"temperature\":";
payload += temperature;
payload += ",\"humidity\":";
payload += humidity;
payload += ",\"gas\":";
payload += ppm;
payload += ",\"dust\":";
payload += concentration;
payload += "}";
// Print the JSON payload to the serial monitor
Serial.print("Publishing payload: ");
// Print the payload to the serial monitor
Serial.println(payload.c_str());
// Publish the payload to the MQTT topic
client.publish(topic, payload.c_str());
// Delay for 10 seconds before publishing the next data set
delay(10000); // Publish data every 10 seconds
}