This shows you the differences between two versions of the page.
pm:prj2024:sseverin:catalina.sindrilaru [2024/05/12 22:04] catalina.sindrilaru [Implementare] |
pm:prj2024:sseverin:catalina.sindrilaru [2024/05/26 23:13] (current) catalina.sindrilaru [Rezultate Obţinute] |
||
---|---|---|---|
Line 52: | Line 52: | ||
==== Implementare ==== | ==== Implementare ==== | ||
- | Github: todo | + | Complete code on Github: todo |
- | Pentru a oferi o experienta cat mai buna utilizatorului, am folosit display-ul LCD cu interfata I2C pentru a afisa mesaje ce au ca scop informarea si ghidarea acestuia. La inceput, utilizatorului ii este adus la cunostinta faptul ca trebuie sa se introduca un cod, urmat de caracterul **#**, pentru ca sistemul sa intre in modul pentru inregistrarea amprentei. | + | Pentru a oferi o experienta cat mai buna utilizatorului, am folosit display-ul LCD cu interfata I2C pentru a afisa mesaje ce au ca scop informarea si ghidarea acestuia. |
- | '' | + | Sistemul verifica in permanenta daca a fost introdus un cod nou. Acest lucru are la baza tastatura, initializata la inceputul programului, 2 coduri de referinta si un sir gol. |
- | if (start) { | + | |
- | // initial message | + | <code> |
- | lcd.clear(); | + | const byte ROWS = 4; |
- | lcd.setCursor(0,0); | + | const byte COLS = 4; |
- | lcd.print("Register finger"); | + | |
- | lcd.setCursor(0,1); | + | char keys[ROWS][COLS] = { |
- | lcd.print("Enter code + #"); | + | {'1','2','3','A'}, |
- | start = false; | + | {'4','5','6','B'}, |
+ | {'7','8','9','C'}, | ||
+ | {'*','0','#','D'} | ||
+ | }; | ||
+ | |||
+ | byte rowPins[ROWS] = {13, 12, 10, 9}; | ||
+ | byte colPins[COLS] = {8, 7, 6, 5}; | ||
+ | |||
+ | Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); | ||
+ | char correctCodeRegister[] = "147258"; | ||
+ | char enteredCode[7] = ""; | ||
+ | char correctCodeDelete[] = "258369"; | ||
+ | </code> | ||
+ | |||
+ | Functia de verificare cod citeste un caracter de la tastatura, iar cand tasta **#** este apasata, verifica validitatea codului. Astfel, tastatura este folosita pentru a pune sistemul in 2 moduri, cel de inregistrare a unei noi amprente si cel de stergere a tuturor amprentelor ce au fost inregistrate. Astfel, daca codul introdus este cel corespunzator modului de inregistrare amprenta sau de golire a bazei de date, pe ecran se afiseaza **Correct Code!** si se incepe citirea amprentei sau a golirii bazei de date, dupa caz. In schimb, daca codul introdus nu este corect, se afiseaza **Incorrect Code!**. Dupa ce un **#** a fost apasat, sirul ce retine codul tastat se goleste. | ||
+ | |||
+ | <code> | ||
+ | void verify_code() { | ||
+ | char key = keypad.getKey(); | ||
+ | if (key) { | ||
+ | if (key == '#') { | ||
+ | if (strcmp(enteredCode, correctCodeRegister) == 0) { | ||
+ | registerMode(); | ||
+ | } else if (strcmp(enteredCode, correctCodeDelete) == 0) { | ||
+ | deleteMode(); | ||
+ | } else { | ||
+ | incorrectMode(); | ||
+ | } | ||
+ | memset(enteredCode, 0, sizeof(enteredCode)); | ||
+ | } else { | ||
+ | if (strlen(enteredCode) < 6) { | ||
+ | strncat(enteredCode, &key, 1); | ||
+ | } | ||
+ | } | ||
} | } | ||
- | '' | + | } |
+ | </code> | ||
- | Sistemul verifica in permanenta daca a fost introdus un cod nou. Acest lucru are la baza tastatura, initializata la inceputul programului, 2 coduri de referinta si un sir gol. Functia de verificare cod citeste un caracter de la tastatura, iar cand tasta **#** este apasata, verifica validitatea codului. Astfel, tastatura este folosita pentru a pune sistemul in 2 moduri, cel de inregistrare a unei noi amprente si cel de stergere a tuturor amprentelor ce au fost inregistrate. Astfel, daca codul introdus este cel corespunzator modului de inregistrare amprenta sau de golire a bazei de date, pe ecran se afiseaza **Correct Code!** si se incepe citirea amprentei sau a golirii bazei de date, dupa caz. In schimb, daca codul introdus nu este corect, se afiseaza **Incorrect Code!**. Dupa ce un **#** a fost apasat, sirul ce retine codul tastat se goleste. | ||
+ | Pentru utilizarea cititorului de amprenta, am folosit biblioteca [[https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library | Adafruit_Fingerprint.h ]], impreuna cu cateva dintre functiile pe care le pune la dispozitie, de stocare a unei amprente, de golire a bazei de date pentru amprente, precum si de verificare daca o amprenta a fost deja inregistrata sau nu. | ||
- | Pentru utilizarea cititorului de amprenta, am folosit biblioteca [[https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library | Adafruit_Fingerprint.h ]], impreuna cu cateva dintre functiile pe care le pune la dispozitie, de stocare a unei amprente, de golire a bazei de date pentru amprente, precum si de verificare daca o amprenta a fost deja inregistrata sau nu. Astfel, dupa tastarea corecta a codului pentru inregistrarea unei amprente, se afiseaza pe ecran mesajul **Enrolling..** si se apeleaza functia din biblioteca pentru inrolarea unei noi amprente. Functia de inrolare foloseste un id caruia sa ii asocieze amprenta pe care o va inregistra (poate inregistra pana la 127 de amprente), asa ca am folosit un id care porneste de la 1 si creste de fiecare data cand o amprenta noua este inregistrata. Aceasta functie presupune asezarea aceluiasi deget pe cititor de 2 ori, pentru a verifica corectitudinea amprentei. Pentru acest proces, am afisat mesaje care sa ghideze utilizatorul, precum **"Place finger!"**, **"Remove finger!"**, **"Place same finger again"**, **"Fingerprints did not match. Introduce code again"**, **"Fingerprints match"**, **"Fingerprint stored"**. | + | <code> |
+ | SoftwareSerial softwareSerial(2, 3); | ||
+ | Adafruit_Fingerprint finger = Adafruit_Fingerprint(&softwareSerial); | ||
+ | uint8_t id = 1; // first id | ||
+ | </code> | ||
+ | |||
+ | Astfel, dupa tastarea corecta a codului pentru inregistrarea unei amprente, se afiseaza pe ecran mesajul **Enrolling..** si se apeleaza functia din biblioteca pentru inrolarea unei noi amprente. Functia de inrolare foloseste un id caruia sa ii asocieze amprenta pe care o va inregistra (poate inregistra pana la 127 de amprente), asa ca am folosit un id care porneste de la 1 si creste de fiecare data cand o amprenta noua este inregistrata. Aceasta functie presupune asezarea aceluiasi deget pe cititor de 2 ori, pentru a verifica corectitudinea amprentei. Pentru acest proces, am afisat mesaje care sa ghideze utilizatorul, precum **"Place finger!"**, **"Remove finger!"**, **"Place same finger again"**, **"Fingerprints did not match. Introduce code again"**, **"Fingerprints match"**, **"Fingerprint stored"**. | ||
+ | |||
+ | <code> | ||
+ | void enrollFinger() { | ||
+ | Serial.println("Enrolling..."); | ||
+ | lcd.clear(); | ||
+ | lcd.setCursor(0,0); | ||
+ | lcd.print("Enrolling..."); | ||
+ | delay(1000); | ||
+ | while (!getFingerprintEnroll()); | ||
+ | id++; | ||
+ | delay(2000); | ||
+ | } | ||
+ | </code> | ||
Sistemul verifica constant daca a fost asezata o amprenta pe cititor, folosind functia din biblioteca. Astfel, daca citeste o amprenta pe care o are deja stocata in baza de date, afiseaza **"Found a print match!"** si intra in modul de deschidere a usii, iar daca amprenta nu exista in baza de date afiseaza **"Did not find a match!"**, iar usa ramane inchisa. | Sistemul verifica constant daca a fost asezata o amprenta pe cititor, folosind functia din biblioteca. Astfel, daca citeste o amprenta pe care o are deja stocata in baza de date, afiseaza **"Found a print match!"** si intra in modul de deschidere a usii, iar daca amprenta nu exista in baza de date afiseaza **"Did not find a match!"**, iar usa ramane inchisa. | ||
De fiecare data cand o amprenta gresita este detectata de cititor, se incrementeaza un contor, care se reseteaza atunci cand o amprenta corecta a fost introdusa. Atunci cand sunt introduse 3 amprente gresite (in mod consecutiv), se activeaza buzzerul, ce simuleaza o alarma, timp de 3 secunde. | De fiecare data cand o amprenta gresita este detectata de cititor, se incrementeaza un contor, care se reseteaza atunci cand o amprenta corecta a fost introdusa. Atunci cand sunt introduse 3 amprente gresite (in mod consecutiv), se activeaza buzzerul, ce simuleaza o alarma, timp de 3 secunde. | ||
+ | |||
+ | <code> | ||
+ | if (failedFingerprintsConsec == 3) { | ||
+ | failedFingerprintsConsec = 0; | ||
+ | activateBuzzer(); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | void activateBuzzer() { | ||
+ | lcd.clear(); | ||
+ | lcd.setCursor(0,0); | ||
+ | lcd.print("3 unsuccessful"); | ||
+ | lcd.setCursor(0,1); | ||
+ | lcd.print("attempts!"); | ||
+ | |||
+ | analogWrite(buzzerPin, 230); | ||
+ | delay(1000); | ||
+ | analogWrite(buzzerPin, 0); | ||
+ | delay(500); | ||
+ | analogWrite(buzzerPin, 230); | ||
+ | delay(1000); | ||
+ | analogWrite(buzzerPin, 0); | ||
+ | delay(500); | ||
+ | analogWrite(buzzerPin, 230); | ||
+ | delay(1000); | ||
+ | analogWrite(buzzerPin, 0); | ||
+ | |||
+ | lcd.clear(); | ||
+ | } | ||
+ | </code> | ||
In modul de deschidere a usii, pe care am simulat-o cu ajutorul unui servo-motor (setat initial la pozitia 0), am afisat mesaje precum **"Opening door..."**, **"Door is open!"**, **"Closing door..."**, **"Door is closed!"**. Pentru a simula deschiderea usii, am schimbat pozitia servo-motorului de la 0 la 90. Usa ramane deschisa timp de 3 secunde. | In modul de deschidere a usii, pe care am simulat-o cu ajutorul unui servo-motor (setat initial la pozitia 0), am afisat mesaje precum **"Opening door..."**, **"Door is open!"**, **"Closing door..."**, **"Door is closed!"**. Pentru a simula deschiderea usii, am schimbat pozitia servo-motorului de la 0 la 90. Usa ramane deschisa timp de 3 secunde. | ||
+ | |||
+ | <code> | ||
+ | void openDoor() { | ||
+ | lcd.clear(); | ||
+ | lcd.setCursor(0,0); | ||
+ | lcd.print("Opening door..."); | ||
+ | delay(1500); | ||
+ | |||
+ | for (;pos<=90;pos+=10) { | ||
+ | Servo1.write(pos); | ||
+ | delay(80); | ||
+ | } | ||
+ | |||
+ | lcd.clear(); | ||
+ | lcd.setCursor(0,0); | ||
+ | lcd.print("Door is open!"); | ||
+ | delay(3000); | ||
+ | lcd.clear(); | ||
+ | lcd.setCursor(0,0); | ||
+ | lcd.print("Closing door..."); | ||
+ | delay(1500); | ||
+ | |||
+ | for (;pos>=0;pos-=10) { | ||
+ | Servo1.write(pos); | ||
+ | delay(80); | ||
+ | } | ||
+ | |||
+ | lcd.clear(); | ||
+ | lcd.setCursor(0,0); | ||
+ | lcd.print("Door is closed!"); | ||
+ | delay(2000); | ||
+ | lcd.clear(); | ||
+ | } | ||
+ | </code> | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
- | Demo: todo | + | Demo: https://www.youtube.com/watch?v=dIeKKA5WVyk |
- | {{:pm:prj2024:sseverin:image2-pm-project-catalina.jpeg?650|}} | + | {{:pm:prj2024:sseverin:img1-proiect-catalinasindrilaru.jpeg?650|}} |
+ | |||
+ | |||
+ | {{:pm:prj2024:sseverin:img2-proiect-catalinasindrilaru.jpeg?650|}} | ||
- | {{:pm:prj2024:sseverin:image1-pm-project-catalina.jpeg?650|}} | ||
===== Concluzii ===== | ===== Concluzii ===== | ||
+ | Realizarea proiectului mi s-a parut foarte interesanta. Am reusit sa realizez ceea ce mi-am propus. Realizarea design-ului final al proiectului, pentru a avea un aspect placut, ce expune doar piesele ce trebuie sa fie vazute, este cea ce m-a pus cel mai mult in dificultate. | ||
===== Download ===== | ===== Download ===== | ||
- | <note warning> | + | Github: https://github.com/CatalinaSindrilaru/Smart-lock-system-Arduino |
- | O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). | + | |
- | Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:pm:prj20??:c?** sau **:pm:prj20??:c?:nume_student** (dacă este cazul). **Exemplu:** Dumitru Alin, 331CC -> **:pm:prj2009:cc:dumitru_alin**. | + | {{:pm:prj2024:sseverin:smart_lock_system_sindrilarucatalina.zip|}} |
- | </note> | + | |
===== Jurnal ===== | ===== Jurnal ===== | ||
Line 104: | Line 223: | ||
===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
- | |||
- | <note> | ||
- | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | ||
- | </note> | ||
- | |||
* LCD | * LCD |