#include <AdafruitIO_WiFi.h> // Thư viện Adafruit IO để kết nối và giao tiếp với Adafruit IO server
#include <Adafruit_Sensor.h> // Thư viện Adafruit Sensor để hỗ trợ các cảm biến
#include <DHT.h> // Thư viện DHT để làm việc với cảm biến DHT22
/**********************************/
/* Cấu hình thông tin kết nối WiFi và Adafruit IO */
/**********************************/
#define IO_USERNAME "huynhquy2004" // Username Adafruit IO
#define IO_KEY "aio_MCvr72WBN7SnkMbtc6LIZmLlOMaj" // Adafruit IO key
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASS ""
/**********************************/
/* Cấu hình DHT, PIR và LED */
/**********************************/
#define DHTPIN 33 // Chân dữ liệu của cảm biến DHT22
#define DHTTYPE DHT22 // Loại cảm biến DHT
DHT dht(DHTPIN, DHTTYPE); // Khởi tạo đối tượng DHT với chân và loại cảm biến đã chỉ định
#define LED_PIN 5 // Chân LED để bật/tắt LED
#define PIR_PIN 12 // Chân cảm biến PIR để phát hiện chuyển động
int enpir = 1; // Biến kiểm soát trạng thái cảm biến PIR (1: cho phép PIR , 0: không cho phép PIR)
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS); // Khởi tạo đối tượng AdafruitIO_WiFi để kết nối tới Adafruit IO
// Tạo các feed Adafruit IO để gửi và nhận dữ liệu từ các cảm biến và điều khiển LED
AdafruitIO_Feed *temperature = io.feed("temperature"); // Feed nhiệt độ
AdafruitIO_Feed *humidity = io.feed("humidity"); // Feed độ ẩm
AdafruitIO_Feed *led_control = io.feed("led_control"); // Feed điều khiển LED
// Khai báo timer của FreeRTOS để gửi dữ liệu DHT mỗi 10 giây
TimerHandle_t dhtTimer;
void sendDHTData(TimerHandle_t xTimer);
void handleLEDControl(AdafruitIO_Data *data);
void setup() {
Serial.begin(115200);
// Cài đặt chân LED và PIR
pinMode(LED_PIN, OUTPUT); // Chân LED là output
pinMode(PIR_PIN, INPUT); // Chân PIR là input
// Khởi động cảm biến DHT
dht.begin();
// Kết nối tới Adafruit IO
Serial.print("Connecting to Adafruit IO...");
io.connect(); // Kết nối đến server Adafruit IO
// Chờ kết nối thành công
while (io.status() < AIO_CONNECTED) {
Serial.print(".");
delay(500); // Chờ 500ms mỗi lần thử kết nối
}
// Sau khi kết nối thành công
Serial.println();
Serial.println(io.statusText()); // In trạng thái kết nối
// Gắn hàm xử lý cho feed led_control, khi nhận dữ liệu sẽ gọi hàm handleLEDControl
led_control->onMessage(handleLEDControl);
// Tạo một timer FreeRTOS để gửi dữ liệu từ cảm biến DHT mỗi 10 giây
dhtTimer = xTimerCreate("DHT Timer", pdMS_TO_TICKS(5000), pdTRUE, (void*)0, sendDHTData);
xTimerStart(dhtTimer, 0); // Bắt đầu timer
}
void loop() {
// Xử lý các sự kiện của Adafruit IO
io.run();
// Kiểm tra cảm biến PIR
int motion = digitalRead(PIR_PIN); // Đọc tín hiệu từ cảm biến PIR
if (motion == HIGH) { // Nếu cảm biến PIR phát hiện chuyển động
Serial.println("Motion detected!"); // In ra khi phát hiện chuyển động
digitalWrite(LED_PIN, HIGH); // Bật LED khi có chuyển động
} else { // Nếu không phát hiện chuyển động
// Kiểm tra feed điều khiển LED từ Adafruit IO (biến enpir kiểm soát việc bật tắt LED)
if (enpir == 1) {
digitalWrite(LED_PIN, LOW); // Tắt LED khi không có chuyển động và feed ddang không bật LED
}
}
delay(500);
}
// Hàm gửi dữ liệu DHT mỗi 5 giây
void sendDHTData(TimerHandle_t xTimer) {
// Đọc dữ liệu từ cảm biến DHT
float h = dht.readHumidity(); // Đọc giá trị độ ẩm
float t = dht.readTemperature(); // Đọc giá trị nhiệt độ
// Kiểm tra xem cảm biến có hoạt động không
if (isnan(h) || isnan(t)) { // Nếu đọc dữ liệu không thành công
Serial.println("Failed to read from DHT sensor!"); // Thông báo lỗi
return; // Kết thúc hàm nếu không đọc được dữ liệu
}
// Gửi dữ liệu lên Adafruit IO
temperature->save(t); // Gửi dữ liệu nhiệt độ lên feed "temperature"
humidity->save(h); // Gửi dữ liệu độ ẩm lên feed "humidity"
// Hiển thị dữ liệu trên Serial Monitor
Serial.print("Temperature: ");
Serial.print(t); // In ra giá trị nhiệt độ
Serial.print(" °C, Humidity: ");
Serial.print(h); // In ra giá trị độ ẩm
Serial.println(" %");
}
// Hàm xử lý khi có dữ liệu điều khiển LED từ feed led_control
void handleLEDControl(AdafruitIO_Data *data) {
if (data->toPinLevel() == HIGH) { // Nếu nhận dữ liệu HIGH, bật LED
digitalWrite(LED_PIN, HIGH); // Bật LED
Serial.println("LED turned ON"); // Thông báo bật LED
enpir = 0; // Tắt kiểm tra PIR
} else { // Nếu nhận dữ liệu LOW, tắt LED
digitalWrite(LED_PIN, LOW); // Tắt LED
Serial.println("LED turned OFF"); // Thông báo tắt LED
enpir = 1; // Bật kiểm tra PIR
}
}