#include <WiFi.h>
#include <PubSubClient.h>
#include "DHTesp.h"
#include <NTPClient.h>
#include <ESP32Servo.h>
#include "LiquidCrystal.h"
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const int photo_sensor = A0;
const int light = 4;
const int heat_light = 2;
const int dht_pin = 14;
const int servo_mist_pin = 12;
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
// Variables to save date and time
int hour;
int minute;
int second;
unsigned long previousMillis = 0; // Biến lưu thời điểm trước đó
const long interval = 5000; // Thời gian đợi 5000 ms (5 giây)
// Servo configuration
const int servo_feed_pin = 27;
Servo servo_feed;
const int servo_drink_pin = 32;
Servo servo_drink;
unsigned long lastServoTime = 0;
//const unsigned long servoInterval = 6 * 60 * 60 * 1000; // 6 hours in milliseconds
DHTesp dhtSensor;
Servo servo_mist;
LiquidCrystal lcd(19, 23, 18, 17, 16, 15);
//***Set server***
const char* mqttServer = "broker.hivemq.com";
int port = 1883;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void wifiConnect() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" Connected!");
}
void mqttConnect() {
while(!mqttClient.connected()) {
Serial.println("Attemping MQTT connection...");
String clientId = "Nhom1";
clientId += String(random(0xffff), HEX);
if(mqttClient.connect(clientId.c_str())) {
Serial.println("connected");
//***Subscribe all topic you need***
mqttClient.subscribe("nhom1/automatic");
}
else {
Serial.println("try again in 5 seconds");
delay(5000);
}
}
}
//MQTT Receiver
void callback(char* topic, byte* message, unsigned int length) {
Serial.println(topic);
String strMsg;
for(int i=0; i<length; i++) {
strMsg += (char)message[i];
}
Serial.println(strMsg);
//***Code here to process the received package***
}
void setup() {
Serial.begin(9600);
Serial.print("Connecting to WiFi");
wifiConnect();
mqttClient.setServer(mqttServer, port);
mqttClient.setCallback(callback);
mqttClient.setKeepAlive( 90 );
pinMode(light, OUTPUT);
pinMode(heat_light, OUTPUT);
pinMode(photo_sensor, INPUT);
servo_mist.attach(servo_mist_pin, 500, 2400);
dhtSensor.setup(dht_pin, DHTesp::DHT22);
lcd.begin(16, 2);
// Initialize a NTPClient to get time
timeClient.begin();
timeClient.setTimeOffset(7*60*60);
// Attach servo to the pin
servo_feed.attach(servo_feed_pin, 500, 2400);
servo_drink.attach(servo_drink_pin, 500, 2400);
lcd.begin(16, 2);
}
bool pre_light = 0;
bool pre_heat = 0;
int pre_mist = servo_mist.read();
void loop() {
if(!mqttClient.connected()) {
mqttConnect();
}
mqttClient.loop();
// Đọc cảm biến nhiệt độ, độ ẩm
TempAndHumidity data = dhtSensor.getTempAndHumidity();
int value = analogRead(photo_sensor);
float t = data.temperature;
float h = data.humidity;
//***Publish data to MQTT Server***
mqttClient.publish("nhom1/temp", String(t).c_str());
mqttClient.publish("nhom1/humid", String(h).c_str());
unsigned long currentMillis = millis(); // Lấy thời điểm hiện tại
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(t);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Hum: ");
lcd.print(h);
lcd.print(" %");
//Serial.println(value);
// Nếu trời tối -> bật đèn
if (value < 300){
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Lưu thời điểm hiện tại
digitalWrite(light, HIGH);
if (digitalRead(light) != pre_light){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Light on");
}
if (currentMillis - previousMillis >= interval * 2) {
pre_light = 1;
// }
// digitalWrite(light, HIGH);
// if (digitalRead(light) != pre_light){
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Light on");
// delay(1000);
// pre_light = 1;
// }
}
}
else{
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Lưu thời điểm hiện tại
digitalWrite(light, LOW);
if (digitalRead(light) != pre_light){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Light off");
}
if (currentMillis - previousMillis >= interval * 2) {
pre_light = 0;
}
}
}
}
// Nếu nhiệt độ cao, độ ẩm thấp -> bật servo phun sương
if (t > 35 && h < 50){
servo_mist.write(0);
if (servo_mist.read() != pre_mist){
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Lưu thời điểm hiện tại
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Spray mist on");
}
if (currentMillis - previousMillis >= interval * 2) {
pre_mist = servo_mist.read();
}
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Spray mist on");
// delay(1000);
// pre_mist = servo_mist.read();
}
}
else if (t < 32){
servo_mist.write(90);
if (servo_mist.read() != pre_mist){
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Lưu thời điểm hiện tại
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Spray mist off");
}
if (currentMillis - previousMillis >= interval * 2) {
pre_mist = servo_mist.read();
}
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Spray mist off");
// delay(1000);
// pre_mist = servo_mist.read();
}
}
// Nếu nhiệt độ thấp, độ ẩm cao -> bật đèn sưởi
if (t < 24 && h > 90){
digitalWrite(heat_light, HIGH);
if (digitalRead(heat_light) != pre_heat){
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Lưu thời điểm hiện tại
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Heat light on");
}
if (currentMillis - previousMillis >= interval * 2) {
pre_heat = 1;
}
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Heat light on");
// delay(1000);
// pre_heat = 1;
}
}
else {
digitalWrite(heat_light, LOW);
if (digitalRead(heat_light) != pre_heat){
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Lưu thời điểm hiện tại
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Heat light off");
}
if (currentMillis - previousMillis >= interval * 2) {
pre_heat = 0;
}
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Heat light off");
// delay(1000);
// pre_heat = 0;
}
}
//Get time to feed and drink
while (!timeClient.update()) {
timeClient.forceUpdate();
}
hour = timeClient.getHours();
minute = timeClient.getMinutes();
second = timeClient.getSeconds();
Serial.println(hour);
// Check if it's time to activate the servo
if (hour == 23 && minute == 38 && second == 0) {
// Kiểm tra thời gian đã trôi qua từ lần cuối cùng
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Lưu thời điểm hiện tại
servo_feed.write(90); // Bật servo lên 90 độ
servo_drink.write(90);
}
if (currentMillis - previousMillis >= interval * 2) {
servo_feed.write(0);
servo_drink.write(0);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Feeding");
lcd.setCursor(0, 1);
lcd.print("Drinking");
}
}
}