#define BLYNK_TEMPLATE_ID "TMPL6q-aY85ec"
#define BLYNK_TEMPLATE_NAME "ESP32"
#define BLYNK_AUTH_TOKEN "3WynS0G-B_iyCCf-G4xzbnp5miDIKvO7"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <time.h>
const char* ssid = "Wokwi-GUEST";
const char* pass = "";
const int pirPin = 19;
const int buzzerPin = 18;
const int led1 = 4;
bool alarmEnabled = false;
int lastMotionState = LOW;
unsigned long lastSendTime = 0;
BlynkTimer timer;
BLYNK_CONNECTED() {
Blynk.syncVirtual(V0);
}
BLYNK_WRITE(V0) {
alarmEnabled = param.asInt();
if (!alarmEnabled) {
Blynk.setProperty(V1, "color", "#4B5563");
Blynk.virtualWrite(V2, "Tắt");
if (lastMotionState == HIGH) {
lastMotionState = LOW;
lastSendTime = 0;
noTone(buzzerPin); // thực tế dùng digitalWrite(buzzerPin, LOW);
digitalWrite(led1, LOW);
}
} else {
Blynk.setProperty(V1, "color", "#2563EB");
Blynk.virtualWrite(V2, "Bật");
}
Serial.println(alarmEnabled ? "🔔 Báo động BẬT" : "🔕 Báo động TẮT");
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n✅ WiFi kết nối thành công!");
configTime(7 * 3600, 0, "pool.ntp.org");
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
pinMode(pirPin, INPUT);
pinMode(led1, OUTPUT);
pinMode(buzzerPin, OUTPUT);
Serial.println("✅ Hệ thống đã khởi động!");
timer.setInterval(1000L, checkMotion); // Kiểm tra chuyển động mỗi giây
}
void loop() {
Blynk.run();
timer.run();
}
void checkMotion() {
if (!alarmEnabled) return;
int motionDetected = digitalRead(pirPin);
if (motionDetected == HIGH && lastMotionState == LOW) {
Blynk.setProperty(V1, "color", "#DC2626");
Blynk.virtualWrite(V2, "Cảnh báo");
lastMotionState = HIGH;
tone(buzzerPin, 1000); // thực tế dùng digitalWrite(buzzerPin, HIGH);
digitalWrite(led1, HIGH);
Serial.println("🚨 Phát hiện chuyển động! Buzzer ON");
if ((millis() - lastSendTime) >= 5000UL) {
time_t now = time(nullptr);
struct tm *timeinfo = localtime(&now);
char timeStr[30];
strftime(timeStr, sizeof(timeStr), "%H:%M:%S %d-%m-%Y", timeinfo);
Blynk.logEvent("motion_alert", String("🔴 Phát hiện lúc ") + timeStr);
lastSendTime = millis();
}
}
else if (motionDetected == LOW && lastMotionState == HIGH) {
Blynk.setProperty(V1, "color", "#16A34A");
Blynk.virtualWrite(V2, "An toàn");
lastMotionState = LOW;
noTone(buzzerPin); // thực tế dùng digitalWrite(buzzerPin, LOW);
digitalWrite(led1, LOW);
Serial.println("✅ Không còn chuyển động! Buzzer OFF");
}
}