This shows you the differences between two versions of the page.
|
pm:prj2024:sseverin:catalina.sindrilaru [2024/05/12 22:05] catalina.sindrilaru |
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. | ||
| + | |||
| + | <code> | ||
| + | const byte ROWS = 4; | ||
| + | const byte COLS = 4; | ||
| + | |||
| + | char keys[ROWS][COLS] = { | ||
| + | {'1','2','3','A'}, | ||
| + | {'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> | <code> | ||
| - | if (start) { | + | void verify_code() { |
| - | // initial message | + | char key = keypad.getKey(); |
| - | lcd.clear(); | + | if (key) { |
| - | lcd.setCursor(0,0); | + | if (key == '#') { |
| - | lcd.print("Register finger"); | + | if (strcmp(enteredCode, correctCodeRegister) == 0) { |
| - | lcd.setCursor(0,1); | + | registerMode(); |
| - | lcd.print("Enter code + #"); | + | } else if (strcmp(enteredCode, correctCodeDelete) == 0) { |
| - | start = false; | + | deleteMode(); |
| + | } else { | ||
| + | incorrectMode(); | ||
| + | } | ||
| + | memset(enteredCode, 0, sizeof(enteredCode)); | ||
| + | } else { | ||
| + | if (strlen(enteredCode) < 6) { | ||
| + | strncat(enteredCode, &key, 1); | ||
| + | } | ||
| + | } | ||
| } | } | ||
| + | } | ||
| </code> | </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 | ||