#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#include <DHT.h>
Servo myServo;
#include <ThingsBoard.h>
#include <PubSubClient.h>
/*// Khai báo các thông số kết nối WiFi và MQTT
#define WIFI_SSID "Khang Hy"
#define WIFI_PASSWORD "0947781757"
#define MQTT_SERVER "thingsboard.cloud"
#define MQTT_PORT 1883
#define MQTT_TOKEN "0ToL8YvSIBuNR8zcfeRv"
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
*/
// GPIO
#define DHTPIN 32
#define DHTTYPE DHT11
#define sensor 27
#define led 5
SemaphoreHandle_t xBinarySemaphore;//khởi tạo
QueueHandle_t xQueueTemp, xQueueHumidity, xQueueRain, xQueueStateBTN, xQueueCheckMode;//khởi tạo
//--------mutex đi kèm với semapho------//
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
SemaphoreHandle_t xMutex;
TaskHandle_t xHandle1;//khai báo có tác dụng điều chỉnh task còn lại trong task của chính mình
TaskHandle_t xHandle2;
TaskHandle_t xHandle3;
static int BTN_STATE;
void readSensor(void *params);// *params là 1 giá trị được truyền vào hàm
void taskChooseMode(void *params);//chọn chế độ hoạt động
void taskAutoMode(void *params);
void taskManualMode(void *params);
void rtos_delay(uint32_t delay_in_ms);
void setup(){
Serial.begin(115200);
lcd.init(); //Khởi động LCD
lcd.backlight(); //Mở đèn
connectWiFi();
connectMQTT();
pinMode(sensor, INPUT);
pinMode(led, OUTPUT);
SemaphoreHandle_t xBinarySemaphore;//khởi tạo
QueueHandle_t xQueueTemp, xQueueHumidity, xQueueRain, xQueueStateBTN, xQueueCheckMode;//khởi tạo
//--------mutex đi kèm với semapho------//
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
SemaphoreHandle_t xMutex;
TaskHandle_t xHandle1;//khai báo có tác dụng điều chỉnh task còn lại trong task của chính mình
TaskHandle_t xHandle2;
TaskHandle_t xHandle3;
static int BTN_STATE;
void readSensor(void *params);// *params là 1 giá trị được truyền vào hàm
void taskChooseMode(void *params);//chọn chế độ hoạt động
void taskAutoMode(void *params);
void taskManualMode(void *params);
void taskRoofOn(void *params);
void taskRoofOff(void *params);
void rtos_delay(uint32_t delay_in_ms);
// SET UP
void setup(){
Serial.begin(115200);
lcd.init(); //Khởi động LCD
lcd.backlight(); //Mở đèn
connectWiFi();
connectMQTT();
pinMode(SERVO_PIN, OUTPUT);
pinMode(RAINSENSOR_PIN, INPUT);
pinMode(AUTO_BUTTON, INPUT_PULLUP);
pinMode(MANU_BUTTON, INPUT_PULLUP);
myServo.attach(SERVO_PIN);
xQueueTemp = xQueueCreate(1, sizeof(float));// ví dụ chức năng: sau khi task sensor đọc dữ liệu xong thì task auto sẽ đọc dữ liệu để xét điều kiện bật hay tắt mái hiên
xQueueRain = xQueueCreate(1, sizeof(int));
xQueueHumidity = xQueueCreate(1, sizeof(float));
xQueueStateBTN = xQueueCreate(1, sizeof(int));
vSemaphoreCreateBinary(xBinarySemaphore);//khởi tạo
xMutex = xSemaphoreCreateMutex();
// ESP32 has 526KB SRAM
xTaskCreatePinnedToCore(readSensor, "ReadSensor", 10000, NULL, 3, &xHandle3, ARDUINO_RUNNING_CORE);// khởi tạo readsensor
xTaskCreatePinnedToCore(taskChooseMode, "ChooseModeUsing", 10000, NULL, 3, NULL, ARDUINO_RUNNING_CORE);// khởi tạo chosemode
}
void connectMQTT() {
Serial.print("Connecting to MQTT server: ");
Serial.println(MQTT_SERVER);
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
if (mqttClient.connect("ESP32Client", MQTT_TOKEN, NULL)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void connectWiFi() {
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop(){
vTaskDelete(NULL);//dùng để xóa dữ liệu trong loop
}
//-------task readsensor-------///
void readSensor(void *params){
float oldtemp = 0;// lưu trữ gí trị nhiệt độ cũ nếu xảy ra vấn đề thì sẽ truyền dữ liệu sang 2 biến h và t
float oldhumidity =0;
int r;
float t;
float h;
DHT dht(DHTPIN, DHTTYPE);
dht.begin();
xSemaphoreTake(xMutex, portMAX_DELAY);
for(;;){
vTaskDelay(1000 / portTICK_PERIOD_MS);
t = dht.readTemperature();
h = dht.readHumidity();
if (isnan(t)){
Serial.println("Faild to read from DHT11 sensor!");
t= oldtemp;
r= oldrain;
h= oldhumidity;
} else{
oldtemp = t;
oldhumidity = h;
}
lcd.setCursor(6,1); //Con trở ở vị trí 5, hiện ô 6
lcd.print(h);
lcd.setCursor(0,0);
lcd.print(t);
// Tạo chuỗi JSON chứa dữ liệu nhiệt độ và độ ẩm
String payload = "{";
payload += "\"t\":"; payload += t; payload += ",";
payload += "\"h\":"; payload += h; payload += ",";
payload += "\"r\":"; payload += r; payload += "}";
Serial.print("Sending data to ThingsBoard: ");
Serial.println(payload);
mqttClient.publish("v1/devices/me/telemetry", payload.c_str());
xSemaphoreGive(xMutex);
xQueueSendToBack(xQueueTemp,&t,0);//gửi giá trị t vào queue
//xQueueSendToBack(xQueueHumidity,&t,0);
Serial.print("Nhiet do moi truong: ");
Serial.println(t);
Serial.print(F("do am: "));
Serial.println(h);
lcd.display();
//lcd.clear(); // Clear the LCD display
rtos_delay(1000);
taskYIELD();
}
}
/*void taskChooseMode(void * params) {
static int temp ;//khởi tạo
for(;;) {
xQueueReceive(xQueueStateBTN,&temp,portMAX_DELAY);
Serial.print(temp);
if (temp == 0){
vTaskDelete(xHandle2);// xóa task manual
xTaskCreatePinnedToCore(taskAutoMode,"AutoMode",12288,NULL,2,&xHandle1,ARDUINO_RUNNING_CORE);
Serial.println(F("AUTO"));
}else if(temp == 1){
vTaskDelete(xHandle1);// xóa task auto
xTaskCreatePinnedToCore(taskManualMode,"ManualMode",12288,NULL,2,&xHandle2,ARDUINO_RUNNING_CORE);
Serial.println(F("MANUAL"));
}
rtos_delay(200);
taskYIELD();
}
}
void taskAutoMode(void * params) {
vTaskResume(xHandle3);//dùng taskreadsensor để đọc cảm biến
xSemaphoreTake(xMutex, portMAX_DELAY);
float Buff;
lcd.clear(); // Clear the LCD display
for(;;){ //chạy vòng
xQueueReceive(xQueueRain,&Buff,portMAX_DELAY);//lấy giá trị lượng mưa cho vào biến buff
Serial.println(F("Hello im auto"));// F có tác dụng lưu dữ liệu sẽ không bị mất khi tắt hoặc reset
if (Buff == 1){
xTaskCreatePinnedToCore(taskRoofOff,"TurnOFF",4096,NULL,4,NULL,0);
}else{
xTaskCreatePinnedToCore(taskRoofOn,"TurnON",4096,NULL,4,NULL,0);
}
xSemaphoreGive(xMutex);
rtos_delay(4000);
taskYIELD();
}
}*/