#include <DHT.h>
#include <Wire.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <LiquidCrystal_I2C.h>
// Định nghĩa thông số cho DHT22
#define DHTPIN 4 // Pin kết nối DHT22
#define DHTTYPE DHT22 // Cảm biến loại DHT22
#define LIGHT_SENSOR_PIN A0 // Chân đọc giá trị cảm biến ánh sáng
#define LED_PIN 12
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHTPIN, DHTTYPE); // Khai báo đối tượng DHT
// Khai báo queue để lưu dữ liệu nhiệt độ
QueueHandle_t temperatureQueue;
// Hàm khai báo cho Task
void TaskReadTemperature(void *pvParameters);
void TaskDisplayTemperature(void *pvParameters);
void TaskControlLight(void *pvParameters);
void setup() {
lcd.init();
Serial.begin(115200);
// Khởi tạo DHT
dht.begin();
lcd.begin(16,2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Hello");
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
// Tạo queue với kích thước 10
temperatureQueue = xQueueCreate(10, sizeof(float));
// Tạo Task để đọc dữ liệu nhiệt độ
xTaskCreate(
TaskReadTemperature,
"TaskReadTemperature",
2048,
NULL,
1,
NULL
);
// task hiển thị màn hình lcd
xTaskCreate(
TaskDisplayTemperature,
"TaskDisplayTemperature",
2048,
NULL,
1,
NULL
);
//task sáng đèn
xTaskCreate(
TaskControlLight,
"TaskControlLight",
2048,
NULL,
1,
NULL
);
}
void loop() {
// Loop trống, mọi thứ sẽ được xử lý trong Task
}
// Task để đọc dữ liệu nhiệt độ từ DHT22
void TaskReadTemperature(void *pvParameters) {
(void) pvParameters; // Không sử dụng tham số truyền vào
for (;;) {
float temperature = dht.readTemperature();
// Kiểm tra nếu cảm biến không hoạt động đúng
if (isnan(temperature)) {
Serial.println("Không thể đọc dữ liệu từ cảm biến DHT22!");
} else {
// Gửi nhiệt độ vào Queue
if (xQueueSend(temperatureQueue, &temperature, portMAX_DELAY) == pdPASS) {
Serial.print("Đã gửi nhiệt độ vào Queue: ");
Serial.println(temperature);
}
}
vTaskDelay(500 / portTICK_PERIOD_MS); // Đợi 500ms trước khi đọc lại
}
}
// Task để hiển thị dữ liệu nhiệt độ lên LCD
void TaskDisplayTemperature(void *pvParameters) {
(void) pvParameters; // Không sử dụng tham số truyền vào
float receivedTemperature;
for (;;) {
// Nhận dữ liệu từ queue
if (xQueueReceive(temperatureQueue, &receivedTemperature, portMAX_DELAY) == pdPASS) {
// Hiển thị nhiệt độ lên LCD
lcd.clear(); // Xóa màn hình trước khi hiển thị
lcd.setCursor(0, 0); // Đặt con trỏ ở đầu dòng 0
lcd.print("nhiet do:");
lcd.setCursor(0, 1); // Đặt con trỏ ở đầu dòng 1
lcd.print(receivedTemperature);
lcd.print(" c");
Serial.print("Hiển thị nhiệt độ lên LCD: ");
Serial.println(receivedTemperature);
}
vTaskDelay(500 / portTICK_PERIOD_MS); // Đợi 500ms trước khi nhận dữ liệu tiếp theo
}
}
// Task để điều khiển đèn theo ánh sáng
void TaskControlLight(void *pvParameters) {
(void) pvParameters; // Không sử dụng tham số truyền vào
for (;;) {
// Đọc giá trị ánh sáng từ cảm biến
int lightValue = analogRead(LIGHT_SENSOR_PIN);
// Chuyển đổi giá trị từ cảm biến thành Lux
// Có thể cần điều chỉnh giá trị này dựa trên cảm biến thực tế
float lux = map(lightValue, 0, 1023, 0, 1000);
Serial.print("Giá trị ánh sáng: ");
Serial.print(lightValue);
Serial.print(" (Lux: ");
Serial.print(lux);
Serial.println(")");
// Kiểm tra nếu mức ánh sáng thấp hơn 1000 Lux
if (lux < 1000) {
digitalWrite(LED_PIN, HIGH); // Bật đèn LED
} else {
digitalWrite(LED_PIN, LOW); // Tắt đèn LED
}
vTaskDelay(500 / portTICK_PERIOD_MS); // Đợi 1 giây trước khi đọc lại
}
}