#include <ESP32Firebase.h>
//DHT
#include "DHT.h"
#include <WiFi.h>
//SERVO
#include <ESP32Servo.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
//OLED
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define DATABASE_URL "https://smart-city-f6b1d-default-rtdb.firebaseio.com/" // Url của Firebase Realtime Database
#define WIFI_SSID "Wokwi-GUEST" // Your WiFi SSID
#define WIFI_PASSWORD "" // Your WiFi Password
//LED
#define LEDX 13
#define LEDD 12
//BUTTON
#define BUTTON_PIN 4 // Chân GPIO kết nối nút nhấn
//DHT
#define DHTTYPE DHT22 // Định nghĩa loại cảm biến DHT22
#define DHTPIN 14 // Chân GPIO kết nối cảm biến DHT
//OLED
#define SCREEN_WIDTH 128 // OLED width, in pixels
#define SCREEN_HEIGHT 64 // OLED height, in pixels
// create an OLED display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
DHT dht(DHTPIN, DHTTYPE); // Khởi tạo cảm biến DHT
Firebase firebase(DATABASE_URL);
WiFiClient client;
Servo servo;
// Task handles
TaskHandle_t Task1;
TaskHandle_t Task2;
TaskHandle_t Task3;
TaskHandle_t Task4;
// Global variable to track high temperature status
volatile bool highTemp = false;
volatile bool buttonPressed = false; // Track button press state
bool ledOn = false; // Track LED state
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
//PIR+SECVO
pinMode(5, INPUT); // Checks the status of the motion sensor
servo.attach(15); // Takes the servo input pin as 15
//BUTTON
pinMode(BUTTON_PIN, INPUT_PULLUP); // Setup button pin with internal pull-up
//LED
pinMode(LEDX, OUTPUT);
pinMode(LEDD, OUTPUT);
//DHT
dht.begin();
//OLED
// initialize OLED display with I2C address 0x3C
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("failed to start SSD1306 OLED"));
while (1);
}
delay(2000); // wait two seconds for initializing
oled.clearDisplay(); // clear display
oled.setTextSize(1); // set text size
oled.setTextColor(WHITE); // set text color
oled.setCursor(0, 2); // chỉnh vị trí (x,y)
oled.println("LETRANMYLINH"); // chỉnh text
oled.display(); // display on OLED
// Create FreeRTOS tasks
xTaskCreatePinnedToCore(send_sensor_task, "Task1", 5120, NULL, 1, &Task1, 0);
xTaskCreatePinnedToCore(pir_servo_task, "Task2", 2048, NULL, 1, &Task2, 1);
xTaskCreatePinnedToCore(blink_led_task, "Task3", 4096, NULL, 1, &Task3, 1);
xTaskCreatePinnedToCore(button_task, "Task4", 2048, NULL, 1, &Task4, 1);
}
void send_sensor_task(void * pvParameters){
for(;;){
float h = dht.readHumidity();
float t = dht.readTemperature();
//LED DO
if(t > 60) {
highTemp = true;
} else {
highTemp = false;
}
Serial.print("Nhiet do: ");
Serial.print(t);
Serial.print("ºC ");
Serial.print("Do am: ");
Serial.print(h);
Serial.println("% ");
firebase.setFloat("Do/Nhietdo/Phongngu", t);
firebase.setFloat("Do/Doam/Phongngu", h);
vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 1 second before reading again
}
}
//PIR+SERVO
void pir_servo_task(void * pvParameters){
for(;;){
int input = digitalRead(5); // Reads the value of the 5 pin
Serial.print("Gia tri Pir: ");
Serial.println(input); // Produces if it is high or low on the terminal
if(input == 1) { // Checks if the motion sensor has been tripped
servo.write(100); // Makes the servo motor move by 100 degrees
digitalWrite(LEDX,HIGH);
} else { // If not tripped
servo.write(0); // Returns the servo back to original position
digitalWrite(LEDX,LOW);
}
vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay between the motion sensor and servo
}
}
//LED DO NHAP NHAY
void blink_led_task(void * pvParameters){
for(;;){
if(highTemp) {
digitalWrite(LEDD, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS); // LED on for 0.5 second
digitalWrite(LEDD, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS); // LED off for 0.5 second
} else {
digitalWrite(LEDD, LOW); // Ensure LED is off if temperature is not high
vTaskDelay(1000 / portTICK_PERIOD_MS); // Check every 1 second
}
}
}
//BUTTON
void button_task(void * pvParameters){
bool lastButtonState = HIGH;
for(;;){
bool buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW && lastButtonState == HIGH) {
// Button is pressed
buttonPressed = !buttonPressed; // Toggle button pressed state
if (buttonPressed) {
// Turn on LED if button is pressed for the first time
highTemp = !highTemp;
}
vTaskDelay(200 / portTICK_PERIOD_MS); // Debounce delay
}
lastButtonState = buttonState;
vTaskDelay(10 / portTICK_PERIOD_MS); // Small delay to prevent task from consuming too much CPU
}
}
void loop() {
// Empty because tasks are handled by FreeRTOS
}