Dispozitivul are 2 mari moduri de functionare: cel in care asteapta input remote de la aplicatie prin intermediul modulului bluetooth HC-05 (in aceasta situatie poate primi fie un cod PIN, caz in care returneaza o valoare in aplicatie pentru a declansa o notificare ce anunta utilizatorul ca PIN-ul a fost setat cu succes, sau poate primi comanda de lock/unlock care blocheaza/deblocheaza seiful de la distanta) sau asteapta input de la keypad si verifica daca codul introdus de utilizator este corect. La fiecare introducere gresita de PIN, LED-ul rosu va lumina pentru a indica acest lucru. La 3 incercari esuate de deblocare, va fi pornita o alarma ce va putea fi oprita doar de utilizator din aplicatia LockIt. Aplicatia LockIt a fost implementata prin intermediul platformei MIT App Inventor.
if(locked){ servo.write(180); } else{ delay(500); servo.write(90); }
Se asteapta input de la interfata seriala UART prin intermediului modulului Bluetooth din aplicatie:
// Checks for input from LockIt app via UART interface if(Serial.available() > 0){ String command = Serial.readString(); //read until timeout command.trim(); // remove any \r \n whitespace at the end of the String // "Lock" command -> lock the safe box remotely using the app if(command == "lock"){ setLocked(true); // "Unlock" command -> unlock the safe box remotely using the app } else if(command == "unlock"){ setLocked(false); } else if(command == "stop"){ } // The app sent the PIN code for the safe box else{ strcpy(passwd, command.c_str()); // Check if PIN is of length 4 if(strlen(passwd) == 4){ digitalWrite(ledPinGreen, HIGH); delay(500); digitalWrite(ledPinGreen, LOW); } // Write back to the app in order to trigger a notification that // lets the user know the PIN has been set correctly Serial.write('0'); setLocked(true); delay(500); } }
Fie de la keypad, caz in care se verifica fiecare caracter primit cu caracterul de la pozitia respectiva din PIN. Pentru a tine cont de pozitia curenta din PIN, am folosit o variabila position. Daca caracterul primit nu corespunde cu cel de la position, codul este gresit si position devine 0 pentru urmatoarea verificare.
// If there is input from the keypad -> used variable position to keep // track of how much of the input from the keypad matches the PIN; // when a wrong key is pressed, position resets to 0. else if((key >= '0' && key <= '9') || (key == '*' || key == '*') && chars_read < 12){ // Lock the safe box after unlocking it using the keypad if(key == '#' || key == '*'){ position=0; chars_read = 0; setLocked(true); digitalWrite(ledPinGreen, LOW); } // Check if the current pressed key is correct else if(key == passwd[position]){ position++; chars_read++; } // The current pressed key is wrong -> reset positions else if(key != passwd[position]){ position =0; chars_read++; } // Signal that a key from the keypad has been received digitalWrite(ledPinGreen, HIGH); delay(500); digitalWrite(ledPinGreen, LOW);
La introducerea corecta a codului PIN, seiful se va debloca si LED-ul verde va ramane aprins tot timpul cat seiful este deschis.
// If the user inputs the PIN correctly -> unlock the safe and reset variables if(position == 4){ digitalWrite(ledPinGreen, HIGH); setLocked(false); chars_read = 0; position = 0; }
La introducerea gresita a unui cod PIN, LED-ul rosu va lumina intermitent pentru a semnaliza eroarea.
// If the user inputs the wrong PIN -> blink the red LED if(chars_read % 4 == 0 && chars_read / 4 >= 1){ digitalWrite(ledPinRed, HIGH); delay(700); digitalWrite(ledPinRed, LOW); } }
La 3 incercari gresite de deblocare, se activeaza tonul de alarma pentru buzzer. In acelasi timp, se verifica si daca exista input din aplicatie pentru a opri alarma.
// If there were 3 failures of opening the safe box, // send a message to the app to notify the user and start the alarm // Waits for input from the owner via LockIt app to stop the alarm if(chars_read == 12) Serial.write('3'); while(chars_read == 12){ if(alarm_stop == 0){ for(int i=600;i<700;i++){ unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { previousMillis = currentMillis; if (ledState == LOW) ledState = HIGH; else ledState = LOW; } // Switch the LED digitalWrite(ledPinRed, ledState); if(Serial.available() > 0){ String stop_command = Serial.readString(); stop_command.trim(); if(stop_command == "stop"){ chars_read = 0; //Serial.write('4'); digitalWrite(ledPinRed, LOW); alarm_stop = 1; noTone(buzzerPin); break; } } tone(buzzerPin,i); delay(15); } } if(alarm_stop == 0){ for(int i=700;i>600;i--){ unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { previousMillis = currentMillis; if (ledState == LOW) ledState = HIGH; else ledState = LOW; } // Switch the LED digitalWrite(ledPinRed, ledState); if(Serial.available() > 0){ String stop_command = Serial.readString(); stop_command.trim(); if(stop_command == "stop"){ chars_read = 0; //Serial.write('4'); digitalWrite(ledPinRed, LOW); alarm_stop = 1; break; } } tone(buzzerPin,i); delay(15); } } noTone(buzzerPin); }