#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 <Firebase_ESP_Client.h>
// Provide the token generation process info.
#include "addons/TokenHelper.h"
// Provide the RTDB payload printing info and other helper functions.
#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/"
// Variables will change:
int lastState = HIGH;
int currentState;
int t = 1;
const int stepsPerRevolution = 1000;
bool notiGas = false;
bool notiFlame = 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 15
#define DO_PIN 13
#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
DHT dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
Stepper myStepper(stepsPerRevolution, IN1, IN3, IN2, IN4);
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;
const long interval1 = 5000; // Khoảng thời gian cho cảm biến DHT
const long interval2 = 1500; // Khoảng thời gian cho cảm biến Gas
const long interval3 = 1000; // Khoảng thời gian cho cảm biến Flame
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;
unsigned long sendDataPrevMillis = 0;
bool signupOK = false;
void setup_Wifi()
{
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("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(300);
}
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);
Firebase.RTDB.setString(&fbdo, "common/LedStatus", "Off");
Firebase.RTDB.setString(&fbdo, "common/DoorStatus", "Close");
}
void setup()
{
Serial.begin(115200);
// set the speed at 5 rpm
myStepper.setSpeed(15);
dht_sensor.begin(); // initialize the DHT sensor
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();
}
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()
{
// step one revolution in one direction:
Firebase.RTDB.setString(&fbdo, "common/DoorStatus", "Open");
Serial.println("Door Opening");
myStepper.step(stepsPerRevolution);
delay(1000);
}
void actDongCua()
{
// step one revolution in the other direction:
Firebase.RTDB.setString(&fbdo, "common/DoorStatus", "Close");
Serial.println("Door Closing");
myStepper.step(-stepsPerRevolution);
delay(1000);
}
void DHT_sensor()
{
float humi = dht_sensor.readHumidity() * 5.0;
float tempC = dht_sensor.readTemperature() + 25.0;
float tempF = dht_sensor.readTemperature(true) + 25.0;
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 pushToFirebase()
{
if (Firebase.ready() && signupOK)
{
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);
}
else {
return;
}
}
void setup_Led(){
Firebase.RTDB.getString(&fbdo, "common/LedStatus");
LedStatus = fbdo.stringData();
if (LedStatus == "On")
{
digitalWrite(LED_PIN, HIGH);
}
else if (LedStatus == "Off")
{
digitalWrite(LED_PIN, LOW);
}
}
void setup_Door()
{
Firebase.RTDB.getString(&fbdo, "common/DoorStatus");
DoorStatus = fbdo.stringData();
if (DoorStatus == "Open" && t == 1)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actMoCua();
t = 2;
}
else if (DoorStatus == "Close" && t == 2)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actDongCua();
t = 1;
}
}
void actKey()
{ char key = keypad.getKey();
if (key == '#' && t == 2)
{
actDongCua();
t = 1;
}
if (key)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
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();
nhay();
t = 2;
while (1)
{
char key1 = keypad.getKey();
currentState = digitalRead(BUTTON_PIN_Door);
if (key1 == '#')
{
actDongCua();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("Nhap mat khau: ");
display.display();
t = 1;
break;
}
if (lastState == HIGH && currentState == LOW && t == 2)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actDongCua();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("Nhap mat khau: ");
display.display();
t = 1;
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 = "";
}
else
{
input_password += key;
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 40);
display.println(input_password);
display.display();
}
}
}
void actButtonLed(){
if (digitalRead(BUTTON_PIN_Led) == HIGH) {
digitalWrite(LED_PIN, HIGH);
}
else {
digitalWrite(LED_PIN, LOW);
}
}
void actButtonDoor()
{
currentState = digitalRead(BUTTON_PIN_Door);
if (lastState == HIGH && currentState == LOW && t == 1)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actMoCua();
t = 2;
}
currentState = digitalRead(BUTTON_PIN_Door);
if (lastState == HIGH && currentState == LOW && t == 2)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
actDongCua();
t = 1;
}
}
bool isConnectedToFirebase = false;
void loop()
{
unsigned long currentMillis = millis();
if (WiFi.status() == WL_CONNECTED) {
isConnectedToFirebase = true;
} else {
isConnectedToFirebase = false;
}
actButtonDoor();
actButtonLed();
actKey();
if (currentMillis - previousMillis3 >= interval3)
{
previousMillis3 = currentMillis;
DHT_sensor();
}
if (currentMillis - previousMillis2 >= interval2)
{
previousMillis2 = currentMillis;
gasSensor();
flameSensor();
}
if (isConnectedToFirebase) {
// Gửi dữ liệu lên Firebase
setup_Door();
setup_Led();
if (currentMillis - previousMillis1 >= interval1)
{
previousMillis1 = currentMillis;
pushToFirebase();
}
}
}