#define BLYNK_TEMPLATE_ID "TMPL6HD1gnjyh"
#define BLYNK_TEMPLATE_NAME "BTL GIAM SAT VA DIEU KHIEN NHIET DO"
#define BLYNK_AUTH_TOKEN "iGSI2rOelPOnr1Az1vOJIbpZIaFk87OH"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include "DHT.h"
// Cảm biến DHT22
#define DHTPIN 25
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
char ssid[] = "Wokwi-GUEST";//Tên wifi
char pass[] = "";//mật khẩu wifi
// Chân thiết bị phần cứng
#define SOIL_PIN 34
#define BUZZER_PIN 13
#define LED_MOTOR 27
#define LED_AIR 14
const int buttonPin = 35; // Định nghĩa chân kết nối với nút nhấn
const int RelayPin = 26; // Định nghĩa chân kết nối motor
boolean updateRelay=0;
WidgetLED LEDCONNECT(V0);
#define RELAY_S_HUMI V1
#define RELAY_TEMP V8
#define LED_A V2
#define TEMP V3
#define HUMI V4
#define S_HUMI V5
#define LED_M V6
#define BUZZ V7
unsigned long timeBlink=millis();
unsigned long timeDelay=millis();
// Every time we connect to the cloud...
BLYNK_CONNECTED() {
// Request the latest state from the server
Blynk.syncVirtual(RELAY_S_HUMI);
}
BLYNK_WRITE(RELAY_S_HUMI) {
int p = param.asInt();
digitalWrite(RelayPin, p);
}
ICACHE_RAM_ATTR void handleButton(){
if(millis()-timeDelay>200){
if(digitalRead(buttonPin)==LOW){
digitalWrite(RelayPin,!digitalRead(RelayPin));
}
updateRelay=1;
timeDelay=millis();
}
}
// Hàm điều khiển thiết bị
void controlDevice(float t, float h, int soilPercent) {
digitalWrite(BUZZER_PIN, (t > 40) ? HIGH : LOW);
digitalWrite(LED_AIR, (h < 80) ? HIGH : LOW);
digitalWrite(LED_MOTOR, (soilPercent < 70) ? HIGH : LOW);
}
// Gửi dữ liệu cảm biến
void sendSensor() {
float h = dht.readHumidity();
float t = dht.readTemperature();
int analogValue = analogRead(SOIL_PIN); // Đọc giá trị từ biến trở
int soilPercent = map(analogValue, 1, 4095, 0, 100); // Quy đổi sang % độ ẩm // Nếu HIGH → 80%, LOW → 20%
if (isnan(h) || isnan(t)) {
Serial.println("❌ Không thể đọc dữ liệu từ cảm biến DHT!");
return;
}
controlDevice(t, h, soilPercent);
Serial.printf("🌡️ Nhiệt độ: %.2f °C\n", t);
Serial.printf("💧 Độ ẩm: %.2f %%\n", h);
Serial.printf("🌱 Độ ẩm đất: %d %%\n", soilPercent);
Serial.println("---------------------");
}
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(SOIL_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_MOTOR, OUTPUT);
pinMode(LED_AIR, OUTPUT);
pinMode(RelayPin, OUTPUT); // Thiết lập chân ledPin là đầu ra
pinMode(buttonPin, INPUT_PULLUP); // Thiết lập chân buttonPin là đầu vào
digitalWrite(RelayPin, LOW); // Tắt relay ban đầu
attachInterrupt(buttonPin,handleButton,FALLING);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop() {
Blynk.run();
// Đọc dữ liệu từ Serial (COM) gửi từ C# xuống
if (Serial.available()) {
String cmd = Serial.readStringUntil('\n'); // Đọc chuỗi đến khi gặp ký tự '\n'
if (cmd.startsWith("SET_TEMP:")) {
float value = cmd.substring(9).toFloat(); // Cắt phần số sau "SET_TEMP:"
Serial.printf("🌡️ Nhận nhiệt độ từ PC: %.2f°C\n", value);
}
else if (cmd.startsWith("SET_HUMI:")) {
float value = cmd.substring(9).toFloat(); // Cắt phần số sau "SET_HUMI:"
Serial.printf("💧 Nhận độ ẩm từ PC: %.2f%%\n", value);
}
else if (cmd.startsWith("SET_SOIL:")) {
float value = cmd.substring(9).toFloat(); // Cắt phần số sau "SET_SOIL:"
Serial.printf("🌱 Nhận độ ẩm đất từ PC: %.2f%%\n", value);
}
else {
Serial.println("Lệnh không hợp lệ!");
}
}
if(millis()-timeBlink>1000){
if(LEDCONNECT.getValue()){
LEDCONNECT.off();
}else{
LEDCONNECT.on();
}
float h = dht.readHumidity();
float t = dht.readTemperature();
int analogValue = analogRead(SOIL_PIN); // Đọc giá trị từ biến trở
int soilPercent = map(analogValue, 1, 4095, 0, 100); // Quy đổi sang % độ ẩm // Nếu HIGH → 80%, LOW → 20%
Blynk.virtualWrite(TEMP,t);
Blynk.virtualWrite(HUMI,h);
Blynk.virtualWrite(S_HUMI,soilPercent);
Blynk.virtualWrite(RELAY_TEMP,digitalRead(BUZZER_PIN));
Blynk.virtualWrite(BUZZ,digitalRead(BUZZER_PIN));
Blynk.virtualWrite(LED_A,digitalRead(LED_AIR));
Blynk.virtualWrite(LED_M,digitalRead(LED_MOTOR));
}
if(updateRelay==1){
Blynk.virtualWrite(RELAY_S_HUMI,digitalRead(RelayPin));
updateRelay=0;
}
sendSensor();
}