#include <Adafruit_Sensor.h> // These libraries are used for interacting with the DHT temperature and humidity sensor.
#include <DHT_U.h> // These libraries are used for interacting with the DHT temperature and humidity sensor.
#include <WiFi.h> //This library enables the ESP32 to connect to a WiFi network.
#include <PubSubClient.h> //It allows the ESP32 to communicate with an MQTT broker.
#include <ESP32Servo.h> //This library is used for controlling servo motors with the ESP32.
#include <FastLED.h> // It's a library for controlling addressable LEDs (such as WS2812) efficiently.
#include <Ultrasonic.h> // This library helps in interfacing ultrasonic distance sensors.
// Defining Pins
#define FASTLED_ESP32_SPI
#define FASTLED_ESP32_I2S
#define DHTPIN 12 //Pin connected to the DHT sensor for temperature and humidity.
#define LED 26 // LED we have used as Aircon
#define Motionsensor_PIN 14 // Pin connected to a motion sensor.
#define SERVO_PIN 2 // Pin connected to the servo motor.
#define LED_PIN 4 // Pin connected to the LED strip us as show indication for door open close
#define NUM_LEDS 17 // Number of LEDs in the strip
#define TRIGGER_PIN 13 // Pins connected to the ultrasonic sensor for measuring distance.
#define ECHO_PIN 27 // Pins connected to the ultrasonic sensor for measuring distance.
#define LIVING_ROOM_LIGHT_PIN 15 //Pin connected to control the living room light.
// DHT parameters
#define DHTTYPE DHT22 // DHT 11
DHT_Unified dht(DHTPIN, DHTTYPE);
uint32_t delayMS;
// Servo motor
Servo servo;
// WS2812 LED strip
CRGB leds[NUM_LEDS];
//Ultrasonic
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
// MQTT Credentials
const char* ssid = "Wokwi-GUEST"; // Setting your AP SSID
const char* password = ""; // Setting your AP PSK
const char* mqttServer = "broker.hivemq.com";
// const char* mqttUserName = "bqzbdodo";
// const char* mqttPwd = "5oU2W_QN2WD8";
const char* espClientName = "esp32Client_Mohanraj"; // Client ID username+0001
// Parameters for using non-blocking delay
unsigned long previousMillis = 0;
const long interval = 1000;
String msgStr = ""; // MQTT message buffer
float temp, hum;
// Setting up WiFi and MQTT client
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
if (client.connect( espClientName)) {
Serial.println("MQTT connected");
client.subscribe("Mohanraj/room/lights");
client.subscribe("Mohanraj/room/servo"); // Subscribe to servo topic
client.subscribe("Mohanraj/room/lights/neopixel"); // Subscribe to neopixel topic
Serial.println("Topic Subscribed");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000); // wait 5sec and retry
}
}
}
/* Subscribe callback
The callback function handles incoming MQTT messages and triggers corresponding actions based on the topic and
payload. It controls the servo motor(Door Open Close) based on the received messages*/
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message: ");
String data = "";
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
data += (char)payload[i];
}
Serial.println();
Serial.print("Message size: ");
Serial.println(length);
Serial.println();
Serial.println("-----------------------");
Serial.println(data);
if (String(topic) == "Mohanraj/room/servo") {
String command = String((char*)payload).substring(0, length);
Serial.print("Received command for servo: ");
Serial.println(command);
if (command == "open") {
Serial.println("Moving servo to 180 degrees");
servo.write(180); // Move the servo to 180 degrees (open position)
// Set LED strip to green
fill_solid(leds, NUM_LEDS, CRGB(0, 255, 0));
FastLED.show();
} else if (command == "close") {
Serial.println("Moving servo to 0 degrees");
servo.write(0); // Move the servo to 0 degrees (close position)
// Set LED strip to red
fill_solid(leds, NUM_LEDS, CRGB(255, 0, 0));
FastLED.show();
} else {
Serial.println("Invalid command for servo");
}
}
}
//Aircon Function:
//Reads temperature and ultrasonic sensor data to determine whether to turn on or off the air conditioner.
void Aircon() {
// Read distance from ultrasonic sensor
float distance = ultrasonic.read();
// Read temperature
sensors_event_t event;
dht.temperature().getEvent(&event);
// Check if temperature is above 28 degrees and ultrasonic distance is less than 1 meter
if (event.temperature >= 28 && distance < 200.0) {
digitalWrite(LED, HIGH); // Turn on the LED
}
// Check if temperature is below or equal to 22 degrees
else if (event.temperature < 22) {
digitalWrite(LED, LOW); // Turn off the LED
}
// In other cases, turn off the LED
else {
digitalWrite(LED, LOW);
}
}
/*Living Room Light Function:
Checks the motion sensor input to control the living room light.*/
void LivingRoomlight(){
int motionSensorValue = digitalRead(Motionsensor_PIN);
// If motion is detected (motionSensorValue is HIGH)
if (motionSensorValue == HIGH) {
digitalWrite(LIVING_ROOM_LIGHT_PIN, HIGH); // Turn on LivingRoomlight
} else {
digitalWrite(LIVING_ROOM_LIGHT_PIN, LOW); // Turn off LivingRoomlight
}
}
/*Setup Function:
Initializes the serial communication for debugging purposes.
Sets up the DHT sensor, servo motor, LED strip, ultrasonic sensor, and living room light pin.
Connects to the WiFi network.
Sets up the MQTT client, including subscribing to specific topics.*/
void setup() {
Serial.begin(115200);
// Initialize device.
dht.begin();
// Get temperature sensor details.
sensor_t sensor;
dht.temperature().getSensor(&sensor);
dht.humidity().getSensor(&sensor);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
// Setup servo
servo.attach(SERVO_PIN);
servo.write(0);
// Setup WS2812 LED strip
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
// Setup ultrasonic sensor
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
//
pinMode(LIVING_ROOM_LIGHT_PIN, OUTPUT);
setup_wifi();
client.setServer(mqttServer, 1883); // Setting MQTT server
client.setCallback(callback); // Define function which will be called when a message is received.
}
/*Loop Function:
Checks if the MQTT client is connected and reconnects if necessary.
Processes incoming MQTT messages and triggers corresponding actions.
Reads sensor data (temperature, humidity, motion, aircon status) and publishes it to MQTT topics at regular intervals.
Implements a non-blocking delay using the millis() function.*/
void loop() {
if (!client.connected()) { // If client is not connected
reconnect(); // Try to reconnect
}
client.loop();
Aircon();
LivingRoomlight();
unsigned long currentMillis = millis(); // Read current time
if (currentMillis - previousMillis >= interval) { // If current time - last time > 5 sec
previousMillis = currentMillis;
// Read temperature and humidity
sensors_event_t event;
dht.temperature().getEvent(&event);
if (isnan(event.temperature)) {
Serial.println(F("Error reading temperature!"));
}
else {
Serial.print(F("Temperature: "));
temp = event.temperature;
Serial.print(temp);
Serial.println(F("°C"));
}
// Get humidity event and print its value
dht.humidity().getEvent(&event);
if (isnan(event.relative_humidity)) {
Serial.println(F("Error reading humidity!"));
}
else {
Serial.print(F("Humidity: "));
hum = event.relative_humidity;
Serial.print(hum);
Serial.println(F("%"));
}
// Print motion sensor value
int motionSensorValue = digitalRead(Motionsensor_PIN);
Serial.print("MotionSensorValue: ");
Serial.println(motionSensorValue);
int AirconStatus = digitalRead(LED);
Serial.print("Aircon: ");
Serial.println(AirconStatus == HIGH ? "ON" : "OFF");
String tempMsg = String(temp);
client.publish("Mohanraj/room/temperature", tempMsg.c_str());
// Construct humidity message
String humMsg = String(hum);
client.publish("Mohanraj/room/humidity", humMsg.c_str());
// Resetting Message Strings
tempMsg = "";
humMsg = "";
// Delay
delay(1);
}
}