#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <DHT.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define DHT_SENSOR_PIN 2
#define DHTTYPE DHT22
#define LDR_PIN 33 // Cảm biến ánh sáng
#define RELAY_LIGHT 4 // Relay điều khiển đèn
#define RELAY_FAN 5 // Relay điều khiển quạt
#define RELAY_PUMP 18 // Relay điều khiển máy bơm
#define BUTTON_LIGHT 15 // Nút nhấn đèn
#define BUTTON_FAN 14 // Nút nhấn quạt
#define BUTTON_PUMP 13 // Nút nhấn máy bơm
#define BUTTON_MODE 12 // Nút chuyển chế độ
#define BUTTON_PAGE 27 // Nút chuyển trang
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
DHT dht(DHT_SENSOR_PIN, DHTTYPE);
QueueHandle_t umidade;
QueueHandle_t temperatura;
QueueHandle_t anhSang;
bool manualMode = false;
bool lightState = false;
bool fanState = false;
bool pumpState = false;
bool page = false; // false = Trang 1 (Cảm biến), true = Trang 2 (Trạng thái thiết bị)
bool lastPage = false;
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
dht.begin();
umidade = xQueueCreate(1, sizeof(float));
temperatura = xQueueCreate(1, sizeof(float));
anhSang = xQueueCreate(1, sizeof(float));
pinMode(RELAY_LIGHT, OUTPUT);
pinMode(RELAY_FAN, OUTPUT);
pinMode(RELAY_PUMP, OUTPUT);
pinMode(BUTTON_LIGHT, INPUT_PULLUP);
pinMode(BUTTON_FAN, INPUT_PULLUP);
pinMode(BUTTON_PUMP, INPUT_PULLUP);
pinMode(BUTTON_MODE, INPUT_PULLUP);
pinMode(BUTTON_PAGE, INPUT_PULLUP);
xTaskCreate(lerLDR, "Đọc ánh sáng", 2048, NULL, 2, NULL);
xTaskCreate(lerSensor, "Đọc DHT22", 2048, NULL, 2, NULL);
xTaskCreate(controlDevices, "Điều khiển thiết bị", 2048, NULL, 1, NULL);
xTaskCreate(buttonTask, "Xử lý nút nhấn", 2048, NULL, 1, NULL);
xTaskCreate(printLCD, "In OLED", 2048, NULL, 1, NULL);
}
void loop() {}
void lerSensor(void *parametro) {
while(true) {
float h = dht.readHumidity();
float t = dht.readTemperature();
xQueueOverwrite(umidade, &h);
xQueueOverwrite(temperatura, &t);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
void lerLDR(void *parametro) {
while(true) {
int adcValue = analogRead(LDR_PIN);
float lightLevel = (4095 - adcValue) / 4095.0 * 100;
xQueueOverwrite(anhSang, &lightLevel);
if (!manualMode) {
digitalWrite(RELAY_LIGHT, lightLevel < 50.0 ? HIGH : LOW);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void controlDevices(void *parametro) {
float temp, hum;
while(true) {
if (xQueueReceive(temperatura, &temp, 200) && xQueueReceive(umidade, &hum, 200)) {
if (!manualMode) {
digitalWrite(RELAY_FAN, temp > 30.0 ? HIGH : LOW);
digitalWrite(RELAY_PUMP, hum < 40.0 ? HIGH : LOW);
}
}
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void buttonTask(void *parametro) {
while (true) {
if (digitalRead(BUTTON_LIGHT) == LOW) {
lightState = !lightState;
digitalWrite(RELAY_LIGHT, lightState ? HIGH : LOW);
while (digitalRead(BUTTON_LIGHT) == LOW);
}
if (digitalRead(BUTTON_FAN) == LOW) {
fanState = !fanState;
digitalWrite(RELAY_FAN, fanState ? HIGH : LOW);
while (digitalRead(BUTTON_FAN) == LOW);
}
if (digitalRead(BUTTON_PUMP) == LOW) {
pumpState = !pumpState;
digitalWrite(RELAY_PUMP, pumpState ? HIGH : LOW);
while (digitalRead(BUTTON_PUMP) == LOW);
}
if (digitalRead(BUTTON_MODE) == LOW) {
manualMode = !manualMode;
while (digitalRead(BUTTON_MODE) == LOW);
}
if (digitalRead(BUTTON_PAGE) == LOW) {
page = !page;
while (digitalRead(BUTTON_PAGE) == LOW);
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
void printLCD(void *parametro) {
float umid, temp, lightLevel;
display.clearDisplay();
while(true) {
if (!page) {
if (xQueueReceive(umidade, &umid, 200) && xQueueReceive(temperatura, &temp, 200) && xQueueReceive(anhSang, &lightLevel, 200)) {
display.clearDisplay();
display.setCursor(0, 00);
display.print("Umid: "); display.print(umid); display.print(" %");
display.setCursor(0, 10);
display.print("Temp: "); display.print(temp); display.print(" C");
display.setCursor(0, 20);
display.print("Light: "); display.print(lightLevel); display.print(" %");
}
} else {
display.clearDisplay();
display.setCursor(0, 00);
display.print("Mode: "); display.print(manualMode ? "Manual" : "Auto");
display.setCursor(0, 10);
display.print("Fan: "); display.print(fanState ? "ON" : "OFF");
display.setCursor(0, 20);
display.print("Pump: "); display.print(pumpState ? "ON" : "OFF");
display.setCursor(0, 30);
display.print("Light: "); display.print(lightState ? "ON" : "OFF");
}
display.display();
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}