#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Postavke LCD zaslona
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Postavke za PIR senzor i tipkovnicu
int motionSensorPin = 10;
bool motionDetected = false;
const byte ROW_NUM = 4; // 4 redka
const byte COLUMN_NUM = 4; // 4 stupca
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] = {9, 8, 7, 6}; // Pinovi za redke
byte pin_column[COLUMN_NUM] = {5, 4, 3, 2}; // Pinovi za stupce
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
// Postavke alarma i simulacije
int analogPinSenzorkvalitetezraka = A0;
int buzzerPin = 12;
bool alarmActive = false; // Status alarma
bool pinEntered = false; // Status da li je PIN uspješno unesen
bool optionSelected = false; // Status odabrane opcije
bool simulationActive = false; // Status simulacije
bool simulateMotionEnabled = false; // Status za ručno pokretanje simulacije
bool useMotionSensor = false; // Koristi PIR senzor
bool useGasSensor = false; // Koristi senzor plina
unsigned long motionDetectedTime = 0; // Vrijeme kada je detektiran pokret
bool inputPasswordEntered = false; //Za unos password-a nakon kad se upali alarm
bool wrongPin = false;
bool alarmActive1 = false; // Alarm za plinski senzor
String initialPassword = ""; // Postavljanje početnog PIN-a
String inputPassword = ""; // Unos korisničkog PIN-a
static bool optionsDisplayed = false;
bool resettingPin = false; // Dodana varijabla koja kontrolira je li u procesu resetiranja PIN-a
int gasThreshold = 700; // Zadana granica PPM-a za alarm (može biti promijenjena od strane korisnika)
// Funkcije za unos PIN-a, odabir opcija i resetiranje statusa
void handlePinEntry();
void selectSystem();
void resetStatuses();
void handleinputPassword();
void setup() {
lcd.begin(16, 2);
lcd.print("Mini alarmni sustav");
pinMode(motionSensorPin, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(analogPinSenzorkvalitetezraka, INPUT); // AOUT kao ulaz
lcd.setCursor(0, 1);
lcd.print("Spreman za rad");
delay(3000);
lcd.clear();
}
void loop() {
if (resettingPin) {
// Ako je resetiranje PIN-a aktivno, samo čekaj unos novog PIN-a
lcd.clear();
lcd.print("Unesite novi PIN:");
lcd.setCursor(0, 1);
lcd.print(inputPassword); // Prikazuje uneseni PIN
handlePinEntry();
} else if (!pinEntered) {
lcd.setCursor(0, 0);
lcd.print("Unesite PIN:");
lcd.setCursor(0, 1);
lcd.print(inputPassword); // Prikazuje uneseni PIN
handlePinEntry();
} else if (!optionSelected) {
if (!optionsDisplayed) {
lcd.clear();
lcd.print("Odaberite opciju:");
lcd.setCursor(0, 1);
lcd.print("A:PIR B:Plin");
optionsDisplayed = true;
}
selectSystem();
} else if (!simulationActive && useMotionSensor) {
lcd.clear();
lcd.print("Simulacija aktivna");
lcd.setCursor(0, 1);
lcd.print("Pokreni kretanje");
simulateMotionEnabled = true; // Omogućuje ručno pokretanje simulacije
simulationActive = true; // Simulacija je sada aktivna
} else {
motionDetected = digitalRead(motionSensorPin); // Provjera pokreta
if (motionDetected && !alarmActive && !alarmActive1) {
lcd.clear();
lcd.print("Pokret detektiran!");
tone(buzzerPin, 783, 30000); // Uključi buzzer (zvuk traje 30 sekundi)
alarmActive = true; // Alarm za PIR senzor je sada aktivan
motionDetectedTime = millis(); // Spremi vrijeme kada je pokret detektiran
}
// Ako je alarm aktiviran, traži unos PIN-a za gašenje alarma
if (alarmActive) {
lcd.setCursor(0, 1);
lcd.print("Unesite PIN:");
lcd.print(inputPassword);
handleinputPassword();
} else if (useGasSensor) {
// Čitanje sa analognog pina za kvalitetu zraka (plinski senzor)
int analogVrijednostkvalitetezraka = analogRead(analogPinSenzorkvalitetezraka);
// Prikaz trenutne vrijednosti PPM
lcd.setCursor(0, 0);
lcd.print("Kvaliteta zraka:");
lcd.setCursor(0, 1);
lcd.print(analogVrijednostkvalitetezraka);
lcd.print(" PPM ");
// Aktivacija alarma za plin ako je PPM > 700
if (analogVrijednostkvalitetezraka > gasThreshold && !alarmActive1) {
lcd.clear();
lcd.print("Plin detektiran!");
tone(buzzerPin, 783); // Aktiviraj alarm (buzzer)
alarmActive1 = true; // Alarm za plin je sada aktivan
}
// Isključenje alarma za plin ako je PPM <= 700
if (analogVrijednostkvalitetezraka <= gasThreshold && alarmActive1) {
noTone(buzzerPin); // Isključi alarm
lcd.clear();
lcd.print("Plin stabilan.");
delay(2000); // Pričekaj prije ponovnog očitavanja
alarmActive1 = false; // Alarm za plin je sada isključen
}
}
}
// Provjera za tipku C - resetiranje PIN-a
char key = keypad.getKey();
if (key == 'C') {
lcd.clear();
lcd.print("Resetiranje PIN-a");
delay(1000);
// Resetiranje početnog PIN-a
lcd.clear();
lcd.print("Unesite novi PIN:");
inputPassword = ""; // Prazni unos PIN-a kako bi korisnik mogao unijeti novi
resettingPin = true; // Označava da je proces resetiranja PIN-a aktivan
delay(1000);
lcd.clear();
lcd.print("Odaberite opciju:");
lcd.setCursor(0, 1);
lcd.print("A:PIR B:Plin");
optionsDisplayed = true;
}
selectSystem();
if (key == 'D' && useGasSensor) { // Provjeri je li 'D' pritisnuto nakon odabira opcije B (Plin)
handleGasThresholdChange(); // Pozovi funkciju za promjenu granice PPM-a
}
}
void handlePinEntry() {
char key = keypad.getKey();
if (key) {
if (key == '#') {
pinEntered = true;
initialPassword = inputPassword; // Sprema uneseni PIN
lcd.clear();
lcd.print("PIN pohranjen");
delay(1000);
lcd.clear();
resettingPin = false; // Završava resetiranje PIN-a
if (!resettingPin) {
// Ako resetiranje nije aktivno, postavljamo sljedeće varijable
pinEntered = true; // Postavljamo pinEntered na true
optionSelected = false; // Postavljamo optionSelected na false, čekanje odabira opcije
optionsDisplayed = false; // Resetiramo optionsDisplayed
}
} else if (key == '*') {
inputPassword = "";
lcd.clear();
lcd.print("Unos resetiran");
delay(1000);
} else {
inputPassword += key;
}
}
}
void handleinputPassword() {
char key = keypad.getKey();
if (key) {
if (key == '#') {
// Kada korisnik pritisne #, PIN se pohranjuje i omogućava simulaciju
if (inputPassword == initialPassword) {
lcd.clear();
lcd.print("Alarm iskljucen!");
noTone(buzzerPin); // Isključi buzzer
alarmActive = false; // Alarm više nije aktivan
inputPassword = ""; // Resetiraj unos PIN-a
inputPasswordEntered = false; // Resetiraj status da nije unesen PIN
simulationActive = false; // Resetiraj simulaciju
delay(1000); // Prikaz poruke 1 sekundu
lcd.clear();
} else {
// Ako je PIN pogrešan
lcd.clear();
lcd.print("Pogresan PIN");
wrongPin = true; // Označi da je uneseni PIN pogrešan
inputPassword = ""; // Resetiraj unos PIN-a
delay(1000); // Prikaz poruke 1 sekundu
lcd.clear(); // Očisti zaslon
lcd.print("Pogresan PIN"); // Ponovno prikazivanje poruke "Pogrešan PIN"
}
}else if (key == '*') {
// Ako je pritisnuta tipka *, resetiraj unos PIN-a
inputPassword = "";
lcd.clear();
lcd.print("Unos resetiran");
delay(1000); // Prikaz poruke 1 sekundu
lcd.clear();
lcd.print("Unesite PIN:"); // Ponovno prikazivanje poruke
} else {
// Ako je pritisnuta bilo koja druga tipka, dodaj je u unos PIN-a
inputPassword += key;
lcd.clear(); // Očisti zaslon
lcd.setCursor(0, 1);
lcd.print("PIN: "); // Prikazujemo poruku za unos PIN-a
lcd.print(inputPassword); // Prikazujemo unesene brojke
}
}
}
void selectSystem() {
char key = keypad.getKey();
if (key == 'A') {
useMotionSensor = true;
optionSelected = true;
lcd.clear();
lcd.print("Odabran PIR senzor");
delay(1000);
} else if (key == 'B') {
useGasSensor = true;
lcd.clear();
lcd.print("Odabran plinski senzor");
delay(1000);
optionSelected = true;
}
}
void resetStatuses() {
alarmActive = false;
simulationActive = false;
simulateMotionEnabled = true; // Ponovno omogućuje simulaciju pokreta
}
// Funkcija za unos granice PPM-a
void handleGasThresholdChange() {
lcd.clear();
lcd.print("Unesite novu granicu:");
lcd.setCursor(0, 1);
String thresholdInput = "";
char key = keypad.getKey();
while (key != '#') { // Korisnik unosi broj dok ne pritisne '#'
key = keypad.getKey();
if (key) {
thresholdInput += key; // Dodaj broj u unos
lcd.clear();
lcd.print("Nova granica:");
lcd.setCursor(0, 1);
lcd.print(thresholdInput); // Prikaz unesenog broja
}
}
// Pretvori unos u integer i pohrani u gasThreshold
gasThreshold = thresholdInput.toInt();
lcd.clear();
lcd.print("Granica postavljena:");
lcd.setCursor(0, 1);
lcd.print(gasThreshold);
delay(1000); // Prikaz poruke 1 sekundu
lcd.clear();
lcd.print("Odaberite opciju:");
lcd.setCursor(0, 1);
lcd.print("A:PIR B:Plin");
}