#include <Wire.h>
#include <DHTesp.h>
#include <RTClib.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#define pirPin 33
#define ldrPin 34
#define dhtPin 32
#define mq2Pin 35
//DHT dht(DHTPIN, DHTTYPE);
#define DHTTYPE DHT22
#define NOTE_CS1 35
#define NOTE_REST 0
#define NOTE_D8 4699
#define NOTE_E5 659
#define NOTE_F5 698
#define dhtControl 27
#define ldrControl 14
#define buzzerControl 13
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {19, 18, 5, 17};
byte colPins[COLS] = {16, 4, 2, 15};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int len_key = 4; // Độ dài của mật khẩu
char master_key_A[len_key] = {'1', '1','1','1'};
char attempt_key[len_key];
int z = 0;
// tạo mảng hẹn giờ
const int hen_gio = 2; // độ dài của giờ
char attempt_key_set[hen_gio];
int z1 = 0;
const int hen_phut = 2; // độ dài của phut
char attempt_key_set_P[hen_phut];
int z2 = 0;
int gio;
int phut;
int dhtNum;
int ldrNum;
int pirNum;
int mq2Num;
int melody[] = {
// Các giá trị nốt nhạc
NOTE_CS1, NOTE_F5, NOTE_CS1,
};
int noteDurations[] = {
// Thời gian của từng nốt nhạc
1, 1, 1,
};
RTC_DS3231 rtc;
DHTesp dhtSensor;
char daysOfWeek[7][12] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
LiquidCrystal_I2C lcd(0x27, 20, 4);
byte khung1[] = {B00000,B00000,B00000,B11111,B11111,B11000,B11000,B11000};
byte ngang[] = {B00000,B00000,B00000,B11111,B11111,B00000,B00000,B00000};
byte doc[] = {B11000,B11000,B11000,B11000,B11000,B11000,B11000,B11000};
byte khung3[] = {B11000,B11000,B11000,B11111,B11111,B00000,B00000,B00000};
byte khung2[] = {B00000,B00000,B00000,B11111,B11111,B00011,B00011,B00011};
byte khung4[] = {B00011,B00011,B00011,B11111,B11111,B00000,B00000,B00000};
byte doc1[] = {B00011,B00011,B00011,B00011,B00011,B00011,B00011,B00011};
SemaphoreHandle_t sem1;//
SemaphoreHandle_t sem2;
SemaphoreHandle_t sem3;
TaskHandle_t tsk1; //bien
TaskHandle_t tsk2;
TaskHandle_t tsk3;
TaskHandle_t tsk4; //bien //mode 1
TaskHandle_t tsk5; //mode2
TaskHandle_t tsk6; // mode3
int data;
QueueHandle_t queue = xQueueCreate(1, sizeof(int));
int count;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(pirPin, INPUT);
pinMode(ldrPin, INPUT);
pinMode(dhtPin, INPUT);
pinMode(mq2Pin, INPUT_PULLUP);
dhtSensor.setup(dhtPin, DHTesp::DHT11);
pinMode(buzzerControl, OUTPUT);
pinMode(ldrControl, OUTPUT);
pinMode(dhtControl, OUTPUT);
digitalWrite(dhtControl, LOW);
if (! rtc.begin()) {
Serial.println("RTC module is NOT found");
Serial.flush();
while (1);
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
sem1 = xSemaphoreCreateBinary();
sem2 = xSemaphoreCreateBinary();
xTaskCreate(lcd1, "lcd1", 3000, NULL, 2, &tsk1);
xTaskCreate(lcd2, "TaskB", 2000, NULL, 1, &tsk2);
xTaskCreate(nhapkeypad, "TaskC", 2000, NULL, 3, &tsk3);
//vTaskStartScheduler();
}
void BUZZER(){
for (int i = 0; i < sizeof(melody) / sizeof(melody[0]); i++) {
int noteDuration = 800 / noteDurations[i];
if (melody[i] != NOTE_REST) {
tone(buzzerControl, melody[i], noteDuration);
}
delay(noteDuration);
noTone(buzzerControl);
}
}
void loop() {
}
void lcd1 (void*){
xSemaphoreGive(sem1);
while(1){
xSemaphoreTake(sem1, portMAX_DELAY);
lcd.setCursor(0, 0);
lcd.print(" //RTOS// ");
lcd.setCursor(3, 2);
lcd.print("NHAP MAT KHAU");
lcd.setCursor(17, 3);
lcd.print("(1)");
lcd.createChar(0, khung1);
lcd.setCursor(2,1);
lcd.write(byte(0));
lcd.createChar(1, khung2);
lcd.setCursor(16,1);
lcd.write(byte(1));
lcd.createChar(2, khung3);
lcd.setCursor(2,3);
lcd.write(byte(2));
lcd.createChar(3, khung4);
lcd.setCursor(16,3);
lcd.write(byte(3));
lcd.createChar(4, ngang);
for (int i =3;i<16;i++){
lcd.setCursor(i,1);
lcd.write(byte(4));
}
lcd.createChar(5, doc);
lcd.setCursor(2,2);
lcd.write(byte(5));
lcd.createChar(6, doc1);
lcd.setCursor(16,2);
lcd.write(byte(6));
lcd.createChar(4, ngang);
for (int i =3;i<16;i++){
lcd.setCursor(i,3);
lcd.write(byte(4));
}
int count = 0;
while(count<1){
char non = keypad.getKey();
if(non){
Serial.print(non);
if(non = 1){
lcd.clear();
for (int i = 0; i < len_key; i++) {
attempt_key[i] = 0;
}
z = 0;
lcd.setCursor(0, 1);
lcd.print(" ");
xSemaphoreGive(sem2);
}
count++;}
}
}
}
void nhapkeypad(void*){
while(1){
xSemaphoreTake(sem2, portMAX_DELAY);
lcd.clear();
lcd.setCursor(0,1);
lcd.print("---ENTER PASSWORD---");
int count = 0;
while(count < 5){
lcd.setCursor(0,2);
lcd.setCursor(9+z, 2);
char key = keypad.getKey();
if(key){
Serial.print(key);
switch (key) {
case '*':
for (int i = 0; i < len_key; i++) {
attempt_key[i] = 0;
}
z = 0;
lcd.setCursor(0, 2);
lcd.print(" ");
break;
case 'D': {
int correct_A = 1;
for (int i = 0; i < len_key; i++) {
if (attempt_key[i] != master_key_A[i]) {
correct_A = 0;
break;
}
}
if ( correct_A) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" CORRECT PASSWORD ");
delay(1000);
lcd.clear();
data =1;
xQueueSend(queue, &data, portMAX_DELAY);
//lcd2();
}
else{
for (int i = 0; i < len_key; i++) {
attempt_key[i] = 0;
}
z = 0;
lcd.setCursor(0, 1);
lcd.print(" ");
}
break;
}
default:{
if (z < len_key) {
attempt_key[z] = key;
lcd.print('*');
z++;
}
if (z == len_key) {
break; }
}
}
count++;
}
}
}
}
void lcd2 (void*){
while(1){
xQueueReceive(queue, &data, portMAX_DELAY);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SELECT MODE ");
lcd.setCursor(0, 1);
lcd.print("mode1 [A] ");
lcd.setCursor(0, 2);
lcd.print("mode2 [B] ");
lcd.setCursor(0, 3);
lcd.print("mode3 [C] OUT [*]");
int count = 0;
while(count<1){
char key = keypad.getKey();
if(key){
Serial.print(key);
switch (key) {
case 'A':
lcd.clear();
z = 0;
z1 = 0;
z2 = 0;
//mode1();
xTaskCreate(mode1, "TaskB", 2000, NULL, 2, &tsk4);
break;
case 'B':
lcd.clear();
//mode2();
xTaskCreate(mode2, "TaskB", 2000, NULL, 2, &tsk5);
break;
case 'C':
lcd.clear();
xTaskCreate(mode3, "TaskB", 2000, NULL, 2, &tsk6);
break;
case '4':
lcd.clear();
// mode4();
break;
case '*':
lcd.clear();
//lcd2();
xSemaphoreGive(sem1);
break;
}
count++;
}
}
}
}
void mode1 (void*){
int count = 0;
while(count<1){
lcd.clear();
DateTime now = rtc.now();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.setCursor(6, 0);
lcd.print(now.hour(), DEC);
lcd.setCursor(8, 0);
lcd.print(":");
lcd.setCursor(9, 0);
lcd.print(now.minute(), DEC);
lcd.setCursor(11, 0);
lcd.print(":");
lcd.setCursor(12, 0);
lcd.print(now.second(), DEC);
lcd.setCursor(0, 1);
lcd.print("Date: ");
lcd.setCursor(6, 1);
lcd.print(now.day(), DEC);
lcd.setCursor(8, 1);
lcd.print(":");
lcd.setCursor(9, 1);
lcd.print(now.month(), DEC);
lcd.setCursor(11, 1);
lcd.print(":");
lcd.setCursor(12, 1);
lcd.print(now.year(), DEC);
lcd.setCursor(0, 2);
lcd.print("Turn on light until:");
lcd.setCursor(5, 3);
lcd.print(attempt_key_set[0]);
lcd.setCursor(6, 3);
lcd.print(attempt_key_set[1]);
lcd.setCursor(7, 3);
lcd.print("h ");
lcd.setCursor(9, 3);
lcd.print(attempt_key_set_P[0]);
lcd.setCursor(10, 3);
lcd.print(attempt_key_set_P[1]);
lcd.setCursor(11, 3);
lcd.print("m");
// nhập giờ để tắt điện
while (z1 != 2){
char keyS = keypad.getKey();
if(keyS){
if (z1 < hen_gio) {
attempt_key_set[z1] = keyS;
lcd.setCursor(5 + z1, 3);
lcd.print(attempt_key_set[z1]);
z1++;
}
}
}
// nhập phút để tắt điện
while (z2 != 2){
char keyX = keypad.getKey();
if(keyX){
if (z2 < hen_phut) {
attempt_key_set_P[z2] = keyX;
lcd.setCursor(9 + z2, 3);
lcd.print(attempt_key_set[z2]);
z2++;
}
}
}
// z1 = 0;
// chuyển mảng 2 ký tự sang số 2 chữ số
gio = (attempt_key_set[0] - '0')*10 + (attempt_key_set[1] - '0');
phut = (attempt_key_set_P[0] - '0')*10 + (attempt_key_set_P[1] - '0');
// so sánh điều kiện giờ để kích hoạt chế độ
if (now.hour() < gio){
digitalWrite(dhtControl, HIGH);
}
else
if (now.hour() == gio && now.minute() < phut){
digitalWrite(dhtControl, HIGH);
digitalWrite(ldrControl, HIGH);
}
else{
digitalWrite(dhtControl, LOW);
digitalWrite(ldrControl, LOW);
}
char non = keypad.getKey();
if(non){
Serial.print(non);
if(non = '1'){
lcd.clear();
digitalWrite(dhtControl, LOW);
for (int i = 0; i < len_key; i++) {
attempt_key[i] = 0;
}
z = 0;
lcd.setCursor(0, 1);
lcd.print(" ");
xQueueSend(queue, &data, portMAX_DELAY);
}
count++;
vTaskDelete(tsk4);
}
delay(1000);
}
}
void mode2 (void*){
int count = 0;
lcd.clear();
while(count<1){
pirNum = digitalRead(pirPin);
mq2Num = analogRead(mq2Pin);
TempAndHumidity data = dhtSensor.getTempAndHumidity();
lcd.setCursor(0, 0);
lcd.print("Hum: ");
lcd.setCursor(5, 0);
lcd.print(String(data.humidity, 2));
lcd.setCursor(9, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Tem: ");
lcd.setCursor(5, 1);
lcd.print(String(data.temperature, 1));
lcd.setCursor(9, 1);
lcd.print("*C");
lcd.setCursor(0, 2);
lcd.print("Gas: ");
lcd.setCursor(5, 2);
lcd.print(mq2Num);
lcd.setCursor(9, 2);
lcd.print("/1500");
if (pirNum){
lcd.setCursor(0, 3);
lcd.print("People: YES");
}
else
{
lcd.setCursor(0, 3);
lcd.print("People: NO ");
}
if (data.temperature > 70|| data.humidity > 80||mq2Num >= 1500|| pirNum == 1){
BUZZER();
}
delay(500);
char non = keypad.getKey();
if(non){
Serial.print(non);
if(non = '1'){
lcd.clear();
for (int i = 0; i < len_key; i++) {
attempt_key[i] = 0;
}
z = 0;
lcd.setCursor(0, 1);
lcd.print(" ");
xQueueSend(queue, &data, portMAX_DELAY);
}
count++;
vTaskDelete(tsk4);
}
}
}
void mode3 (void*){
int count = 0;
while(count<1){
pirNum = digitalRead(pirPin);
ldrNum = digitalRead(ldrPin);
TempAndHumidity data = dhtSensor.getTempAndHumidity();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hum: ");
lcd.setCursor(5, 0);
lcd.print(String(data.humidity, 2));
lcd.setCursor(9, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Tem: ");
lcd.setCursor(5, 1);
lcd.print(String(data.temperature, 1));
lcd.setCursor(9, 1);
lcd.print("*C");
if (ldrNum == 0){
lcd.setCursor(0, 3);
lcd.print("TROI SANG");
}
else{
lcd.setCursor(0, 3);
lcd.print("TROI TOI");
}
if (pirNum){
lcd.setCursor(0, 2);
lcd.print("People: YES");
}
else
{
lcd.setCursor(0, 2);
lcd.print("People: NO ");
}
if (pirNum == 1){
if (ldrNum == 0){
digitalWrite(ldrControl, LOW);
}
else{
digitalWrite(ldrControl, HIGH);
}
if (data.temperature > 40|| data.humidity > 70){
digitalWrite(dhtControl, HIGH);
}
else
{
digitalWrite(dhtControl, LOW);
}
}
else{
digitalWrite(dhtControl, LOW);
digitalWrite(ldrControl, LOW);
}
delay(1000);
char non = keypad.getKey();
if(non){
Serial.print(non);
if(non = '1'){
lcd.clear();
for (int i = 0; i < len_key; i++) {
attempt_key[i] = 0;
}
z = 0;
lcd.setCursor(0, 1);
lcd.print(" ");
xQueueSend(queue, &data, portMAX_DELAY);
}
count++;
vTaskDelete(tsk4);
}
}
}