#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
//inizializza l'lcd 16 colonne 2 righe all'indirizzo 0x27
LiquidCrystal_I2C lcd(0x27, 16, 2);
//Variable
bool passc = true;//se true accetta l'inserimento della password per inserire/disinserire l'allarme
bool ins = false;//se true indica che l'allarme è inserito
bool home = true;//se l'arduino ritorna nel loop dopo che la password è corretta inserisce l'allarme
bool man = false;//se true indica che lo stato di manutenzione è attivo
bool almMan = false;//indica se l'allarme è scattato a causa dei sensori anti-manomissione
bool passmanc = false;//se true accetta l'inserimento della password per inserire/disinserire la modalità di manutenzione
bool hardReset = false;//se true indica ad arduino di resettarsi
const unsigned long durata = 15000;//tempo dopo il quale l'allarme scatta se viene aperto il circuito del pre allarme (pin 12 LOW)
const unsigned long durataIns = 10000;//tempo dopo il quale l'arduino ritorna nel menu principale se non viene premuto alcun tasto
long noRetro = 0;//valore che si aggiorna dopo ogni pressione di un tasto (gestione retro illuminazione)
unsigned long startTime = 0;
long tempIns = 0;//valore che si aggiorna dopo ogni pressione di un tasto quando si inserisce la password
bool condizione;//viene aggiornata con allarme inserito con il valore logico del pin 12
bool reset;//indica al timer del pre-allarme se può resettarsi
bool canSound = false;//indica se il buzzer può suonare
char key;//contiene il carattere premuto sul keypad
const byte ROWS = 4; //4 righe
const byte COLS = 4; //4 colonne
char keys[ROWS][COLS] = {
{'1','2','3','a'},
{'4','5','6','b'},
{'7','8','9','c'},
{'*','0','#','d'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; //pin righe keypad
byte colPins[COLS] = {5, 4, 3, 2}; //pin colonne keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );//keymap
char password[5] = "b030";//password
char tempPassword[5];//contiene la password inserita dall'utente
int tempPasswordIndex = 0;//contiene l'ndice della password inserita dall'utente
//funzione inserimento password per inserimento/disinserimento allarme
void pass(){
key = keypad.getKey();//memorizza il tasto premuto sul keypad
//ritorna nel menu principale se non si preme un tasto da piu del tempo inserito in durataIns o se si preme il tasto '#'
if (millis() - tempIns >= durataIns || key == '#') {
passc = false;//non permette l'inserimento della password
home = false;//fa in modo che non venga inserito l'allarme
hardReset = false;//reimposta la variabile per il reset della scheda
lcd.clear();
//resetta la password
for(int i; i >= 5; i++){
tempPassword[i] = "";
}
tempPasswordIndex = 0;
}
//se il tasto premuto non è '#'
else if (key){
noRetro = millis();//salva quando è stato premuto il tasto
tempPassword[tempPasswordIndex] = key; //legge la password
tempPasswordIndex++;//aumenta l'indice di 1
lcd.setCursor(tempPasswordIndex - 1,1);//imposta il cursore sul display
lcd.print(F("*"));//stampa il carattere '*' sull'lcd
//tone(1,1200, 20);
//delay(20);
//noTone(1);
if(tempPasswordIndex>4) //controlla se l'indice password è maggiore di 4
{
tempPasswordIndex = 0;//resetta l'indice della password
if(checkPassword()) //se la password è corretta
{
//indica all'utente che la password è corretta con una scritta sull'lcd
lcd.clear();
lcd.setCursor(4, 1);
lcd.print(F("DifAlarm"));
delay(500);
lcd.setCursor(3,0);
lcd.print(F("Password V"));
delay(500);
passc = false;//esce dal ciclo di inserimento password
reset = false;//indica al timer del pre-allarme che può resettarsi
condizione = false;//questa riga serve nella funzione scattopre() per far si che legga lo stato logico del pin 12
//se si è entrati nella funzione con il tasto 'd' resetta la scheda
if (hardReset){
lcd.clear();
lcd.setCursor(4, 1);
lcd.print(F("DifAlarm"));
lcd.setCursor(4, 0);
lcd.print(F("Reset"));
delay(150);
lcd.print(F("."));
tone(1, 1200);
delay(50);
noTone(1);
delay(250);
lcd.print(F("."));
tone(1, 1200);
delay(50);
noTone(1);
delay(250);
lcd.print(F("."));
tone(1, 1200);
delay(200);
digitalWrite(0,HIGH);//attiva il rele collegato sul reset
}
lcd.clear();
}
else //se la password è sbagliata
{
//indica all'utente che la password è sbagliata con una scritta sull'lcd
lcd.clear();
lcd.setCursor(4, 1);
lcd.print(F("DifAlarm"));
delay(500);
lcd.setCursor(3,0);
lcd.print(F("Password X"));
delay(500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Password"));
}
}
}
//delay(50);
}
//----------------------------------------
//funzione inserimento password per attivazione/disattivazione stato di manutenzione
void passman(){
key = keypad.getKey();//memorizza il tasto premuto sul keypad
//ritorna nel menu principale se non si preme un tasto da piu del tempo inserito in durataIns o se si preme il tasto '#'
if (millis() - tempIns >= durataIns || key == '#') {
passmanc = false;
lcd.clear();
for(int i; i >= 5; i++){
tempPassword[i] = "";
}
tempPasswordIndex = 0;
}
//se il tasto premuto non è '#'
else if (key){
noRetro = millis();//salva quando è stato premuto il tasto
tempPassword[tempPasswordIndex] = key; //legge la password
tempPasswordIndex++;//aumenta l'indice di 1
lcd.setCursor(tempPasswordIndex - 1,1);//imposta il cursore sul display
lcd.print(F("*"));//stampa il carattere '*' sull'lcd
tone(1,1200);
delay(20);
noTone(1);
if(tempPasswordIndex>4) //controlla se l'indice password è maggiore di 4
{
tempPasswordIndex = 0;//resetta l'indice della password
if(checkPassword()) //se la password è corretta
{
//indica all'utente che la password è corretta con una scritta sull'lcd
lcd.clear();
lcd.setCursor(4, 1);
lcd.print(F("DifAlarm"));
delay(500);
lcd.setCursor(3,0);
lcd.print(F("Password V"));
delay(500);
passmanc = false;//esce dal ciclo di inserimento della password
//se l'allarme è inserito lo disinserisce
if(ins){
ins = false;
}
//se l'allarme è scattato a causa dei sensori anti-manomissione lo disattiva
if (almMan){
almMan = false;
}
man = !man;//inverte la variabile che determina lo stato di manutenzione
lcd.clear();
}
else //indica all'utente che la password è sbagliata con una scritta sull'lcd
{
lcd.clear();
lcd.setCursor(4, 1);
lcd.print(F("DifAlarm"));
delay(500);
lcd.setCursor(3,0);
lcd.print(F("Password X"));
delay(500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Password"));
}
}
}
delay(50);
}
//controlla se la password è corretta oppure no
boolean checkPassword(){
if(strncmp(password, tempPassword, 4) == 0)
{
return true;
}
else {
return false;
}
}
//controlla i pin collegati ai sensori
void controllo(){
lcd.setCursor(14, 0);
//se il pin è su alto stampa il carattere 'v'
if(digitalRead(13) == HIGH){
lcd.print(F("V"));
}
//altrimenti se il pin è su basso stampa il carattere 'x'
else if(digitalRead(13) == LOW){
lcd.print(F("X"));
}
lcd.setCursor(15, 0);
//se il pin è su alto stampa il carattere 'v'
if(digitalRead(12) == HIGH){
lcd.print(F("V"));
}
//altrimenti se il pin è su basso stampa il carattere 'x'
else if(digitalRead(12) == LOW){
lcd.print(F("X"));
}
}
//gestisce la retro illuminazione
void retro(){
//se l'allarme NON è scattato
if (digitalRead(11) == LOW){
//se sono passati 5sec dall'ultima pressione di un tasto spegne la retro illuminazione
if (millis() - noRetro >= 5000) {
lcd.noBacklight();
}
}
//altrimenti la accende
else{
lcd.backlight();
}
}
//controlla lo stato dell'allarme(inserito/manutenzione) e chiama le funzioni che controllano i sensori
void stato(){
lcd.setCursor(4, 1);
lcd.print(F("DifAlarm"));
//se lo stato di manutenzione è attivo stampa "MAN" sull'lcd
if (man){
lcd.setCursor(13,0);
lcd.print(F("MAN"));
}
//se lo stato di manutenzione NON è inserito
else{
scattoman();
}
//se l'allarme non è inserito
if(ins == false && reset == false){
//se l'allarme non è scattato a causa dei sensori anti-manomissione spegnilo
if (almMan == false){
digitalWrite(11,LOW);
}
//stampa "OFF" sull'lcd
lcd.setCursor(0,0);
lcd.print(F("OFF"));
}
//altrimenti(allarme inserito)
else{
//stampa "ON" sull'lcd
lcd.setCursor(0,0);
lcd.print(F("ON"));
//chiama le funzioni che controllano i sensori
scatto();
scattopre();
}
}
//controlla i sensori collegati al pin 13
void scatto(){
//appena il circuito si apre stampa "ALM" sull'lcd e accende la sirena (pin 11)
if(digitalRead(13) == LOW){
lcd.setCursor(13,0);
lcd.print(F("ALM"));
digitalWrite(11,HIGH);
}
delay(20);//piccola pausa
}
//controlla i sensori collegati al pin 12
void scattopre(){
//legge lo stato del pin 12 solo se questo è falso
if (condizione == false){
condizione = digitalRead(12) == LOW;//se true indica che il circuito è stato aperto
canSound = true;//abilita il buzzer
}
//se il il circuito è stato aperto
if (condizione) {
//se il buzzer può suonare emette dei bip per ricordare all'utente di disinserire l'allarme prima che esso scatti
if (canSound){
tone(1, 1200);
delay(50);
noTone(1);
delay(50);
}
reset = true;//permette di resettare il timer del pre-allarme
if (startTime == 0) {
startTime = millis(); // Memorizza il tempo di inizio
}
//se è passato più tempo del valore di durata
if (millis() - startTime >= durata) {
//stampa "ALM" sull'lcd
lcd.setCursor(13,0);
lcd.print(F("ALM"));
//accende la sirena
digitalWrite(11,HIGH);
//impedisce al buzzer di suonare
canSound = false;
noTone(1);
}
}
}
//controlla i sensori anti-manomissione
void scattoman(){
//se il circuito viene aperto
if(digitalRead(10) == LOW){
//stampa "ALM" sull'lcd
lcd.setCursor(13,0);
lcd.print(F("ALM"));
almMan = true;//indica che l'allarme è scattato a causa dei sensori anti-manomissione
digitalWrite(11,HIGH);//accende la sirena
}
delay(20);//piccola pausa
}
void setup() {
Serial.begin(115200);
pinMode(13,INPUT);//sensori finestre (scatto dell'allarme istantaneo), l'allarme può essere disattivato con il tasto '#' e inserimento password
pinMode(12,INPUT);//senore porta di ingresso (scatto dell'allarme dopo i secondi contenuti nella variabile durata), l'allarme può essere disattivato con il tasto '#' e inserimento password
pinMode(10,INPUT);//sensori anti-manomissione (scatto dell'allarme istantaneo), l'allarme può essere disattivato con il tasto '*' e inserimento password
pinMode(11,OUTPUT);//rele sirena
pinMode(1,OUTPUT);//buzzer
pinMode(0,OUTPUT);//pin collegato con il reset
char tempPassword[5] = "1234";
/*for(int i; i >= 5; i++){
Serial.println(i);
tempPassword[i] = "";
}*/
for(int i=0; i < 5; i++) {
Serial.println(i);
tempPassword[i] = '\0';
}
Serial.println(tempPassword);
lcd.init(); //inizializza l'lcd
lcd.backlight(); //accende la retroilluminazione
lcd.setCursor(4, 1);
lcd.print(F("DifAlarm"));
//delay (1000);
lcd.setCursor(0, 0);
lcd.print(F("Inizializzazione"));
//delay (1500);
lcd.clear();
noRetro = millis();
}
void loop(){
stato();//chiama la funzione stato per aggiornare l'utente sullo stato dell'allarme
retro();//chiama la funzione retro per spegnere/accendere la etroilluminazione
char key = keypad.getKey();//salva il carattere premuto sul keypad
//se viene premuto un tasto
if(key){
noRetro = millis();//salva quando viene premuto il tasto(gestione retro illuminazione)
tempIns = millis();//salva quando viene premuto il tasto(ritorno al menu principale automatico)
lcd.backlight();
}
//se il tasto premuto è '#',l'allarme non èinserito,lo stato di manutenzione non è attivo e l'allarme non è scattato a causa dei sensori anti-manomissione(quest'ultima cosa serve per non far inserire l'allarme se questo è stato manomesso)
if (key == '#' && ins == false && man == false && almMan == false){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Password"));
passc = true;//accetta l'inserimento della password
home = true;
//finche la password non è corretta
while(passc){
//se lo stato di manutenzione è disattivato chiama la funzione che controlla i sensori anti-manomissione
if (man == false){
scattoman();
}
pass();//funzione inserimento password
controllo();//controlla se porta e finestre (pin 12 e 13) sono chiuse
retro();//gestione retroilluminazione
}
//se l'arduino ritorna in questo if dopo che la password è corretta inserisce l'allarme
if (home){
lcd.clear();
lcd.setCursor(1,0);
startTime = millis();
lcd.print(F("Inserimento..."));
delay(15000);//tempo per uscire di casa senza far scattare l'allarme
noRetro = millis();
startTime = millis();
ins = true;//allarme inserito
lcd.clear();
}
//se l'arduino ritorna in questo if perche sono passati 10sec dall'ultima pressione di un tasto o si preme il tasto '#' nella funzione pass()
else{lcd.clear();}
}
//se il tasto premuto è '#',l'allarme è inserito e lo stato di manutenzione è spento
else if (key == '#' && ins == true && man == false){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Password"));
passc = true;//accetta l'inserimento della password
home = true;
//finche la password non è corretta
while(passc){
//se lo stato di manutenzione è disattivato chiama la funzione che controlla i sensori anti-manomissione
if (man == false){
scattoman();
}
pass();//funzione inserimento password
retro();//gestione retroilluminazione
//impedisce al buzzer di suonare
canSound = false;
noTone(1);
//controlla i sensori
scatto();
scattopre();
}
//se l'arduino ritorna in questo if dopo che la password è corretta disinserisce l'allarme
if (home){
ins = false;
}
}
//se il tasto premuto è '*'
if (key == '*'){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Password"));
passmanc = true;//accetta l'inserimento della password
//finche la password non è corretta
while(passmanc){
passman();//funzione inserimento password manutenzione
retro();//gestione retro illuminazione
//se l'allarme è inserito controlla i sensori
if (ins){
scatto();
scattopre();
}
//se lo stato di manutenzione è disattivato chiama la funzione che controlla i sensori anti-manomissione
if (man == false){
scattoman();
}
}
}
//se il tasto premuto è 'd'
if(key == 'd'){
hardReset = true;//imposta la variabile per il reset su true
passc = true;//accetta l'inserimento della password
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Password"));
//finchè la password non è corretta
while(passc){
pass();//funzione inserimento password
retro();//gestione retro illuminazione
//se lo stato di manutenzione è disattivato chiama la funzione che controlla i sensori anti-manomissione
if (man == false){
scattoman();
}
}
}
//resetta il timer se il cicuito sul pin 12 si chiude e l'allarme viene disinserito tremite password diventa falsa
if (digitalRead(12) == HIGH && reset == false) {
startTime = millis();
}
}