Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2026:andrei.batasev:serban.dadulescu [2026/05/16 16:33]
serban.dadulescu
pm:prj2026:andrei.batasev:serban.dadulescu [2026/05/27 00:10] (current)
serban.dadulescu
Line 3: Line 3:
 ===== Introducere ===== ===== Introducere =====
 **Prezentare:​** **Prezentare:​**
-Proiectul reprezintă un sistem de securitate pentru controlul accesului, care validează identitatea utilizatorilor pe baza tag-urilor sau cardurilor RFID. La scanarea unui card autorizat, sistemul acționează un mecanism de blocare (simulat printr-un servomotor),​ afișează un mesaj personalizat de bun venit pe un ecran LCD cu interfață ​I2C și emite un semnal sonor de confirmare.+Proiectul reprezintă un sistem de securitate pentru controlul accesului, care validează identitatea utilizatorilor pe baza tag-urilor sau cardurilor RFID. La scanarea unui card autorizat, sistemul acționează un mecanism de blocare (simulat printr-un servomotor),​ afișează un mesaj personalizat de bun venit pe un ecran LCD cu interfață și emite un semnal sonor de confirmare.
  
 **Scopul proiectului:​** **Scopul proiectului:​**
Line 12: Line 12:
  
 **Utilitate:​** **Utilitate:​**
-Pentru mine, este o oportunitate excelentă de a integra simultan mai multe protocoale de comunicație (SPI, I2C) și funcții hardware avansate (Timere, PWM, Întreruperi și EEPROM) pe un singur microcontroller. Pentru alții, un astfel de sistem poate fi scalat și integrat în viața reală pentru a securiza dulapuri, cutii de valori sau chiar ușa unei camere.+Pentru mine, este o oportunitate excelentă de a integra simultan mai multe protocoale de comunicație (SPI) și funcții hardware avansate (Timere, PWM, Întreruperi și EEPROM) pe un singur microcontroller. Pentru alții, un astfel de sistem poate fi scalat și integrat în viața reală pentru a securiza dulapuri, cutii de valori sau chiar ușa unei camere.
  
 ===== Descriere generală ===== ===== Descriere generală =====
Line 22: Line 22:
     * **Buton tactil (Exit Button):** Permite deschiderea manuală a ușii din interior. Este conectat la un pin setat să declanșeze o **întrerupere externă** hardware, asigurând un răspuns imediat al sistemului.     * **Buton tactil (Exit Button):** Permite deschiderea manuală a ușii din interior. Este conectat la un pin setat să declanșeze o **întrerupere externă** hardware, asigurând un răspuns imediat al sistemului.
   * **Blocul de Output (Ieșiri):​**   * **Blocul de Output (Ieșiri):​**
-    * **Display LCD 1602 (cu modul I2C):** Afișează mesaje de status și saluturi personalizate. Comunicarea se face prin protocolul **I2C**.+    * **Display LCD** Afișează mesaje de status și saluturi personalizate.
     * **Servomotor SG90:** Reprezintă acționarea fizică (zăvorul). Este controlat prin generarea unui semnal **PWM**.     * **Servomotor SG90:** Reprezintă acționarea fizică (zăvorul). Este controlat prin generarea unui semnal **PWM**.
     * **Buzzer pasiv:** Oferă feedback auditiv (bip scurt pentru succes, bip lung pentru eroare), controlat tot prin semnale **PWM** cu frecvențe variabile.     * **Buzzer pasiv:** Oferă feedback auditiv (bip scurt pentru succes, bip lung pentru eroare), controlat tot prin semnale **PWM** cu frecvențe variabile.
Line 34: Line 34:
 ==== Stadiul actual ==== ==== Stadiul actual ====
  
-Sistemul este montat pe breadboard în jurul unei plăci ​Arduino Uno.+Sistemul este montat pe breadboard în jurul unei plăci ​ATmega.
 Toate componentele sunt conectate și sistemul răspunde corect la Toate componentele sunt conectate și sistemul răspunde corect la
 scanarea cardurilor. scanarea cardurilor.
Line 43: Line 43:
 | Arduino Uno (ATmega328P) | Creierul sistemului — decide ce se întâmplă când se scanează un card și ține minte cardurile autorizate | | Arduino Uno (ATmega328P) | Creierul sistemului — decide ce se întâmplă când se scanează un card și ține minte cardurile autorizate |
 | Modul RFID RC522 | Citește cardurile și brelocurile RFID | | Modul RFID RC522 | Citește cardurile și brelocurile RFID |
-| LCD 1602 cu modul I²C | Afișează mesaje (status, bun venit, erori) |+| LCD | Afișează mesaje (status, bun venit, erori) |
 | Servomotor SG90 | Simulează zăvorul care se deschide | | Servomotor SG90 | Simulează zăvorul care se deschide |
 | Buzzer pasiv | Sunete de confirmare sau eroare | | Buzzer pasiv | Sunete de confirmare sau eroare |
Line 51: Line 51:
 ==== Detalii de cablare ==== ==== Detalii de cablare ====
  
-  * **RC522:** alimentat la **3.3 V** (foarte important — modulul se arde la 5 V!). Comunică cu Arduino ​prin SPI, deci folosește pinii D10-D13 (sunt pinii dedicați pentru SPI pe Arduino Uno). Pinul RST este pus pe D7. +  * **RC522:** alimentat la **3.3 V** (foarte important — modulul se arde la 5 V!). Comunică cu ATmega ​prin SPI, deci folosește pinii D10-D13 (sunt pinii dedicați pentru SPI pe Arduino Uno). Pinul RST este pus pe D7. 
-  * **LCD I²C:** alimentat la 5 V și conectat la pinii A4 (SDA) și A5 (SCL), pinii dedicați pentru comunicarea I²C. Doar 4 fire în total — un mare avantaj față de un LCD obișnuit care ar avea nevoie de 6-7 fire.+  * **LCD** ​
   * **Servomotor SG90:** semnalul pe D9, un pin care poate genera semnal PWM (necesar pentru a controla unghiul motorului).   * **Servomotor SG90:** semnalul pe D9, un pin care poate genera semnal PWM (necesar pentru a controla unghiul motorului).
   * **Buzzer pasiv:** conectat la D3, tot un pin PWM, ca să poată genera sunete de frecvențe diferite.   * **Buzzer pasiv:** conectat la D3, tot un pin PWM, ca să poată genera sunete de frecvențe diferite.
Line 64: Line 64:
 Schema separă cele două surse de alimentare (3.3 V doar pentru RC522, Schema separă cele două surse de alimentare (3.3 V doar pentru RC522,
 5 V pentru restul) și cele două magistrale de comunicare (SPI pentru 5 V pentru restul) și cele două magistrale de comunicare (SPI pentru
-RC522, ​I²C pentru LCD), toate cu masă comună pe breadboard.+RC522, ​toate cu masă comună pe breadboard. 
 + 
 +===== Software Design ===== 
 +  
 +==== Mediul de dezvoltare ==== 
 +  
 +Codul este scris în limbajul **C**, direct cu regiștri (bare-metal),​ fără framework-ul Arduino. Am folosit **Microchip Studio 7** pentru scriere și compilare, iar placa o programez prin debugger-ul **mEDBG** de pe ATmega328P Xplained Mini, folosind interfața ISP. 
 +  
 +==== Biblioteci și surse 3rd-party ==== 
 +  
 +**Nu am folosit nicio bibliotecă externă.** Tot codul este scris de mine, direct pe regiștri, pentru că cerința a fost să lucrez la nivel de regiștri, nu cu funcții gata făcute de tip ''​digitalWrite()''​. 
 +  
 +Singurele header-e incluse sunt cele standard din AVR-libc: 
 +  
 +  * ''<​avr/​io.h>''​ — definițiile de regiștri ale ATmega328P 
 +  * ''<​avr/​interrupt.h>''​ — macro-ul ''​ISR()''​ și ''​sei()''​ / ''​cli()''​ 
 +  * ''<​util/​delay.h>''​ — întârzieri (''​_delay_ms'',​ ''​_delay_us''​) 
 +  
 +Driverul ​pentru LCD (HD44780, pe 4 bițiși driverul pentru cititorul RFID (MFRC522) le-am scris eu de la zeroîn loc să folosesc biblioteci gata făcute de tip ''​LiquidCrystal''​ sau ''​MFRC522''​. 
 +  
 +==== Elementul de noutate ==== 
 +  
 +Noutatea proiectului este că **am scris tot codul de la zero**, fără biblioteci, și că **utilizatorii se pot adăuga direct de pe dispozitiv**. Cardul autorizat nu este scris fix în cod: dacă ții butonul apăsat 3 secunde, intri într-un mod de înrolare în care scanezi un card nou, iar UID-ul lui se salvează în **EEPROM**. Astfel cardul rămâne salvat chiar și după ce oprești curentul. 
 +  
 +==== Justificarea funcționalităților din laborator ==== 
 +  
 +Fiecare temă de laborator are un rol concret în proiect: 
 +  
 +  * **Lab 1 — Întreruperi externe (INT0):** butonul de ieșire este legat pe PD2 ca întrerupere pe front căzător. Așa sistemul reacționează imediat la apăsare, fără să aștepte bucla principală. 
 +  * **Lab 2 — Timere și PWM hardware:** Timer1 generează semnalul de 50 Hz pentru servo (pe OC1A), iar Timer2 generează sunetele buzzer-ului cu frecvență variabilă (pe OC2B). Ambele semnale sunt produse de hardware. 
 +  * **Lab 3 — SPI:** cititorul RFID comunică prin SPI, configurat la nivel de regiștri. LCD-ul este paralel, deci nu folosesc I²C — protocolul serial demonstrat este SPI. 
 +  * **Lab 4 — USART:** îl folosesc pentru debugging — afișează în Serial Monitor versiunea cititorului RFID la pornire și UID-ul fiecărui card scanat. 
 +  * **Lab 5 — EEPROM:** salvez UID-ul cardului master în EEPROM, ca să nu se piardă când opresc placa. 
 +  
 +Exemplu — configurarea Timer1 pentru semnalul PWM al servo-ului:​ 
 +  
 +<code c> 
 +void servoInit(void) { 
 +    DDRB |= (1 << PB1);                                  // OC1A iesire 
 +    TCCR1A = (1 << COM1A1) | (1 << WGM11); ​              // Fast PWM, TOP=ICR1 
 +    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); ​ // prescaler 8 
 +    ICR1   = 39999; ​                                     // perioada 20ms = 50Hz 
 +    OCR1A  = SERVO_CLOSED; ​                              // pozitia initiala 
 +
 +</​code>​ 
 +  
 +Exemplu — întreruperea pe buton (ISR scurt, doar ridică un flag): 
 +  
 +<code c> 
 +ISR(INT0_vect) { 
 +    exitRequested = 1; 
 +
 +</​code>​ 
 +  
 +==== Cum funcționează codul ==== 
 +  
 +La pornire, programul inițializează ​toate componentele (LCD, USART, întrerupere,​ timere, SPI, RFID), încarcă UID-ul master din EEPROM și intră în starea de standby ("​Sistem Blocat"​). 
 +  
 +Apoi, în bucla principală,​ sistemul așteaptă două lucruri: 
 +  
 +  * **Butonul:​** apăsare scurtă deschide bariera; apăsare lungă (3 secunde) intră în modul de înrolare și salvează un card nou. 
 +  * **Un card RFID:** dacă UID-ul cardului e același ​cu cel salvat în EEPROM, se acordă accesul; dacă nu, accesul e refuzat. 
 +  
 +Reacțiile sistemului:​ 
 +  
 +  * **Acces aprobat:** LCD scrie "Acces Aprobat",​ LED-ul se aprinde, buzzer-ul cântă scurt și vesel, servo-ul deschide bariera 3 secunde, apoi se închide. 
 +  * **Card invalid:** LCD scrie "Card Invalid!",​ LED-ul clipește, buzzer-ul scoate un sunet lung și grav, bariera rămâne închisă. 
 +  
 +==== Funcții implementate ==== 
 +  
 +^ Funcție ^ Rol ^ 
 +| ''​int0Init''​ / ''​ISR(INT0_vect)''​ | Configurarea și tratarea întreruperii butonului | 
 +| ''​servoInit''​ / ''​servoWrite''​ | Configurare Timer1 PWM și control poziție servo | 
 +| ''​buzzerInit''​ / ''​buzzerTone''​ / ''​buzzerOff''​ | Generare tonuri ​pe Timer2 | 
 +| ''​usartInit''​ / ''​usartTx''​ / ''​usartPrint''​ / ''​usartHex''​ | Ieșire serială pentru debug | 
 +| ''​eepromWrite''​ / ''​eepromRead''​ / ''​loadMaster''​ / ''​saveMaster''​ | Stocare UID master în EEPROM | 
 +| ''​spiInit''​ / ''​spiTransfer''​ | SPI master la nivel de regiștri | 
 +| ''​rcWrite''​ / ''​rcRead''​ / ''​rc522Init''​ / ''​rcTransceive''​ / ''​rcReadCard''​ | Driver MFRC522 și citire UID | 
 +| ''​lcdInit''​ / ''​lcdNibble''​ / ''​lcdByte''​ / ''​lcdClear''​ / ''​lcdSetCursor''​ / ''​lcdPrint''​ | Driver LCD HD44780 pe 4 biți | 
 +| ''​lockSystem''​ / ''​grantAccess''​ / ''​denyAccess''​ / ''​isMaster''​ | Mașina de stări a aplicației | 
 +  
 +==== Cum am verificat că funcționează ==== 
 +  
 +Am testat pe rând, nu tot odată: 
 +  
 +  * **SPI / RFID:** întâi am verificat în Serial Monitor că apare versiunea cititorului (la modulul meu apare 0x82), ca să fiu sigur că SPI-ul merge. Apoi am verificat că apare UID-ul când scanez un card. 
 +  * **INT0:** am verificat că bariera se deschide la apăsarea butonului. 
 +  * **Servo:** am verificat vizual cele două poziții. 
 +  * **Buzzer:** am verificat că sună diferit la succes față de eroare. 
 +  * **EEPROM:** am înrolat un card, am oprit curentul, am repornit, iar cardul tot funcționa — deci datele s-au păstrat. 
 +  
 +==== Calibrare ==== 
 +  
 +  * **Servo:** am ajustat valorile poziției până când bariera a ajuns exact unde voiam (jos = blocat, sus = deschis). La început aveam un servo de 360° care nu poate ține o poziție fixă, așa că l-am înlocuit cu unul standard. 
 +  * **RFID:** cardul trebuie pus lipit de antenă, altfel nu citește. 
 +  * **LCD:** contrastul se reglează dintr-un potențiometru până se vede textul. 
 +  
 +==== Optimizări ==== 
 +  
 +  * **Întrerupere scurtă:** în ISR doar setez un flag, restul muncii o fac în bucla principală. 
 +  * **PWM hardware:** semnalele pentru servo și buzzer sunt generate de timere, nu de procesor. 
 +  * **Debounce buton:** la început butonul declanșa de două ori din cauza contactului mecanic. Am rezolvat dezactivând întreruperea pe durata acțiunii și ștergând flag-ul de întrerupere (EIFR) înainte de a o reactiva. 
 + 
 +=== Github === 
 +https://​github.com/​raresdadulescu003-code/​SmartAccessSystem-PM/​tree/​main 
pm/prj2026/andrei.batasev/serban.dadulescu.1778938437.txt.gz · Last modified: 2026/05/16 16:33 by serban.dadulescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0