#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h>
#include <DHT.h>
#include <WiFi.h>
#include <PubSubClient.h>
// Khai báo chân
#define DHT_PIN 15 // Chân của cảm biến DHT22
#define DHT_TYPE DHT22
#define LIGHT_SENSOR_PIN 34 // Chân của cảm biến ánh sáng
#define TRIG_PIN 19 // Chân TRIG cho HC-SR04
#define ECHO_PIN 18 // Chân ECHO cho HC-SR04
#define RELAY_DHT_PIN_1 14 // Relay điều khiển dựa trên nhiệt độ
#define RELAY_DHT_PIN_2 12 // Relay điều khiển dựa trên độ ẩm
#define RELAY_LIGHT_PIN 32 // Relay điều khiển dựa trên ánh sáng
#define RELAY_ULTRASONIC_PIN 33 // Relay điều khiển cảm biến siêu âm
#define BUTTON_DHT_PIN_1 25 // Nút bấm điều khiển relay DHT 1
#define BUTTON_DHT_PIN_2 13 // Nút bấm điều khiển relay DHT 2
#define BUTTON_LIGHT_PIN 26 // Nút bấm điều khiển relay ánh sáng
#define BUTTON_ULTRASONIC_PIN 27 // Nút bấm điều khiển relay siêu âm
// Màn hình OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Cảm biến DHT22
DHT dht(DHT_PIN, DHT_TYPE);
// Khởi tạo các biến để lưu trạng thái relay và button
//Trạng thái cuối cùng cho relay
bool dhtRelayState_1 = false; // Trạng thái cuối cùng cho Relay DHT 1
bool dhtRelayState_2 = false; // Trạng thái cuối cùng cho Relay DHT 2
bool lightRelayState = false; // Trạng thái cuối cùng cho Relay ánh sáng
bool ultrasonicRelayState = false; // Trạng thái cuối cùng cho Relay siêu âm
// Các biến để theo dõi trạng thái nút bấm
volatile bool dhtButtonPressed_1 = false;
volatile bool dhtButtonPressed_2 = false;
volatile bool lightButtonPressed = false;
volatile bool UltraButtonPressed = false;
// Biến trạng thái điều khiển thủ công
bool dhtManualControl_1 = false;
bool dhtManualControl_2 = false;
bool lightManualControl = false;
bool ultrasonicManualControl = false;
// Khai báo thông tin MQTT
#define MQTT_CLIENT_ID "clientidweather"
#define MQTT_BROKER "mqtt-dashboard.com"
#define MQTT_TOPIC "garden"
#define MQTT_TOPICDK "gardendk"
const char* ssid = "Wokwi-GUEST";
const char* password = "";
WiFiClient espClient;
PubSubClient client(espClient);
// Hàm kết nối WiFi
void connectWiFi()
{
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" Connected!");
}
// Hàm kết nối lại MQTT
void reconnectMQTT()
{
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect(MQTT_CLIENT_ID)) {
Serial.println(" Connected!");
client.subscribe(MQTT_TOPICDK);
} else {
Serial.print(" failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
// Hàm gửi dữ liệu lên MQTT
void sendToMQTT(float nhietdo, float doam, float anhsang, float mucnuoc) {
String payload = "{\"temperature\":" + String(nhietdo) +
",\"humidity\":" + String(doam) +
",\"waterLevel\":" + String(mucnuoc) +
",\"lightIntensity\":" + String(anhsang) +
+",\"RELAY_DHT_1\":" + (dhtRelayState_1 ? "ON" : "OFF")
+",\"RELAY_DHT_2\":" + (dhtRelayState_2 ? "ON" : "OFF")
+",\"RELAY_LIGHT\":" + (lightRelayState ? "ON" : "OFF")
+",\"RELAY_ULTRASONIC\":" + (ultrasonicRelayState ? "ON" : "OFF")
+"}";
client.publish(MQTT_TOPIC, payload.c_str());
}
void setup() {
Serial.begin(115200);
// Cấu hình chân cho cảm biến, relay, nút bấm, và LED
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(RELAY_DHT_PIN_1, OUTPUT);
pinMode(RELAY_DHT_PIN_2, OUTPUT);
pinMode(RELAY_LIGHT_PIN, OUTPUT);
pinMode(RELAY_ULTRASONIC_PIN, OUTPUT);
pinMode(BUTTON_DHT_PIN_1, INPUT_PULLUP);
pinMode(BUTTON_DHT_PIN_2, INPUT_PULLUP);
pinMode(BUTTON_LIGHT_PIN, INPUT_PULLUP);
pinMode(BUTTON_ULTRASONIC_PIN, INPUT_PULLUP);
// Khởi động cảm biến DHT
dht.begin();
// Khởi động màn hình OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED initialization failed"));
for(;;);
}
display.clearDisplay();
display.display();
// Kết nối WiFi và MQTT
connectWiFi();
client.setServer(MQTT_BROKER, 1883);
//client.setCallback(mqttCallback);
// Cấu hình ngắt
attachInterrupt(digitalPinToInterrupt(BUTTON_DHT_PIN_1), dhtButtonISR_1, FALLING);
attachInterrupt(digitalPinToInterrupt(BUTTON_DHT_PIN_2), dhtButtonISR_2, FALLING);
attachInterrupt(digitalPinToInterrupt(BUTTON_LIGHT_PIN), lightButtonISR, FALLING);
attachInterrupt(digitalPinToInterrupt(BUTTON_ULTRASONIC_PIN), UltraButtonISR, FALLING);
}
// Ngắt xử lý cho nút bấm
void dhtButtonISR_1() {
dhtButtonPressed_1 = true;
}
void dhtButtonISR_2() {
dhtButtonPressed_2 = true;
}
void lightButtonISR() {
lightButtonPressed = true;
}
void UltraButtonISR() {
UltraButtonPressed = true;
}
void handleButtons() {
// Xử lý nút bấm DHT 1
if (dhtButtonPressed_1) {
dhtManualControl_1 = !dhtManualControl_1; // Chuyển đổi chế độ thủ công
dhtRelayState_1 = !dhtRelayState_1; // Đổi trạng thái relay
digitalWrite(RELAY_DHT_PIN_1, dhtRelayState_1 ? HIGH : LOW);
dhtButtonPressed_1 = false; // Đặt lại cờ nút bấm
}
// Xử lý nút bấm DHT 2
if (dhtButtonPressed_2) {
dhtManualControl_2 = !dhtManualControl_2;
dhtRelayState_2 = !dhtRelayState_2;
digitalWrite(RELAY_DHT_PIN_2, dhtRelayState_2 ? HIGH : LOW);
dhtButtonPressed_2 = false;
}
// Xử lý nút bấm ánh sáng
if (lightButtonPressed) {
lightManualControl = !lightManualControl;
lightRelayState = !lightRelayState;
digitalWrite(RELAY_LIGHT_PIN, lightRelayState ? HIGH : LOW);
lightButtonPressed = false;
}
// Xử lý nút bấm siêu âm
if (UltraButtonPressed) {
ultrasonicManualControl = !ultrasonicManualControl;
ultrasonicRelayState = !ultrasonicRelayState;
digitalWrite(RELAY_ULTRASONIC_PIN, ultrasonicRelayState ? HIGH : LOW);
UltraButtonPressed = false;
}
}
// Đọc giá trị từ cảm biến ánh sáng
void readLightLevel(float &lux) {
int analogValue = analogRead(LIGHT_SENSOR_PIN);
float voltage = analogValue / 4096.0 * 3.3;
float resistance = 2000 * voltage / (1 - voltage / 3.3);
lux = pow(33 * 1e3 * pow(10, 0.7) / resistance, (1 / 0.7));
Serial.print("Gia tri cuong do a/s: ");
Serial.print(lux);
Serial.println(" lux");
}
// Hàm đo khoảng cách từ cảm biến HC-SR04
void measureDistance(float &mucnuochientai) {
long duration;
float dodaibenuoc = 200;
float nguongnuoc = 50;
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
float distance = duration * 0.034 / 2; // Tính toán khoảng cách bằng cm
mucnuochientai = dodaibenuoc - distance;
if(mucnuochientai < 0){
mucnuochientai=0;
}
Serial.print("Muc nuoc: ");
Serial.print(mucnuochientai);
Serial.println(" cm");
if(mucnuochientai < nguongnuoc && ultrasonicRelayState == LOW){
digitalWrite(RELAY_ULTRASONIC_PIN, HIGH);
ultrasonicRelayState = HIGH;
Serial.print("Dang bom nuoc ");
Serial.println(" ");
}else if(mucnuochientai >= nguongnuoc && ultrasonicRelayState == HIGH){
digitalWrite(RELAY_ULTRASONIC_PIN, LOW);
ultrasonicRelayState = LOW;
Serial.print("Khong can bom nuoc ");
Serial.println(" ");
}
}
// Đọc nhiệt độ và độ ẩm từ DHT22
void readDHTData(float &temperature, float &humidity) {
temperature = dht.readTemperature();
humidity = dht.readHumidity();
if (isnan(temperature) || isnan(humidity)) {
Serial.println(F("Failed to read from DHT sensor!"));
temperature = humidity = 0; // Đặt giá trị mặc định khi đọc thất bại
}
Serial.print("Nhiet do: ");
Serial.print(temperature);
Serial.println(" doC");
Serial.print("Do am: ");
Serial.print(humidity);
Serial.println(" %");
}
// Điều khiển relay nhiệt độ và LED
void controlDHTRelay1(float &temperature) {
if (temperature > 30 && dhtRelayState_1 == HIGH) {
digitalWrite(RELAY_DHT_PIN_1, LOW);
dhtRelayState_1 = LOW;
Serial.println(" Nong -> Khong can lo suoi ");
} else if(temperature <= 30 && dhtRelayState_1 == LOW) {
digitalWrite(RELAY_DHT_PIN_1, HIGH);
dhtRelayState_1 = HIGH;
Serial.println(" Lanh -> Bat lo suoi ");
}
}
// Điều khiển relay độ ẩm và LED
void controlDHTRelay2(float &humidity) {
if (humidity < 65 && dhtRelayState_2 == HIGH) {
digitalWrite(RELAY_DHT_PIN_2, LOW);
dhtRelayState_2 = LOW;
Serial.println("DO am thap -> Khong can quat ");
} else if(humidity >= 65 && dhtRelayState_2 == LOW){
digitalWrite(RELAY_DHT_PIN_2, HIGH);
dhtRelayState_2 = HIGH;
Serial.println("Do am cao -> Bat quat ");
}
}
// Điều khiển relay dựa trên ánh sáng và LED
void controlLightRelay(float &lux) {
if (lux < 1000 && lightRelayState == LOW) {
digitalWrite(RELAY_LIGHT_PIN, HIGH); // Bật LED
lightRelayState = HIGH;
Serial.println("Da bat den` ");
} else if (lux >= 1000 && lightRelayState == HIGH) {
digitalWrite(RELAY_LIGHT_PIN, LOW); // Tắt LED
lightRelayState = LOW;
Serial.println("Khong toi -> Khong can bat den` ");
}
}
// Hiển thị thông tin lên màn hình OLED
void displayData(float temperature, float humidity, float lux, float mucnuochientai) {
display.clearDisplay();
display.setTextSize(0.6);
display.setTextColor(WHITE);
// Hiển thị nhiệt độ và độ ẩm
display.setCursor(0, 0);
display.print("Temp: ");
display.print(temperature);
display.print(" C");
display.setCursor(0, 8);
display.print("Hum: ");
display.print(humidity);
display.print(" %");
// Hiển thị mức ánh sáng
display.setCursor(0, 16);
display.print("Light: ");
display.print(lux);
display.print(" Lux");
// Hiển thị khoảng cách
display.setCursor(0, 24);
display.print("Muc nuoc ht: ");
display.print(mucnuochientai);
display.print(" cm");
// Hiển thị trạng thái relay
display.setCursor(0, 32);
display.print("Relay DHT 1 : ");
display.print(dhtRelayState_1 ? "ON" : "OFF");
display.setCursor(0, 40);
display.print("Relay DHT 2 : ");
display.print(dhtRelayState_2 ? "ON" : "OFF");
display.setCursor(0, 48);
display.print("Relay Light: ");
display.print(lightRelayState ? "ON" : "OFF");
display.setCursor(0, 56);
display.print("Relay Ultrasonic: ");
display.print(ultrasonicRelayState ? "ON" : "OFF");
display.display();
}
// Vòng lặp chính
void loop() {
float temperature, humidity, mucnuochientai;
float lux;
if (!client.connected()) {
reconnectMQTT();
}
client.loop(); // Gọi hàm xử lý MQTT
// Xử lý nút bấm
handleButtons();
// Đọc dữ liệu từ cảm biến và điều khiển relay nếu không ở chế độ thủ công
if (!dhtManualControl_1) {
readDHTData(temperature, humidity);
controlDHTRelay1(temperature);
}
if (!dhtManualControl_2) {
controlDHTRelay2(humidity);
}
if (!lightManualControl) {
readLightLevel(lux);
controlLightRelay(lux);
}
if (!ultrasonicManualControl) {
measureDistance(mucnuochientai);
}
// Hiển thị dữ liệu lên OLED
displayData(temperature, humidity, lux, mucnuochientai);
//Gửi dl lên mqtt
sendToMQTT(temperature, humidity, lux, mucnuochientai);
// Đợi 2 giây trước khi lặp lại
delay(2000);
}
Loading
esp32-devkit-c-v4
esp32-devkit-c-v4
Loading
ssd1306
ssd1306