#include <Wire.h>
#include <WiFi.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
// Pin Definitions
#define DHT_PIN 23
#define PIR_PIN 34
#define LDR_PIN 32
#define LED_PIN 33
#define SERVO_PIN_ND 26
#define SERVO_PIN_LRD 27
#define SERVO_PIN_TV 14
#define SERVO_PIN_DM 25
#define BUZ_PIR 12
// WiFi and MQTT Configuration
const char* MQTTServer = "broker.emqx.io";
const char* MQTT_ID = "cdd3c95a-f95b-402d-8c9f-5e340641ee06";
const char* topics[] = {"DuLieu", "CanhBao", "control/motor", "control/motor2", "control/motor3", "control/motor4"};
int Port = 1883;
DHT dht(DHT_PIN, DHT22);
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS3231 rtc;
WiFiClient espClient;
PubSubClient client(espClient);
Servo servo_ND, servo_LRD, servo_TV, servo_DM;
void setup() {
Serial.begin(115200);
connectToWiFi("Wokwi-GUEST", "");
setupMQTT();
initializeSensors();
initializeServos();
}
void loop() {
maintainMQTTConnection();
readAndDisplaySensorData();
performControlActions();
delay(1000); // Adjust the delay as needed
}
void connectToWiFi(const char* ssid, const char* password) {
Serial.print("Connecting to SSID: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected, IP address: ");
Serial.println(WiFi.localIP());
}
void setupMQTT() {
client.setServer(MQTTServer, Port);
client.setCallback(callback);
}
void maintainMQTTConnection() {
if (!client.connected()) {
reconnectMQTT();
}
client.loop();
}
void reconnectMQTT() {
while (!client.connected()) {
if (client.connect(MQTT_ID)) {
for (const char* topic : topics) {
client.subscribe(topic);
}
} else {
delay(5000);
}
}
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
if (String(topic) == "control/motor") {
controlServo(servo_ND, messageTemp);
} else if (String(topic) == "control/motor2") {
controlServo(servo_LRD, messageTemp);
} else if (String(topic) == "control/motor3") {
controlServo(servo_TV, messageTemp);
} else if (String(topic) == "control/motor4") {
controlServo(servo_DM, messageTemp);
}
}
void controlServo(Servo& servo, const String& command) {
if (command == "on") {
servo.write(180); // hoặc một góc cụ thể nào đó
} else if (command == "off") {
servo.write(0); // hoặc một góc cụ thể nào đó
}
}
void initializeSensors() {
dht.begin();
lcd.init();
lcd.backlight();
Wire.begin();
rtc.begin();
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(LDR_PIN, INPUT);
pinMode(BUZ_PIR, OUTPUT);
}
void initializeServos() {
servo_ND.attach(SERVO_PIN_ND, 500, 2400);
servo_LRD.attach(SERVO_PIN_LRD, 500, 2400);
servo_TV.attach(SERVO_PIN_TV, 500, 2400);
servo_DM.attach(SERVO_PIN_DM, 500, 2400);
}
void readAndDisplaySensorData() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
int lightLevel = analogRead(LDR_PIN);
DateTime now = rtc.now();
lcd.clear();
displayDateTime(now);
displaySensorData(temperature, humidity, lightLevel);
publishSensorData(temperature, humidity, lightLevel);
}
void displayDateTime(const DateTime& now) {
char daysOfTheWeek[7][3] = {"MO", "TU", "WE", "TH", "FR", "SA", "SU"};
lcd.setCursor(0, 0);
lcd.print(daysOfTheWeek[now.dayOfTheWeek() - 1]);
lcd.print(", ");
lcd.print(now.day());
lcd.print("/");
lcd.print(now.month());
lcd.print("/");
lcd.print(now.year());
lcd.print(" ");
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute() < 10 ? "0" : "");
lcd.print(now.minute());
}
void displaySensorData(float temperature, float humidity, int lightLevel) {
lcd.setCursor(0, 1);
lcd.print("Temp:");
lcd.print(temperature, 1);
lcd.print("C Hum:");
lcd.print(humidity, 1);
lcd.print("% Light:");
lcd.print(lightLevel);
}
void publishSensorData(float temperature, float humidity, int lightLevel) {
char dataString[150];
sprintf(dataString, "%.1f|%.1f|%d", temperature, humidity, lightLevel);
client.publish(topics[0], dataString);
}
void performControlActions() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
int lightLevel = analogRead(LDR_PIN);
controlTemperature(temperature);
controlHumidity(humidity);
controlLightLevel(lightLevel);
controlMotionSensor();
}
void controlTemperature(float temperature) {
if (temperature >= 50) {
servo_ND.write(180);
client.publish(topics[1], "High Temperature");
} else {
servo_ND.write(0);
}
}
void controlHumidity(float humidity) {
if (humidity >= 25 && humidity < 35) {
servo_DM.write(0);
} else {
servo_DM.write(180);
client.publish(topics[1], "High Humidity");
}
}
void controlLightLevel(int lightLevel) {
if (lightLevel <= 2000) {
servo_LRD.write(180);
client.publish(topics[1], "Low Light Level");
} else {
servo_LRD.write(0);
}
}
void controlMotionSensor() {
if (digitalRead(PIR_PIN) == HIGH) {
tone(BUZ_PIR, 32);
digitalWrite(LED_PIN, HIGH);
} else {
noTone(BUZ_PIR);
digitalWrite(LED_PIN, LOW);
}
}