/*
Componente:
1. Arduino + Wifi Module(la alegere)
2. Senzor Lumina Brick (sistemul se pornește automat "noaptea" - sub un anumit prag)
3. LED-uri brick (roșu, galben și albastru)
4. Minidifuzor brick (semnal audio pentru alarmă)
5. Senzor distanta cu ultrasunete (declanșare alarmă de proximitate)
6. Tastatura
7. Un modul RTC (Real Time Clock)
Cerințe:
- La introducerea unui cod se pornește/oprește sistemul si se aprinde LED-ul rosu/verde.
- Să se realizeze simularea unui sistem de alarmă care pornește automat noaptea.
- În caz de alarma de proximitate (daca persoana se apropie prea mult de senzor)
se va declanșa alarma dupa 10 secunde (pentru a permite persoanei autorizate sa
dezarmeze de la distanta): LED-urile vor clipi intermitent (galben și albastru) și difuzorul va suna.
- Toate valorile se vor afișa pe Serial Monitor.
- Modulul RTC este folosit pentru a marca timpii la care s-au produs evenimentele.
- Toate datele vor fi salvate intr-o bază de date.
*/
#include <LiquidCrystal_I2C.h> //for LCD
//#include <Wire.h> //library for setting i2c pins
#include <RTClib.h> //For RTC
#include <Keypad.h> //for Keyboard
#include <WiFi.h> //For WiFi
#include <HTTPClient.h> //For http
//define RTC
RTC_DS1307 rtc;
//define LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
//define 4x4 Keypad
#define ROW_NUM 4 // four rows
#define COLUMN_NUM 4 // four columns
char keys[ROW_NUM][COLUMN_NUM] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
/*
They can't be used as outputs, so use these pins only as inputs:
GPIO 34.
GPIO 35.
GPIO 36.
GPIO 39.
*/
//define pin
#define PIN_RED 14 //led
#define PIN_GREEN 12 //led
#define PIN_BLUE 13 //led
#define PIN_TRIG 25 //distance sensor
#define PIN_ECHO 33 //distance sensor
#define LIGHT_SENSOR_PIN 35 //light sensor
#define SPEAKER_PIN 26 //Speaker
byte pin_rows[ROW_NUM] = {23, 2, 15, 19}; // Keyboard row pins
byte pin_column[COLUMN_NUM] = {4, 5, 18, 32}; // Keyboard column pins
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );
/*
//Set pins for I2C1 LCD
#define I2C1_SDA 21
#define I2C1_SCL 22
//Set pins for I2C2 RTC
#define I2C2_SDA 21
#define I2C2_SCL 22
*/
/*
TwoWire I2CLCD = TwoWire(0); //I2C1 bus
TwoWire I2CRTC = TwoWire(1); //I2C2 bus
*/
// LIGHT_SENSOR Characteristics https://docs.wokwi.com/parts/wokwi-photoresistor-sensor
//const float GAMMA = 0.7;
//const float RL10 = 50;
unsigned long DELAY_TIME = 500UL;
const String password = "1"; // 1234 change your password here
String input_password;
bool alarm_armed = 0; //stare alarma armat
bool alarm_triggered = 0; //stare alarma efractie
const int dist_min = 100;
int dist; //variabila dist
bool sensor_presence = 0;
bool timer_on = 0; //variabila pt time_before_alarm
//const float lux_light_min = 500;
//float lux = lux_light_min +1;
bool sensor_night = 0;
int msg_showed = 0;
int db_showed = 0;
unsigned long time_before_alarm = 10000UL; //10000UL miliseconds pt 10 sec
unsigned long DistPreviousMillis = 0UL;
unsigned long LedPreviousMillis = 0UL;
unsigned long currentMillis;
int red=1, green=1, blue=1; //save previous value of led - '1' is a random value given
int night_return;
int presence_return;
bool once_show = 0;
unsigned long lastTick = 0UL;
unsigned long currentTick;
int tensec = 11;
bool sec10WasSet;
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Defining the WiFi channel speeds up the connection:
#define WIFI_CHANNEL 1
//const char WIFI_SSID[] = "Wokwi-GUEST";
//const char WIFI_PASSWORD[] = "";
String HOST_NAME = "http://dbsecurity.000webhostapp.com"; // change to your PC's IP address
String PATH_NAME = "/insert_action.php";
//String queryString = "?temperature=30.5";
//*************************************************************************************
//https://techtutorialsx.com/2017/07/01/esp32-arduino-controlling-a-buzzer-with-pwm/
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
//*************************************************************************************
DateTime now;
DateTime sec10;
void setup()
{
// Init buses
/*
I2CLCD.begin(I2C1_SDA, I2C1_SCL); // Start I2C2 on pins 21 and 22
I2CRTC.begin(I2C2_SDA, I2C2_SCL); // Start I2C2 on pins 18 and 5
*/
input_password.reserve(16); // maximum input characters is 33, change if needed
lcd.init();
lcd.backlight();
Serial.begin(115200);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
lcd.setCursor(0, 0); //afiseaza mesaj doar la inceput
lcd.print("*-reset, #-enter");
lcd.setCursor(0, 1);
/*
WIFI Library statuses = Constants Value
WL_NO_SHIELD = 255
WL_IDLE_STATUS = 0
WL_NO_SSID_AVAIL = 1
WL_SCAN_COMPLETED = 2
WL_CONNECTED = 3
WL_CONNECT_FAILED = 4
WL_CONNECTION_LOST = 5
WL_DISCONNECTED = 6
*/
//WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
WiFi.begin("Wokwi-GUEST", "", 6);
Serial.println("Connecting");
lcd.print("Connecting WiFi ");
//while (WiFi.localIP().toString() == "0.0.0.0") {
//while (WiFi.waitForConnectResult() != WL_CONNECTED){
while(WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
lcd.setCursor(0, 1);
lcd.print("WiFi Connected !");
//configure pin as output
pinMode(PIN_RED, OUTPUT);
pinMode(PIN_GREEN, OUTPUT);
pinMode(PIN_BLUE, OUTPUT);
pinMode(LIGHT_SENSOR_PIN, INPUT);
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
pinMode(SPEAKER_PIN, OUTPUT);
//*************************************************************************************
//https://techtutorialsx.com/2017/07/01/esp32-arduino-controlling-a-buzzer-with-pwm/
// configure LED PWM functionalitites
ledcSetup(ledChannel, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(SPEAKER_PIN, ledChannel);
//*************************************************************************************
}
void save_DB(String msg)
{
now = rtc.now(); //get date time stamp
//char date_time[100];
//sprintf(date_time, "%02d/%02d/%02d %02d:%02d:%02d", now.year(),now.month(),now.day(), now.hour(),now.minute(),now.second());
String httpRequestData = "?message='" + (String(now.year(), DEC) + "-" + String(now.month(), DEC) + "-" + String(now.day(), DEC) + " "
+ String(now.hour(), DEC) + ":" + String(now.minute(), DEC) + ":" + String(now.second(), DEC) + "'" ) + ",'" + msg + "'";
httpRequestData.replace(" ","%20");
/*//testing purpose
//Serial.print("URL=");
//Serial.println(HOST_NAME + PATH_NAME + httpRequestData);
*/
HTTPClient http;
http.begin(HOST_NAME + PATH_NAME + httpRequestData); //HTTP
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpCode = http.GET();
// httpCode will be negative on error
// if(httpCode > 0)
{
// file found at server
// if(httpCode == HTTP_CODE_OK)
{
// String payload = http.getString();
// Serial.println(payload);
}
// else
{
// HTTP header has been send and Server response header has been handled
// Serial.printf("[HTTP] GET... code: %d\n", httpCode);
}
}
// else
{
// Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
// http.end();
}
void led_blink(int red1, int green1, int blue1, int dlay_time, int red2, int green2, int blue2)
{
//led_blink(255, 0, 0, 0, 255, 0, 0); //arm=1 si triggered=0
//led_blink(255, 255, 0, DELAY_TIME, 0, 0, 255); //arm=1 si triggered=1
//led_blink(0, 255, 0, 0, 0, 255, 0); //arm=0 si triggered=0
//led_blink(0, 255, 0, DELAY_TIME, 0, 0, 0); //arm=0 si triggered=1
currentMillis = millis();
if ((currentMillis - LedPreviousMillis) >= dlay_time)
{
LedPreviousMillis = currentMillis;
if(dlay_time == 0) //daca nu exista delay, se utilizeaza doar prima stare (red1, green1, blue1)
{
analogWrite(PIN_RED, red1);
analogWrite(PIN_GREEN, green1);
analogWrite(PIN_BLUE, blue1);
}
else //blink
{
if (red == red1 && green == green1 && blue == blue1)
{
red = red2;
green = green2;
blue = blue2;
}
else
{
red = red1;
green = green1;
blue = blue1;
}
analogWrite(PIN_RED, red);
analogWrite(PIN_GREEN, green);
analogWrite(PIN_BLUE, blue);
}
}
}
int light_sensor_check()
{
/*
//Read analog light sensor
int analogValue = analogRead(LIGHT_SENSOR_PIN);
float voltage = analogValue / 1024.0 * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
Serial.print("lux ");
Serial.println(lux);
if (lux < lux_light_min)
{
night_on = 1;
alarm_armed = 1;
Serial.println("night ");
}
*/
//read digital light sensor
if(digitalRead(LIGHT_SENSOR_PIN) == HIGH) //noapte
{
sensor_night = 1;
alarm_armed = 1;
return 1;
}
else //zi
{
sensor_night = 0;
return 0;
}
}
int dist_sensor_check()
{
// Start a new measurement from distance sensor
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10); //Microseconds sau miliseconds ??
digitalWrite(PIN_TRIG, LOW);
// Read the result from distance sensor
int duration = pulseIn(PIN_ECHO, HIGH);
//Serial.print("Distance in CM: ");
//Serial.println(duration / 58);
dist = duration/58;
char key = keypad.getKey();
if ((dist < dist_min) && (alarm_armed == 1))
{
check_password(key);
//if (once_show == 0) //verifica timp doar o data - aici e problema !!! ???
{
if(tenseconds()==1)
//currentMillis = millis(); //10 s ex: 9000
//if ( (currentMillis - DistPreviousMillis) >= (time_before_alarm) ) // daca a trcut timpul pentru dezarmare
{ //ex: 9000-0 >= 10000
DistPreviousMillis = currentMillis; //=11000
timer_on = 0;
sensor_presence = 1;
alarm_triggered = 1;
once_show = 1; // aici e problema !!! , dupa ce se executa o data, once_show se pune pe 1, si nu se mai executa acest bloc de instructiuni, de mutat codul de afisare separat
return 2;
}
else if (once_show == 0)// daca nu a trecut timpul pentru dezarmare
{
//Serial.println((currentMillis - DistPreviousMillis));// de sters sau pus sa afiseze secunde pe lcd ??
timer_on = 1; //variabila ce ia valoarea 1 doar daca nu a trecut perioada time_before_alarm
sensor_presence = 1;
alarm_triggered = 1;
return 1;
}
}
}
else if (dist >= dist_min)
{
check_password(key);
if ((alarm_triggered == 1) && (alarm_armed == 1)) //Daca alarma a fost triggered, chiar daca persoana iasa din raza de actiune a senzorului, numaratoarea secundelor sa continue
{
if(tenseconds()==1)
//if ((currentMillis - DistPreviousMillis) >= time_before_alarm) // daca a trcut timpul pentru dezarmare
{
DistPreviousMillis = currentMillis;
timer_on = 0;
sensor_presence = 1;
alarm_triggered = 1;
once_show = 1; // ????!!!!
return 2;
}
else if (once_show == 0)// daca nu a trecut timpul pentru dezarmare
{
timer_on = 1; //variabila ce ia valoarea 1 doar daca nu a trecut perioada time_before_alarm
sensor_presence = 1;
alarm_triggered = 1;
return 1;
}
}
else if(alarm_triggered == 0)
{
once_show = 0; // ????!!!!
sensor_presence = 0;
return 3;
}
}
return 0;
}
void check_password(char key)
{
if(key)
{
//Serial.println(key);
lcd.setCursor(0, 1);
if (key == '*')
{
input_password = ""; // reset - clear input password
lcd.print(" ");
}
else if (key == '#') // enter - submit password
{
if (password == input_password) //verificare daca e buna parola
{
if (alarm_armed == 1)
{
if (alarm_triggered == 1)
{
sec10WasSet = 0; //resetare variabila timp
tensec = 10; //resetare contor secunde
DistPreviousMillis = currentMillis; //resetare - linie de cod aflata in testare
Serial.println("WELLCOME HOME - ALARM DISARMED WITH PASSWORD!");
alarm_armed = 0; //
alarm_triggered = 0;
ledcWriteTone(ledChannel, 0); // stop alarm sound
save_DB("WELLCOME HOME - ALARM DISARMED WITH PASSWORD!");
for(int i=10;i>0;i--) //loop pentru ca persoana care dezarmeaza, sa aibe timp sa iasa din raza de actiune a senzorului
{
lcd.setCursor(0, 1);
lcd.print("DISARMING ");
lcd.print(i);
lcd.println(" s");
delay(1000); // 1000 pt 1 sec
}
lcd.setCursor(0, 1);
lcd.print("WELLCOME HOME!");
}
else // if (alarm_triggered == 0)
{
sec10WasSet = 0; //resetare variabila timp
tensec = 10; //resetare contor secunde
DistPreviousMillis = currentMillis; //resetare - linie de cod aflata in testare
Serial.println("ALARM DISARMED WITH PASSWORD!");
lcd.print("ALARM DISARMED! ");
alarm_armed = 0;
save_DB("ALARM DISARMED WITH PASSWORD!");
}
}
else //if (alarm_armed == 0)
{
Serial.println("ALARM ARMING!");
lcd.setCursor(0, 1);
//Serial.println("ALARM ARMED MANUAL!");
//lcd.print("ALARM ARMED MAN!");
alarm_armed = 1; //
alarm_triggered = 0;
once_show = 0;
for(int i=10;i>0;i--)
{
lcd.setCursor(0, 1);
lcd.print("ALARM ARMING! ");
lcd.print(i);
lcd.println(" s");
delay(1000); // 1000 pt 1 sec
}
//save_DB("ALARM ARMED MANUAL!");
}
}
else //if (password != input_password)
{
Serial.println("WRONG PASSWORD!");
lcd.print("WRONG PASSWORD!");
save_DB("WRONG PASSWORD!");
}
input_password = ""; // clear input password after enter
}
else //daca este apasata orice alta tasta
{
input_password += key; // append new character to input password string
if (input_password.length()==17) //tratare exceptie depasire caractere
{
lcd.print("$ ");
input_password = key; //resetare -in stringul in care se salveaza caract introd, se introduce doar ultimul caracter tastat
}
else
{
for (int i=0; i < input_password.length(); i++)
{
lcd.print("$");
}
for (int i=0; i < (16-input_password.length()); i++) //16 is number of characters in display line
{
lcd.print(" ");
}
}
}
}
}
void alarm_check()
{
night_return = light_sensor_check();
presence_return = dist_sensor_check();
lcd.setCursor(0, 1);
if(night_return == 1)
{
if(presence_return == 1) //cazul alarma activata - cu trigger in perioada time_before_alarm
{
led_blink(255, 0, 0, DELAY_TIME, 0, 0, 0); //Ledul Rosu va lumina intermitent
if(msg_showed != 1)
{
ledcWriteTone(ledChannel, 0); // stop alarm sound
Serial.println("ENTER PASSWORD!"); //timer_on??
lcd.print("ENTER PASSWORD! ");
//save_DB("ENTER PASSWORD!");
msg_showed = 1; //setare variabila msg_showed
}
}
else if(presence_return == 2) //cazul alarma activata - cu trigger dupa perioada time_before_alarm
{
led_blink(255, 255, 0, DELAY_TIME, 0, 0, 255); //Ledul galben si albastru va lumina intermitent
//*************************************************************************************
//https://techtutorialsx.com/2017/07/01/esp32-arduino-controlling-a-buzzer-with-pwm/
ledcWriteTone(ledChannel, 256); //solutie de compromis in lipsa unui buzzer activ pe Wokwi
//digitalWrite (SPEAKER_PIN, HIGH); //turn active buzzer on
//tone(SPEAKER_PIN, 262, 250); // for arduino
//*************************************************************************************
if(msg_showed != 2)
{
Serial.println("NIGHT ALARM TRIGGERED!"); //timer_on??
lcd.print("NGT ALARM TRIG! ");
save_DB("NIGHT ALARM TRIGGERED!");
msg_showed = 2; //setare variabila msg_showed
}
}
else if(presence_return == 3) //cazul alarma activata - fara trigger
{
led_blink(255, 0, 0, 0, 255, 0, 0); //ledul rosu este aprins
if(msg_showed != 3)
{
Serial.println("NIGHT ALARM ARMED!");
lcd.print("NGT ALARM ARMED!");
save_DB("NIGHT ALARM ARMED!");
msg_showed = 3; //setare variabila msg_showed
}
}
}
else //if(light_sensor_check() == 0)
{
if(alarm_armed == 1)
{
if(presence_return == 1) //cazul alarma activata - cu trigger in perioada time_before_alarm
{
led_blink(255, 0, 0, DELAY_TIME, 0, 0, 0); //Ledul Rosu va lumina intermitent
if(msg_showed != 4)
{
//de pus sa nu mai sune difuzorul!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ledcWriteTone(ledChannel, 0); // stop alarm sound
Serial.println("ENTER PASSWORD!"); //timer_on??
lcd.print("ENTER PASSWORD! ");
//save_DB("ENTER PASSW!"); //de sters
msg_showed = 4; //setare variabila msg_showed
}
}
else if(presence_return == 2) //cazul alarma activata - cu trigger dupa perioada time_before_alarm
{
led_blink(255, 255, 0, DELAY_TIME, 0, 0, 255); //Ledul galben si albastru va lumina intermitent
//*************************************************************************************
//https://techtutorialsx.com/2017/07/01/esp32-arduino-controlling-a-buzzer-with-pwm/
ledcWriteTone(ledChannel, 256); //solutie de compromis in lipsa unui buzzer activ pe Wokwi
//digitalWrite (SPEAKER_PIN, HIGH); //turn active buzzer on
//tone(SPEAKER_PIN, 262, 250); // for arduino
//************************************************************************************* if(msg_showed != 5)
{
Serial.println("DAY ALARM TRIGGERED!"); //timer_on??
lcd.print("DAY ALARM TRIG! ");
save_DB("DAY ALARM TRIGGERED!");
msg_showed = 5; //setare variabila msg_showed
}
}
else if(presence_return == 3) //cazul alarma activata - fara trigger
{
led_blink(255, 0, 0, 0, 255, 0, 0); //ledul rosu este aprins
if(msg_showed != 6)
{
Serial.println("DAY ALARM ARMED!");
lcd.print("DAY ALARM ARMED!");
save_DB("DAY ALARM ARMED!");
msg_showed = 6; //setare variabila msg_showed
}
}
}
else //if(alarm_armed == 0)
{
led_blink(0, 255, 0, 0, 0, 255, 0); //Ledul Verde este aprins
if(msg_showed != 7)
{
Serial.println("ALARM DISARMED!");
lcd.print("ALARM DISARMED! ");
msg_showed = 7; //setare variabila msg_showed
}
}
}
}
int tenseconds()
{
if ( (tensec > 0) && (sec10WasSet == 0) )
{
currentTick = millis();
if (currentTick - lastTick >= 1000UL)
{
lastTick = currentTick;
tensec = tensec - 1;
Serial.print("Asteptare ");
Serial.print(tensec);
Serial.println(" secunde ");
}
}
else if(tensec == 0)
{
sec10WasSet=1;
tensec = 10;
return 1;
}
return 0;
// if((now.second() == sec10.second()) && (sec10WasSet == 0) )// In 10 seconds
// {
// now=rtc.now();
// sec10 = (now + TimeSpan(0,0,0,10)); // variabila ce memoreaza cat va fi timpul peste 10 sec
// sec10WasSet = 1;
// return 0;
// }
// else if((now.second() == sec10.second()) && (sec10WasSet == 1) )
// {
// now=rtc.now();
// sec10 = (now + TimeSpan(0,0,0,10)); // variabila ce memoreaza cat va fi timpul peste 10 sec
// sec10WasSet == 0;
// Serial.print(now.second());
// Serial.print(" - ");
// Serial.println(sec10.second());
// return 1;
// }
// else
// {
// now=rtc.now();
// return 0;
// }
}
void loop() {
//delay(10);
char key = keypad.getKey();
//test*************************************
// now=rtc.now();
// sec10 = (now + TimeSpan(0,0,0,10));
//for(int i=0;i<2;i++) //for remembering
// if(tenseconds() == 1)
// {
// Serial.println("1 Succes 10s");
// // sec10WasSet = 0;
// }
//test*************************************
alarm_check();
check_password(key); //apelare functie verifica parola si armare-dezarmare
}