#include <Keypad.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>
#include <DHT.h>
#include <ezBuzzer.h>
#include <ezButton.h>
#include <Stepper.h>
#include <Arduino.h>
#include <WiFi.h>
#include "DHTesp.h"
#include <Firebase_ESP_Client.h>
#include<freertos/FreeRTOS.h>
#include<freertos/task.h>
#include "addons/TokenHelper.h"
#include "addons/RTDBHelper.h"
#define WIFI_SSID "Free"
#define WIFI_PASSWORD "00000000"
#define API_KEY "AIzaSyA23hg-I_0qNzDZicOfEfOwMYy1FqndvLA"
#define DATABASE_URL "https://smarthome-6c436-default-rtdb.asia-southeast1.firebasedatabase.app/"
#define stepsPerRevolution 1024
int currentState,currentState1;
bool notiGas = false;
bool notiFlame = false;
bool statusDoor = false;
bool statusLed = false;
int valGas = 0;
float valTemC = 0.0, valTemF = 0.0, valHumi = 0.0;
#define DEBOUNCE_TIME 50
#define BUTTON_PIN_Door 23
#define BUTTON_PIN_Led 13
#define DO_PIN 35
#define IN1 4
#define IN2 16
#define IN3 17
#define IN4 5
#define BUZZER_PIN 15
#define LED_PIN 2
#define AO_PIN 34 // ESP32's pin GPIO36 connected to AO pin of the MQ2 sensor
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define ROW_NUM 4 // four rows
#define COLUMN_NUM 4 // four columns
#define DHT_SENSOR_PIN 19 // ESP32 pin GPIO21 connected to DHT11 sensor
#define DHT_SENSOR_TYPE DHT11
TaskHandle_t task_handler1;
TaskHandle_t task_handler2;
TaskHandle_t task_handler3;
TaskHandle_t task_handler4;
DHTesp dht_sensor;
Stepper myStepper(stepsPerRevolution, IN1, IN3, IN2, IN4);
char keys[ROW_NUM][COLUMN_NUM] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}};
byte pin_rows[ROW_NUM] = {14, 27, 26, 25}; // GPIO18, GPIO5, GPIO17, GPIO16 connect to the row pins
byte pin_column[COLUMN_NUM] = {33, 32, 18, 0}; // GPIO4, GPIO0, GPIO2 connect to the column pins
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
const String password_1 = "12345"; // change your password here
const String password_2 = "00000"; // change your password here
const String password_3 = "11111"; // change your password here
String input_password;
String DoorStatus = "";
String LedStatus = "";
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Define Firebase Data object
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
bool signupOK = false;
void setup_Wifi()
{
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.println("Connecting to Wi-Fi");
if (WiFi.status() != WL_CONNECTED)
{
Serial.println(WiFi.status());
Serial.println(WiFi.SSID());
Serial.println(WiFi.psk());
}
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
}
void setup_Firebase()
{
/* Assign the api key (required) */
config.api_key = API_KEY;
/* Assign the RTDB URL (required) */
config.database_url = DATABASE_URL;
/* Sign up */
if (Firebase.signUp(&config, &auth, "", ""))
{
Serial.println("ok");
signupOK = true;
}
else{
Serial.printf("%s\n", config.signer.signupError.message.c_str());
}
/* Assign the callback function for the long running token generation task */
config.token_status_callback = tokenStatusCallback; // see addons/TokenHelper.h
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
}
void nhay()
{
int t = 3;
while (t-- > 0)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
}
}
void nhay1()
{
int t = 20;
while (t-- > 0)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
}
}
void actMoCua()
{
statusDoor = true;
Serial.println("Door Opening");
myStepper.step(stepsPerRevolution);
}
void actDongCua()
{
statusDoor= false;
Serial.println("Door Closing");
myStepper.step(-stepsPerRevolution);
}
void DHT_sensor()
{
float humi = dht_sensor.getHumidity() * 5;
float tempC = dht_sensor.getTemperature() + 25.0;
float tempF = dht_sensor.toFahrenheit(tempC) ;
valTemC = tempC;
valTemF = tempF;
valHumi = humi;
if (isnan(tempC) || isnan(tempF) || isnan(humi))
{
Serial.println("Failed to read from DHT sensor!");
}
else{
Serial.print("Humidity: ");
Serial.print(humi);
Serial.print("%");
Serial.print(" | ");
Serial.print("Temperature: ");
Serial.print(tempC);
Serial.print("°C ~ ");
Serial.print(tempF);
Serial.println("°F");
}
}
void flameSensor()
{
int flame_state = digitalRead(DO_PIN);
if (flame_state == HIGH)
{
notiFlame = false;
Serial.println("No flame dected => The fire is NOT detected");
}
else
{
notiFlame = true;
nhay1();
Serial.println("Flame dected => The fire is detected");
}
}
void gasSensor()
{
int gasValue = analogRead(AO_PIN);
valGas = gasValue;
if (isnan(gasValue))
{
notiGas = false;
Serial.println("Failed to read from gas sensor !");
return;
}
if (gasValue >= 1000)
{
nhay1();
notiGas = true;
}
else
{
notiGas = false;
}
Serial.print("MQ2 sensor AO value: ");
Serial.println(gasValue);
}
void setup_Led(){
Firebase.RTDB.getString(&fbdo, "common/LedStatus");
LedStatus = fbdo.stringData();
if (LedStatus == "On" && !statusLed)
{
statusLed = true;
digitalWrite(LED_PIN, HIGH);
}
else if (LedStatus == "Off" && statusLed)
{
statusLed = false;
digitalWrite(LED_PIN, LOW);
}
}
void setup_Door()
{
Firebase.RTDB.getString(&fbdo, "common/DoorStatus");
DoorStatus = fbdo.stringData();
if (DoorStatus == "Open" && !statusDoor)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actMoCua();
}
else if (DoorStatus == "Close" && statusDoor)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actDongCua();
}
}
void actButtonLed(void *pvParameter)
{
while(1){
currentState1 = digitalRead(BUTTON_PIN_Led);
if ( currentState1 == LOW && !statusLed)
{
Firebase.RTDB.setString(&fbdo, "common/LedStatus","On");
statusLed= true;
digitalWrite(LED_PIN, HIGH);
delay(500);
}
currentState1 = digitalRead(BUTTON_PIN_Led);
if (currentState1 == LOW && statusLed)
{
Firebase.RTDB.setString(&fbdo, "common/LedStatus","Off");
statusLed= false;
digitalWrite(LED_PIN, LOW);
delay(500);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void actButtonDoor(void *pvParameter)
{ while(1){
currentState = digitalRead(BUTTON_PIN_Door);
if (currentState == LOW && !statusDoor)
{
Firebase.RTDB.setString(&fbdo, "common/DoorStatus","Open");
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actMoCua();
}
currentState = digitalRead(BUTTON_PIN_Door);
if (currentState == LOW && statusDoor)
{
Firebase.RTDB.setString(&fbdo, "common/DoorStatus","Close");
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actDongCua();
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void actKey(void *pvParameter)
{
while(1){
char key = keypad.getKey();
if (key == '#' && statusDoor)
{
actDongCua();
Firebase.RTDB.setString(&fbdo, "common/DoorStatus","Close");
}
if (key)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
if (key == '*')
{
input_password = ""; // reset the input password
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
// Display static text
display.println("Nhap mat khau: ");
display.display();
}
else if (key == '#')
{
if (input_password == password_1 || input_password == password_2 || input_password == password_3)
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(1, 30);
display.println("The password is correct!");
display.display();
actMoCua();
Firebase.RTDB.setString(&fbdo, "common/DoorStatus","Open");
nhay();
input_password = "";
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("Nhan'#'de dong cua!");
display.display();
while (1)
{
char key1 = keypad.getKey();
currentState = digitalRead(BUTTON_PIN_Door);
if (key1 == '#' && statusDoor)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actDongCua();
Firebase.RTDB.setString(&fbdo, "common/DoorStatus","Close");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("Nhap mat khau: ");
display.display();
break;
}
if (currentState == LOW && statusDoor)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actDongCua();
Firebase.RTDB.setString(&fbdo, "common/DoorStatus","Close");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
// Display static text
display.println("Nhap mat khau: ");
display.display();
break;
}
}
}
else if (input_password.length() != 0)
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("The password is incorrect!");
display.display();
nhay1();
}
input_password = "";
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("Nhap mat khau: ");
display.display();
}
else
{
input_password += key;
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 40);
display.println(input_password);
display.display();
}
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void pushToFirebase(void *pvParameter)
{
dht_sensor.setup(DHT_SENSOR_PIN, DHTesp::DHT_SENSOR_TYPE);
while(1){
gasSensor();
DHT_sensor();
flameSensor();
if (Firebase.ready()){
setup_Led();
setup_Door();
Firebase.RTDB.setInt(&fbdo, "common/GasValue/ValueGas", valGas);
Firebase.RTDB.setBool(&fbdo, "common/GasValue/notiGas", notiGas);
Firebase.RTDB.setFloat(&fbdo, "common/Humidity", valHumi);
Firebase.RTDB.setBool(&fbdo, "common/NotiFlame", notiFlame);
Firebase.RTDB.setFloat(&fbdo, "common/Temperature/tempC", valTemC);
Firebase.RTDB.setFloat(&fbdo, "common/Temperature/tempF", valTemF);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void setTask(){
// xTaskCreate( pushToFirebase,"pushToFirebase", 100000, NULL, 1, &task_handler1);
xTaskCreate( actKey,"setKey", 10000, NULL, 0, &task_handler2);
xTaskCreate( actButtonDoor,"actButtonDoor", 10000, NULL, 0, &task_handler3);
xTaskCreate( actButtonLed,"actButtonLed", 10000, NULL, 0, &task_handler4);
vTaskStartScheduler();
}
void setup()
{
Serial.begin(115200);
myStepper.setSpeed(20);
pinMode(BUTTON_PIN_Door, INPUT_PULLUP);
pinMode(BUTTON_PIN_Led, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(DO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{ // Address 0x3D for 128x64
Serial.println(F("Man Hinh bi hong?"));
for (;;)
;
}
display.setFont(&FreeSerif9pt7b);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("Nhap mat khau: ");
display.display();
setup_Wifi();
setup_Firebase();
Firebase.RTDB.setString(&fbdo, "common/LedStatus", "Off");
Firebase.RTDB.setString(&fbdo, "common/DoorStatus", "Close");
digitalWrite(LED_PIN, LOW);
setTask();
}
void loop(){
vTaskDelete(NULL);
}