#include "DHTesp.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define LED 12
#define pump 13
#define DHT22_ID 0
#define LIGHT_ID 1
#define RAIN_ID 2
#define SOIL_ID 3
const int PIN_in1 = 33;
const int PIN_in2 = 32;
const int PIN_doAmDat = 34;
const int PIN_camBienMua = 15;
const int PIN_camBienAnhSang = 35;
int button1, button2, button3;
int trangThaiMayBom = 0;
int trangThaiDen = 0;
int trangThaiRem = 0;
int mode = 1;
int reff = 30;
static void dht22( void *pvParameters );
static void light( void *pvParameters );
static void rain( void *pvParameters );
static void soil( void *pvParameters );
static void lcdTask( void *pvParameters );
typedef struct {
byte deviceID;
float value1;
float value2;
} SENSOR;
QueueHandle_t queueSensor = xQueueCreate(8, sizeof(SENSOR));
void dht22(void *pvParameters) {
const byte dhtPin = 4;
DHTesp dhtSensor;
dhtSensor.setup(dhtPin, DHTesp::DHT22);
SENSOR dht22Sensor;
dht22Sensor.deviceID = DHT22_ID;
while (1) {
TempAndHumidity data = dhtSensor.getTempAndHumidity();
dht22Sensor.value1 = data.temperature;
dht22Sensor.value2 = data.humidity;
const TickType_t timeOut = 1000 / portTICK_PERIOD_MS;
if (xQueueSend(queueSensor, &dht22Sensor, timeOut) != pdPASS) {
Serial.println("DHT22: Queue is full.");
}
vTaskDelay(1000);
}
}
void light(void *pvParameters) {
pinMode(PIN_camBienAnhSang, INPUT_PULLUP);
SENSOR lightSensor;
lightSensor.deviceID = LIGHT_ID;
while (1) {
int light1 = digitalRead(PIN_camBienAnhSang);
float light = light1;
lightSensor.value1 = light;
lightSensor.value2 = 0.0;
const TickType_t timeOut = 1000 / portTICK_PERIOD_MS;
if (xQueueSend(queueSensor, &lightSensor, timeOut) != pdPASS) {
Serial.println("LDR: Queue is full.");
}
vTaskDelay(1000);
}
}
void rain(void *pvParameters) {
pinMode(PIN_camBienMua, INPUT_PULLUP);
SENSOR rainSensor;
rainSensor.deviceID = RAIN_ID;
while (1) {
int rain1 = digitalRead(PIN_camBienMua);
float rain = rain1;
rainSensor.value1 = rain;
rainSensor.value2 = 0.0;
const TickType_t timeOut = 1000 / portTICK_PERIOD_MS;
if (xQueueSend(queueSensor, &rainSensor, timeOut) != pdPASS) {
Serial.println("LDR: Queue is full.");
}
vTaskDelay(1000);
}
}
void soil(void *pvParameters) {
pinMode(PIN_doAmDat, INPUT_PULLUP);
SENSOR soilSensor;
soilSensor.deviceID = SOIL_ID;
while (1) {
int soil1 = digitalRead(PIN_doAmDat);
int percent = map(soil1, 0, 4095, 0, 100); // đưa về thang đo 0-100%
float soil = 100 - percent;
soilSensor.value1 = soil;
soilSensor.value2 = 0.0;
const TickType_t timeOut = 1000 / portTICK_PERIOD_MS;
if (xQueueSend(queueSensor, &soilSensor, timeOut) != pdPASS) {
Serial.println("LDR: Queue is full.");
}
vTaskDelay(1000);
}
}
void lcdTask(void *pvParameters) {
lcd.init();
lcd.backlight();
lcd.clear();
pinMode(LED, OUTPUT);
pinMode(pump, OUTPUT);
pinMode(PIN_in1, OUTPUT);
pinMode(PIN_in2, OUTPUT);
SENSOR data;
while (1) {
TickType_t timeOut = 2000;
if (xQueueReceive(queueSensor, &data, timeOut) == pdPASS) {
switch (data.deviceID) {
case DHT22_ID:
lcd.setCursor(0, 0);
lcd.print("Tem " + String(data.value1, 1) + "C");
lcd.setCursor(10, 0);
lcd.print("Humi " + String(data.value2, 1) + "%");
Serial.println("Tem: " + String(data.value1, 1) + "°C");
Serial.println("Humi: " + String(data.value2, 1) + "%");
break;
case LIGHT_ID:
lcd.setCursor(0, 1);
if (data.value1 == 1) {
lcd.print("Toi ");
lcd.setCursor(10, 1);
lcd.print("Den Bat");
batDen();
} else if(data.value1 == 0) {
lcd.print("Sang");
lcd.setCursor(10, 1);
lcd.print("Den Tat");
tatDen();
}
break;
case RAIN_ID:
lcd.setCursor(0, 2);
if (data.value1 == 1) {
lcd.print("Mua ");
lcd.setCursor(10, 2);
lcd.print("Rem Che");
batBomNuoc();
} else if(data.value1 == 0) {
lcd.print("Tanh");
lcd.setCursor(10, 2);
lcd.print("Rem Thu");
tatBomNuoc();
}
break;
case SOIL_ID:
lcd.setCursor(0, 3);
if (data.value1 < reff) {
lcd.print("Thieu");
lcd.setCursor(10, 3);
lcd.print("Bom Bat");
cheRem();
} else {
lcd.print("Du ");
lcd.setCursor(10, 3);
lcd.print("Bom Tat");
thuRem();
}
break;
default:
Serial.println("LCD: Unkown Device");
break;
}
} else {
Serial.println("LCD: Message Queue is Empty");
};
}
}
void batDen() {
digitalWrite(LED, HIGH); // Bật đèn
Serial.println("Đèn đã bật");
trangThaiDen = 1;
}
void tatDen() {
digitalWrite(LED, LOW); // Tắt đèn
Serial.println("Đèn đã tắt");
trangThaiDen = 0;
}
void batBomNuoc() {
digitalWrite(pump, HIGH); // Bật máy bơm nước
Serial.println("Máy bơm đã bật");
trangThaiMayBom = 1;
delay(10000);
digitalWrite(pump, LOW);
}
void tatBomNuoc() {
digitalWrite(pump, LOW); // Tắt máy bơm nước
Serial.println("Máy bơm đã tắt");
trangThaiMayBom = 0;
delay(10000);
}
void cheRem() { //Nguồn motor 12V
if (trangThaiRem == 0) {
digitalWrite(PIN_in1, LOW);
digitalWrite(PIN_in2, HIGH);
delay(10000);
// long now = millis();
// static long previous_time = 0;
// if (now - previous_time > 11000)
// {
// previous_time = now;
digitalWrite(PIN_in1, LOW);
digitalWrite(PIN_in2, LOW);
// }
}
trangThaiRem = 1;
Serial.println("Rèm đã che");
}
void thuRem() { // Nguồn motor 12V
if (trangThaiRem == 1) {
digitalWrite(PIN_in1, HIGH);
digitalWrite(PIN_in2, LOW);
delay(10000);
// long now = millis();
// static long previous_time = 0;
// if (now - previous_time > 11000)
// {
// previous_time = now;
digitalWrite(PIN_in1, LOW);
digitalWrite(PIN_in2, LOW);
// }
}
trangThaiRem = 0;
Serial.println("Rèm đã thu");
}
void setup()
{
Serial.begin(115200);
QueueHandle_t queueSensor = xQueueCreate(8, sizeof(SENSOR));
xTaskCreate(dht22, "DHT22", 1024 * 4, NULL, 1, NULL);
xTaskCreate(light, "LIGHT", 1024 * 4, NULL, 1, NULL);
xTaskCreate(rain, "RAIN", 1024 * 4, NULL, 1, NULL);
xTaskCreate(soil, "SOIL", 1024 * 4, NULL, 1, NULL);
xTaskCreate(lcdTask, "LCD", 1024*8 , NULL, 1, NULL);
}
void loop() {}