Differences

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

Link to this comparison view

pm:prj2026:alexandru.jipa2803:costin.spataru [2026/05/16 22:17]
costin.spataru
pm:prj2026:alexandru.jipa2803:costin.spataru [2026/05/23 22:47] (current)
costin.spataru
Line 22: Line 22:
 Schema electrică a proiectului este realizată în KiCad și este atașată mai jos. Pentru lizibilitate,​ conexiunile sunt grupate prin etichete de semnal, iar alimentarea servo-ului este separată de alimentarea logică. Schema electrică a proiectului este realizată în KiCad și este atașată mai jos. Pentru lizibilitate,​ conexiunile sunt grupate prin etichete de semnal, iar alimentarea servo-ului este separată de alimentarea logică.
  
-{{url>​https://​ocw.cs.pub.ro/​courses/​_media/​pm:​prj2026:​alexandru.jipa2803:​timelock-box.pdf ​100%,595}} +{{url>​https://​ocw.cs.pub.ro/​courses/​_media/​pm:​prj2026:​alexandru.jipa2803:​timelock-box.pdf ​98%,400px}}
 ==== Listă de componente ==== ==== Listă de componente ====
  
Line 33: Line 32:
 | Servomotor SG90 | 1 | acționare zăvor | | Servomotor SG90 | 1 | acționare zăvor |
 | Buzzer pasiv 5V | 1 | alarmă acustică | | Buzzer pasiv 5V | 1 | alarmă acustică |
-| Microswitch cu levier | 1 | detecție capac | +| Microswitch cu levier ​(Panasonic) ​| 1 | detecție capac | 
-| LED roșu | 1 | indicator alarmă | +| LED roșu | 1 | indicator alarmă ​/ blocat ​
-| LED verde | 1 | indicator OK |+| LED verde | 1 | indicator OK / deschis ​|
 | Rezistențe 330Ω | 2 | limitare curent LED | | Rezistențe 330Ω | 2 | limitare curent LED |
 | Condensator electrolitic 470uF / 16V | 1 | stabilizare servo | | Condensator electrolitic 470uF / 16V | 1 | stabilizare servo |
Line 45: Line 44:
  
 ^ Modul ^ Conexiuni ^ Motiv ^ ^ Modul ^ Conexiuni ^ Motiv ^
-| Encoder ​timp KY-040 | CLK - PD2 / INT0; DT - PD4; SW - PB0 / PCINT0; VCC -> +5V; GND -> GND | PD2 oferă întrerupere externă pentru ​citirea rapidă a rotației ​+| Encoder ​cod KY-040 | CLK - PD2; DT - PD3; SW - PD4; VCC -> +5V; GND -> GND | Interfață dedicată pentru ​setarea și introducerea codului. ​
-| Encoder ​cod KY-040 | CLK - PD5 / PCINT21; DT - PD6; SW - PC2 / PCINT10; VCC -> +5V; GND -> GND | PC2 evită conflictul cu PB3/MOSI, folosit posibil ​de SPI +| Encoder ​timp KY-040 | CLK - PD5; DT - PD6; SW - PD7; VCC -> +5V; GND -> GND | Interfață dedicată pentru alegerea duratei ​de blocare. ​
-| LCD 1602 I2C | SDA - PC4; SCL - PC5; VCC -> +5V; GND -> GND | PC4 și PC5 sunt pinii hardware I2C/​TWI ​+| LCD 1602 I2C | SDA - PC4; SCL - PC5; VCC -> +5V; GND -> GND | Afișează meniul, codul și timpul rămas. ​
-| Servomotor SG90 | Semnal - PB1 / OC1A; VCC -> +5V servo; GND -> GND comun | PB1/OC1A permite generarea PWM cu Timer1 ​+| Servomotor SG90 | Semnal - PB1; VCC -> +5V servo; GND -> GND comun | Acționează zăvorul mecanic. ​
-| Buzzer pasiv | + -> PD3 / OC2B; - -> GND | PD3/OC2B permite generarea unui ton prin PWM +| Buzzer pasiv | + -> PB0; - -> GND | Feedback sonor și alarmă. ​
-| Microswitch capac | NO - PB2; C - GND | PB2 este citit cu pull-up intern pentru detecția ​capacului | +| Microswitch capac | NO - PB2; C - GND | Detectează deschiderea ​capacului
-| LED roșu | anod - PC0; catod -> rezistență 330Ω -> GND | PC0 comandă indicatorul de alarmă/​eroare ​+| LED roșu | anod - PC0; catod -> rezistență 330Ω -> GND | Indică seif blocat / alarmă
-| LED verde | anod - PC1; catod -> rezistență 330Ω -> GND | PC1 comandă indicatorul de stare OK/​deblocat ​|+| LED verde | anod - PC1; catod -> rezistență 330Ω -> GND | Indică seif deschis / OK|
  
 ==== Alimentare ==== ==== Alimentare ====
  
 ^ Linie alimentare ^ Componente alimentate ^ Observații ^ ^ Linie alimentare ^ Componente alimentate ^ Observații ^
-| +5V logică | ATmega328P Xplained Mini, LCD 1602 I2C, encodere KY-040 | Alimentarea logică este folosită pentru modulele ​cu consum redus. | +| +5V logică | ATmega328P Xplained Mini, LCD 1602 I2C, encodere KY-040 | Pentru componente ​cu consum redus. | 
-| +5V servo | Servomotor SG90 | Servo-ul este alimentat ​separat ​deoarece poate avea vârfuri ​de curent ​în timpul mișcării. | +| +5V servo | Servomotor SG90 | Alimentare ​separată pentru vârfurile ​de curent. | 
-| GND comun | Toate modulele | Masa sursei externe pentru servo este conectată la masa plăcii, astfel încât semnalul PWM să aibă aceeași referință electrică. | +| GND comun | Toate modulele | Leagă sursa servo de masa plăcii. | 
-| Condensator 470uF / 16V | Între +5V servo și GND | Ajută la stabilizarea tensiunii când servo-ul pornește sau schimbă poziția. |+| Condensator 470uF / 16V | Între +5V servo și GND | Stabilizează alimentarea ​servo-ului. |
  
 ==== Sumar pini ==== ==== Sumar pini ====
  
 ^ Pin ATmega328P ^ Funcție în proiect ^ ^ Pin ATmega328P ^ Funcție în proiect ^
-| PD2 / INT0 | CLK encoder ​timp +| PD2 | CLK encoder ​cod 
-PD4 | DT encoder ​timp +PD3 | DT encoder ​cod 
-PB0 / PCINT0 ​| SW encoder ​timp +PD4 | SW encoder ​cod (Buton) ​
-| PD5 / PCINT21 ​| CLK encoder ​cod +| PD5 | CLK encoder ​timp 
-| PD6 | DT encoder ​cod +| PD6 | DT encoder ​timp 
-PC2 / PCINT10 ​| SW encoder ​cod +PD7 | SW encoder ​timp (Buton) ​
-PC4 / SDA Date I2C pentru LCD | +PB0 Buzzer pasiv (Alarmă/Confirmare) ​
-| PC5 SCL | Ceas I2C pentru LCD +| PB1 | Semnal ​servomotor SG90 (Zăvor) ​
-| PB1 / OC1A PWM servomotor SG90 +| PB2 | Intrare ​senzor ușă (Microswitch Panasonic) ​
-| PD3 / OC2B | PWM buzzer pasiv +| PC0 | Ieșire ​LED roșu | 
-| PB2 | Intrare ​microswitch capac +| PC1 | Ieșire ​LED verde 
-| PC0 | LED roșu | +| PC4 | Date I2C pentru ecran LCD | 
-| PC1 | LED verde | +| PC5 | Ceas I2C pentru ecran LCD 
-| PD0 PD1 | UART pentru debug, lăsați liberi |+| PD0PD1 | UART pentru debug, lăsați liberi |
  
 ==== Dovezi de funcționare ==== ==== Dovezi de funcționare ====
  
-În această secțiune voi încărca ​pozele realizate ​în laborator:+În această secțiune voi încărca ​video-ul realizat ​în laborator:
   * montajul general pe breadboard;   * montajul general pe breadboard;
-  * testul pentru ​encoder și servomotor;​ +  * testul pentru buzzer și LED roșu;
-  * testul pentru microswitch, ​buzzer și LED roșu;+
   * testul pentru LCD și LED-ul verde.   * testul pentru LCD și LED-ul verde.
 +
 +{{url>​https://​www.youtube.com/​embed/​FYHVN1Hon-A 100%,​400px}}
  
 ===== Software Design ===== ===== Software Design =====
  
-<note tip> +==== Mediu de dezvoltare ==== 
-Descrierea ​codului aplicaţiei (firmware): + 
-  * mediu de dezvoltare ​(if any) (e.gAVR StudioCodeVisionAVR+Firmware-ul este dezvoltat în **PlatformIO**,​ folosind framework-ul **Arduino** pentru microcontrollerul **ATmega328P Xplained Mini**. Configurația proiectului folosește platforma atmelavr, placa custom atmega328p_xplained_mini și frecvența de lucru de 16 MHz. 
-  ​* librării şsurse 3rd-party (e.gProcyon AVRlib+ 
-  * algoritmi şstructuri ​pe care plănuiţi ​să le implementaţi +==== Biblioteci folosite ==== 
-  * (etapa 3) surse şi funcţii implementate + 
-</​note>​+  * Arduino.h - funcționalități de bază Arduino: setup(), loop(), millis(), digitalRead(),​ pinMode(), tone(). 
 +  * Wire.h - comunicația I2C/TWI folosită de LCD. 
 +  * LiquidCrystal_I2C.h - afișarea meniurilor, ​codului ​și timpului rămas pe LCD 1602. 
 +  * Servo.h - generarea semnalului PWM pentru servomotorul SG90 care acționează zăvorul. 
 +  * avr/io.h - acces direct la registre AVR pentru LED-uri, prin DDRC și PORTC. 
 + 
 +==== Element de noutate ==== 
 + 
 +Proiectul implementează un **TimeLock Box** cu două encodere rotative separate: unul pentru alegerea timpului de blocare și unul pentru setarea/​introducerea codului. Codul de deblocare este setat direct din hardware la începutul sesiunii, fără a fi recompilat firmware-ul și fără cod de deblocare hardcodat în firmware. În plus, cutia are un sistem de alarmă folosind microswitch-ul,​ care detectează deschiderea capacului cât timp seiful este blocat. 
 + 
 +==== Funcționalități din laboratoare ==== 
 + 
 +  * **GPIO** - citire butoane encoder, microswitch capac, comandă LED-uri. 
 +  * **Întreruperi externe** - citirea encoderului pentru cod folosind pinii PD2 și PD3. 
 +  * **Timere / PWM** - semnalul pentru servomotor și semnalele sonore pentru buzzer. 
 +  * **I2C / TWI** - comunicația cu LCD-ul 1602 prin adaptorul I2C. 
 +  * **USART** - serialul este folosit pentru debug în timpul testării. 
 + 
 +==== Structura ​aplicației ==== 
 + 
 +Logica este organizată ca o mașină de stări: 
 + 
 +<code cpp> 
 +enum SafeState { 
 +  SET_CODE, 
 +  SET_TIME, 
 +  LOCKED, 
 +  ENTER_CODE,​ 
 +  ALARM 
 +}; 
 +</​code>​ 
 + 
 +Stările principale sunt: 
 + 
 +  * SET_CODE - utilizatorul alege codul de sesiune folosind encoderul de cod; 
 +  * SET_TIME - utilizatorul alege durata de blocare folosind encoderul de timp; 
 +  * LOCKED - servo-ul ține zăvorul închis, LED-ul roșu este aprins și cronometrul scade; 
 +  * ENTER_CODE - utilizatorul introduce codul pentru deblocare sau pentru oprirea alarmei; 
 +  * ALARM - microswitch-ul a detectat capacul ridicat cât timp seiful era blocat. 
 + 
 +Pe lângă aceste stări există variabile de control pentru starea fizică a seifului: 
 + 
 +<code cpp> 
 +bool safe_locked = false; 
 +bool alarm_active = false; 
 +long remaining_seconds = 0; 
 +int session_code[3] = {0, 0, 0}; 
 +</​code>​ 
 + 
 +==== Algoritm ==== 
 + 
 +În funcția setup() se inițializează LCD-ul, encoderele, microswitch-ul,​ buzzerul, LED-urile, servomotorul și comunicația serială. LED-ul verde este aprins la pornire, iar servo-ul este poziționat în starea de zăvor deschis. 
 + 
 +În funcția loop() se execută următorii pași: 
 + 
 +  * se verifică microswitch-ul;​ dacă seiful este blocat și capacul este ridicat, se activează alarma; 
 +  * în starea ​de alarmă, codul poate fi introdus doar după ce capacul revine închis; 
 +  * dacă seiful este blocat, cronometrul este actualizat cu millis(), fără delay() pentru scurgerea timpului; 
 +  * timpul continuă să scadă inclusiv în starea ENTER_CODE;​ 
 +  * encoderul de timp modifică durata în trepte de 5 minute; 
 +  * encoderul de cod modifică cifra curentă între 0 și 9; 
 +  * apăsarea butonului encoderului de cod confirmă cifra curentă; 
 +  * la introducerea celor 3 cifre, codul este comparat cu session_code;​ 
 +  * dacă acest cod este corect, servo-ul retrage zăvorul, LED-ul verde se aprinde și sesiunea se resetează;​ 
 +  * dacă timpul expiră natural, seiful se deblochează automat și revine la setarea unui cod nou. 
 + 
 +Pentru a reduce problemele de bouncing și citirile greșite ale encoderelor,​ afișajul LCD nu este redesenat continuuSe folosește un flag de refreshastfel încât LCD-ul este actualizat doar când se schimbă o valoare sau o stare: 
 + 
 +<code cpp> 
 +bool screen_dirty = true; 
 + 
 +// exemplu: după rotirea encoderului 
 +current_digit++;​ 
 +screen_dirty = true; 
 +</​code>​ 
 + 
 +==== Repartizare pini în firmware ==== 
 + 
 +<code cpp> 
 +#define CODE_CLK_PIN 2    // PD2 
 +#define CODE_DT_PIN 3     // PD3 
 +#define CODE_SW_PIN 4     // PD4 
 + 
 +#define TIME_CLK_PIN 5    // PD5 
 +#define TIME_DT_PIN 6     // PD6 
 +#define TIME_SW_PIN 7     // PD7 
 + 
 +#define BUZZER_PIN 8       // PB0 
 +#define SERVO_PIN 9        // PB1 
 +#define DOOR_SWITCH_PIN 10 // PB2 
 +</​code>​ 
 + 
 +LED-urile sunt controlate direct prin registre: 
 + 
 +<code cpp> 
 +DDRC |= (1 << PC0| (1 << PC1); // PC0 roșu, PC1 verde 
 + 
 +void stareDeschis_LED() { 
 +  ​PORTC |= (1 << PC1); 
 +  PORTC &= ~(1 << PC0); 
 +
 + 
 +void stareInchis_LED() { 
 +  PORTC |= (1 << PC0); 
 +  PORTC &= ~(1 << PC1); 
 +
 +</​code>​ 
 + 
 +==== GPIO și întreruperi ==== 
 + 
 +Microswitch-ul și butoanele encoderelor sunt configurate cu rezistențele interne de pull-up. Astfel, apăsarea butonului sau închiderea microswitch-ului produce nivel logic LOW. 
 + 
 +<code cpp> 
 +pinMode(DOOR_SWITCH_PIN,​ INPUT_PULLUP);​ 
 +pinMode(CODE_SW_PIN,​ INPUT_PULLUP);​ 
 +pinMode(TIME_SW_PIN,​ INPUT_PULLUP);​ 
 +</​code>​ 
 + 
 +Encoderul pentru cod este citit prin întreruperi externe pe ambele linii (CLK șDT). Tranzițiile sunt decodate cu un tabel de cuadratură,​ ceea ce reduce citirile inverse produse de bouncing. 
 + 
 +<code cpp> 
 +attachInterrupt(digitalPinToInterrupt(CODE_CLK_PIN),​ code_encoder_interrupt,​ CHANGE); 
 +attachInterrupt(digitalPinToInterrupt(CODE_DT_PIN),​ code_encoder_interrupt,​ CHANGE); 
 +</​code>​ 
 + 
 +==== PWM, servo și buzzer ==== 
 + 
 +Servomotorul SG90 este controlat prin biblioteca Servo.h. În implementarea curentă, unghiul 0 reprezintă zăvorul retras, iar unghiul 90 reprezintă zăvorul coborât. 
 + 
 +<code cpp> 
 +Servo lockServo;​ 
 + 
 +lockServo.attach(SERVO_PIN);​ 
 +lockServo.write(0); ​  // zăvor deschis 
 +lockServo.write(90); ​ // zăvor închis 
 +</​code>​ 
 + 
 +Buzzerul este folosit pentru confirmări scurte, erori și alarmă: 
 + 
 +<code cpp> 
 +void sunaBuzzer(int durata_ms) { 
 +  tone(BUZZER_PIN,​ 1000); 
 +  delay(durata_ms);​ 
 +  noTone(BUZZER_PIN);​ 
 +
 +</​code>​ 
 + 
 +==== I2C ==== 
 + 
 +LCD-ul 1602 este inițializat la adresa 0x27 și este folosit pentru afișarea meniului, codului și timpului rămas. 
 + 
 +<code cpp> 
 +LiquidCrystal_I2C lcd(0x27, 16, 2); 
 + 
 +lcd.init(); 
 +lcd.backlight()
 +lcd.clear();​ 
 +</​code>​ 
 + 
 +Timpul rămas este afișat în format HHh:​MMm:​SSs,​ pentru a putea reprezenta inclusiv sesiuni mai lungi de o oră. 
 + 
 +==== USART ==== 
 + 
 +Serialul este folosit pentru debug în timpul dezvoltării și testării:​ 
 + 
 +<code cpp> 
 +Serial.begin(115200);​ 
 +</​code>​ 
 + 
 +==== Calibrări ==== 
 + 
 +  * Encoderele KY-040 sunt citite pe front descendent șau debounce software scurt, bazat pe millis(). 
 +  * LCD-ul este actualizat doar la schimbări de stare sau valoare, pentru a evita lag-ul ​care poate produce citiri greșite ale encoderelor. 
 +  * Pentru encoderul de timp, fiecare pas modifică durata cu 5 minute. 
 +  * Butoanele encoderelor au un mic delay de confirmare pentru a evita apăsările multiple. 
 +  * Unghiurile servo-ului ​(0 ș90) pot fi ajustate în funcție de zăvorul mecanic real. 
 +  * Servo-ul este alimentat separat la 5V, iar GND-ul sursei servo este comun cu GND-ul plăcii. 
 +  * Dacă bouncing-ul mecanic persistă, se pot adăuga condensatori de 100nF între CLK și GND, respectiv între DT și GND pentru fiecare encoder.
  
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
  
-<note tip> +Am obținut o cutie care se blochează pe un timp ales din encoder și se deschide doar cu codul setat sau după ce expiră timpul. Pe LCD se afișează timpul rămas, iar dacă ușa este forțată pornește alarma
-Care au fost rezultatele ​obţinute în urma realizării proiectului vostru+ 
-</note>+{{url>https://​www.youtube.com/​embed/​Un5VciYyRXg 100%,​400px}}
  
 ===== Concluzii ===== ===== Concluzii =====
 +
 +Proiectul funcționează cum mi-am propus. Partea cea mai dificilă a fost legarea și calibrarea componentelor,​ mai ales encoderele și microswitch-ul.
  
 ===== Download ===== ===== Download =====
  
-<note warning+<html
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului:​ surse, scheme, etcUn fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). +<​style>​ 
- +  a.timelock-github-link { text-decoration:​ none; } 
-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**+  a.timelock-github-link:hover { text-decorationunderline; } 
-</note>+</​style>​ 
 +<a class="​timelock-github-link"​ href="​https://github.com/​Costin10/​TimeLock-Box" target="​_blank"​ rel="​noopener"​> 
 +  <svg width="​18"​ height="​18"​ viewBox="​0 0 16 16" aria-hidden="​true"​ style="​vertical-align:-3px;​margin-right:6px" fill="​currentColor">​ 
 +    <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82A7.64 7.64 0 0 1 8 3.87c.68 0 1.36.09 2 .26 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"></​path>​ 
 +  </​svg>​ 
 +  GitHub 
 +</a> 
 +</html>
  
 ===== Jurnal ===== ===== Jurnal =====
Line 127: Line 313:
  
 <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​ <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​
- 
- 
pm/prj2026/alexandru.jipa2803/costin.spataru.1778959055.txt.gz · Last modified: 2026/05/16 22:17 by costin.spataru
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