Differences

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

Link to this comparison view

pm:prj2026:atoader:bianca.gorgovan [2026/05/09 22:15]
bianca.gorgovan [Descriere generală]
pm:prj2026:atoader:bianca.gorgovan [2026/05/22 00:16] (current)
bianca.gorgovan [Script demo video]
Line 8: Line 8:
  
   * detectează startul și sfârșitul unei lovituri din semnătura inerțială a swing-ului;   * detectează startul și sfârșitul unei lovituri din semnătura inerțială a swing-ului;
-  * estimează **tipul loviturii** — //​forehand//​ vs //​backhand//​ — pe baza sensului de rotație al brațului; 
   * estimează **intensitatea loviturii** — //slab// / //mediu// / //​puternic//​ — din vârful de accelerație;​   * estimează **intensitatea loviturii** — //slab// / //mediu// / //​puternic//​ — din vârful de accelerație;​
   * estimează **viteza unghiulară maximă** a swing-ului prin integrarea giroscopului;​   * estimează **viteza unghiulară maximă** a swing-ului prin integrarea giroscopului;​
   * afișează un **contor de lovituri** și statistici live pe un display TFT 1.8";   * afișează un **contor de lovituri** și statistici live pe un display TFT 1.8";
-  * oferă **feedback vizual instant** printr-un LED RGB (verde = lovitură bună, roșu = slabă, galben = forehand, albastru = backhand); +  * oferă **feedback vizual instant** printr-un LED RGB (verde = lovitură bună, roșu = slabă); 
-  * permite reset / schimbare de mod printr-un buton fizic.+  * permite reset printr-un buton fizic.
  
 ==== Scop ==== ==== Scop ====
Line 35: Line 34:
  
 Sistemul este construit în jurul plăcii de dezvoltare **ATmega328P Xplained Mini**, care joacă rolul de coordonator central. Microcontrollerul citește continuu date inerțiale de la senzorul MPU6050 prin magistrala **I2C**, le procesează printr-o pipeline simplă de detecție și clasificare,​ după care actualizează simultan două canale de output: ecranul TFT (text și statistici) prin **SPI** și LED-ul RGB (feedback luminos) prin trei canale **PWM**. Un buton conectat ca GPIO permite reset-ul contorului. Sistemul este construit în jurul plăcii de dezvoltare **ATmega328P Xplained Mini**, care joacă rolul de coordonator central. Microcontrollerul citește continuu date inerțiale de la senzorul MPU6050 prin magistrala **I2C**, le procesează printr-o pipeline simplă de detecție și clasificare,​ după care actualizează simultan două canale de output: ecranul TFT (text și statistici) prin **SPI** și LED-ul RGB (feedback luminos) prin trei canale **PWM**. Un buton conectat ca GPIO permite reset-ul contorului.
-}==== Schemă bloc ==== 
  
 +==== Schemă bloc ====
 +{{ :​pm:​prj2026:​atoader:​schema_blocbgorgovan.png?​500 |}}
  
 +  * **MPU6050** ⇄ **ATmega328P** — //I2C, 100 kHz//: la fiecare ~10 ms, MCU-ul (master) citește 14 octeți (3× accel + temp + 3× gyro) de la slave-ul MPU6050 (adresa 0x68). Sunt folosite primitivele ''​twi_start''​ / ''​twi_write''​ / ''​twi_read_ack''​ / ''​twi_read_nack''​ / ''​twi_stop''​ din driverul de la Lab 6.
 +  * **ATmega328P → modul detecție swing** //​(software)//:​ un filtru pe magnitudinea accelerației (||a|| − g) detectează startul și sfârșitul unei lovituri.
 +  * **ATmega328P → modul clasificare** //​(software)//:​ pe baza semnului ω_z (giroscop, axa verticală a încheieturii) și a vârfului de accelerație,​ decide forehand/​backhand și slab/​mediu/​puternic.
 +  * **ATmega328P → ST7735 TFT 1.8"** — //SPI, master → slave//: după fiecare lovitură detectată, MCU-ul redesenează zona de text și afișează:
 +    * ''​HITS:​ 24''​
 +    * ''​SHOT:​ FOREHAND''​
 +    * ''​POWER:​ HIGH''​
 +    * ''​SWING:​ 320 deg/​s''​
 +  * **ATmega328P → LED RGB (R+G)** — //PWM//: 2 canale PWM independente,​ generate de Timer 0 (OC0B = verde) și Timer 2 (OC2B = roșu), modulează intensitatea celor două culori. LED-ul are anod comun → driver-ul software inversează duty-cycle-ul (0 = stins, 255 = maxim).
 +  * **Buton → ATmega328P** — //GPIO + INT0//: tratat în întrerupere externă pe PD2, cu debouncing software. La apăsare = reset contor lovituri.
 + 
 +==== Module software ====
 + 
 +| Modul | Sursă | Descriere |
 +| ''​twi.c/​.h''​ | Lab 6 (preluat, F_CPU adaptat la 16 MHz) | driver I2C low-level |
 +| ''​mpu6050.c/​.h''​ | **scris** (după pattern-ul ''​mpl3115a2''​ din Lab 6) | init, citire accel/gyro burst, calibrare offset |
 +| ''​spi.c/​.h''​ | Lab 5 (preluat) | driver SPI low-level |
 +| ''​st7735.c/​.h''​ | Lab 5 (preluat, adaptat pentru pini noi) | driver TFT 1.8" |
 +| ''​timers.c/​.h''​ | Lab 3 (preluat, extins) | configurare PWM 2 canale pe Timer 0 + Timer 2 |
 +| ''​rgb.c/​.h''​ | **scris** | wrapper PWM pentru LED RGB (R+G) cu efecte (solid / blink / fade) |
 +| ''​swing_detect.c/​.h''​ | **scris** | detecție swing și clasificare |
 +| ''​main.c''​ | **scris** | bucla principală,​ integrare module, FSM |
  
  
 +
 +
 +===== Hardware Design =====
 ===== Hardware Design ===== ===== Hardware Design =====
 +
 +==== 1. Componentele folosite și rolul lor în proiect ====
 +
 +  * **ATmega328P Xplained Mini** — placa de dezvoltare cu microcontrolerul ATmega328P (AVR 8-bit, 16 MHz). Are debugger/​programator integrat (mEDBG) și port serial virtual (CDC), deci poate fi programată și depanată direct prin USB, fără programator extern. Rolul ei este de **coordonator central**: citește datele de mișcare de la senzor, le procesează,​ comandă display-ul și LED-ul și tratează apăsarea butonului.
 +  * **MPU6050 (modul GY-521)** — senzor inerțial 6-DOF (accelerometru 3 axe + giroscop 3 axe, 16-bit fiecare). Comunică prin **I2C** la adresa ''​0x68''​. Rolul lui: **achiziția semnăturii inerțiale a loviturii** — accelerometrul detectează startul și sfârșitul unei lovituri prin praguri de magnitudine,​ iar giroscopul oferă sensul de rotație pentru clasificarea forehand/​backhand.
 +  * **Display TFT 1.8" ST7735** — ecran color 128×160 pixeli, control prin **SPI**. Rolul lui: **afișarea informațiilor în timp real** — contor de lovituri, tipul loviturii, intensitatea și viteza unghiulară maximă.
 +  * **LED RGB 5 mm cu anod comun** — folosim canalele Roșu și Verde. Rolul lui: **feedback vizual instant** — verde pentru o lovitură puternică, roșu pentru o lovitură slabă. Intensitatea fiecărei culori este controlată prin **PWM**.
 +  * **Buton tactil 6×6×5 mm** — rolul lui: **resetarea contorului de lovituri**. Este tratat printr-o întrerupere externă pe linia INT0.
 +  * **Componente pasive și de suport** — rezistori de 220 Ω pentru limitarea curentului prin LED, breadboard MB-102 pentru prototipare,​ fire de legătură, suport de baterie 9V pentru alimentarea autonomă (în faza de dezvoltare alimentarea se face prin USB).
 +
 +==== 2. Pinii folosiți și justificarea alegerilor ====
 +
 +Microcontrolerul ATmega328P are un număr limitat de pini cu funcții speciale (I2C, SPI, PWM, întreruperi). Alegerea fiecărui pin nu este arbitrară, ci impusă de funcția hardware de care avem nevoie.
 +
 +^ Semnal ^ Pin AVR ^ Componentă ^ Justificarea alegerii ^
 +| SDA | PC4 | MPU6050 | Pin hardware TWI al ATmega328P — singura opțiune pentru I2C hardware. |
 +| SCL | PC5 | MPU6050 | Pin hardware TWI — pereche cu SDA. |
 +| SCK | PB5 | Display | Pin hardware SPI SCK. |
 +| MOSI (SDA) | PB3 | Display | Pin hardware SPI MOSI. |
 +| CS | PB2 | Display | Pinul hardware SS; trebuie configurat ca ieșire, altfel modulul SPI cade în mod slave. |
 +| DC | PB1 | Display | GPIO liber, adiacent fizic pinilor SPI — cablaj scurt. |
 +| RST | PB0 | Display | GPIO liber, adiacent pinului DC. |
 +| Rosu (R) | PD3 | LED RGB | Ieșire OC2B — PWM hardware generat de Timer 2. |
 +| Verde (G) | PD5 | LED RGB | Ieșire OC0B — PWM hardware generat de Timer 0. |
 +| Buton | PD2 | Buton | Pin INT0 — întrerupere externă dedicată, cu pull-up intern activat în software. |
 +
 +**De ce I2C pe PC4/PC5:** magistrala I2C hardware (TWI) a ATmega328P este fixată pe acești doi pini. Nu există alternativă dacă vrem comunicare I2C hardware, fără emulare software.
 +
 +**De ce SPI pe portul B:** modulul SPI hardware folosește obligatoriu PB3 (MOSI) și PB5 (SCK). Pinii de control specifici ST7735 (CS, DC, RST) pot fi GPIO oarecare; i-am ales pe PB0–PB2 pentru a fi grupați lângă pinii SPI, ceea ce scurtează cablajul și reduce riscul de erori.
 +
 +**De ce PWM pe PD3 și PD5:** pe ATmega328P, pinul PD3 este ieșirea comparatorului OC2B (Timer 2), iar PD5 este OC0B (Timer 0). Acestea sunt ieșirile de PWM hardware disponibile,​ care generează semnalul fără a încărca procesorul.
 +
 +**De ce butonul pe PD2:** pinul PD2 corespunde întreruperii externe INT0. Resetarea contorului este un eveniment punctual, ideal de tratat într-o rutină de întrerupere,​ fără a fi nevoie de verificare repetată (polling) în bucla principală.
 +
 +**Lipsa conflictelor:​** cele trei magistrale folosesc porturi diferite — I2C pe portul C, SPI pe portul B, PWM-ul LED-ului pe portul D — deci nu există suprapuneri. Singura observație:​ PB5 este folosit și de LED-ul utilizator de pe placă, care va pâlpâi în timpul transmisiilor SPI; acest efect este pur cosmetic și nu afectează funcționarea.
 +
 +==== 3. Schema electrică ====
 +{{ :​pm:​prj2026:​atoader:​circuit_image.png?​400 |}}
 +
 +
 +==== 4. Imagini și dovezi de funcționare ====
 +
 +=== Montajul complet pe breadboard ===
 +
 +
 +Imaginea arată sistemul asamblat pe breadboard: placa ATmega328P Xplained Mini alimentată prin USB, senzorul MPU6050, display-ul ST7735, LED-ul RGB cu cei doi rezistori de limitare și butonul de reset. Alimentarea este distribuită prin șinele laterale ale breadboard-ului.
 +{{ :​pm:​prj2026:​atoader:​ecran.png?​300 |}}
 +
  
 ==== Listă de piese ==== ==== Listă de piese ====
Line 62: Line 135:
  
 ===== Software Design ===== ===== Software Design =====
 +==== Mediu de dezvoltare ====
 +Proiectul a fost dezvoltat folosind PlatformIO cu toolchain-ul avr-gcc, integrat în Visual Studio Code. Compilatorul țintă este ''​avr-gcc''​ cu flagul ''​-mmcu=atmega328p''​ și ''​-DF_CPU=16000000UL''​. Deoarece codul folosește ''​sqrt()''​ din ''<​math.h>'',​ au fost adăugate flagurile de linker pentru floating point:
 +<code ini>
 +build_flags = -Wl,​-u,​vfprintf -lprintf_flt -lm
 +</​code>​
 +Depanarea s-a realizat prin interfața UART la 9600 baud, cu mesaje trimise către un terminal serial (Serial Monitor din PlatformIO sau PuTTY).
 +==== Biblioteci și surse folosite ====
 +^ Modul ^ Fișier sursă ^ Origine ^ Rol ^
 +| Driver I2C/TWI | ''​twi.c''​ / ''​twi.h''​ | Preluat din Laboratorul 6, adaptat (F_CPU = 16 MHz, timeout adăugat) | Comunicare I²C cu MPU6050 |
 +| Driver SPI | ''​spi.c''​ / ''​spi.h''​ | Preluat din Laboratorul 5 | Comunicare SPI cu display-ul ST7735 |
 +| Driver TFT | ''​st7735.c''​ / ''​st7735.h''​ | Preluat din Laboratorul 5, adaptat pentru pinii ATmega328P Xplained Mini | Afișare text și grafice pe ecranul 1.8" |
 +| Loop principal + logică | ''​main.c''​ | Scris integral în cadrul proiectului | Inițializare,​ FSM detecție swing, clasificare,​ UART, LED RGB, buton |
 +| AVR LibC | ''<​avr/​io.h>'',​ ''<​avr/​interrupt.h>'',​ ''<​util/​delay.h>'',​ ''<​math.h>''​ | Standard AVR-LibC | Acces registre, întreruperi,​ delay, sqrt() |
 +Nu au fost folosite biblioteci externe de tip Arduino sau framework-uri de nivel înalt — întreaga stivă este bare-metal C pe AVR.
 +==== Algoritmi și structuri implementate ====
 +=== 1. Citirea senzorului MPU6050 prin I²C (burst read) ===
 +Funcția ''​mpu_read_gyro()''​ realizează o citire în rafală (burst read) a 6 octeți consecutivi începând de la registrul ''​0x43''​ (GYRO_XOUT_H). Secvența respectă protocolul I²C descris în Laboratorul 6:
 +<code c>
 +twi_start(SLA_W) → twi_write(REG_GYRO_X) →
 +twi_start(SLA_R) → twi_read(ACK) x5 → twi_read(NACK) → twi_stop()
 +</​code>​
 +Cei 6 octeți sunt recombinați în trei valori ''​int16_t''​ (gx, gy, gz) prin shift și OR pe biți:
 +<code c>
 +*gx = (int16_t)((b[0] << 8) | b[1]);
 +</​code>​
 +=== 2. Calculul magnitudinii vectorului giroscopic ===
 +Pentru a obține un scalar independent de orientarea rachetei, se calculează norma euclidiană a vectorului angular:
 +<​code>​
 +mag = sqrt(gx² + gy² + gz²)
 +</​code>​
 +Aceasta este implementată în ''​gyro_magnitude()''​ folosind ''​sqrt()''​ din ''<​math.h>''​ aplicat pe ''​double''​. Valorile intermediare sunt calculate pe ''​int32_t''​ pentru a evita overflow-ul pe 16 biți:
 +<code c>
 +int32_t sx = (int32_t)gx * gx;
 +</​code>​
 +Avantajul magnitudinii față de o singură axă este robustețea la montaj: indiferent cum este fixat senzorul pe rachetă, o mișcare rapidă va produce o valoare mare.
 +=== 3. Mașina de stări pentru detecția swing-ului (histerezis) ===
 +Detecția loviturii folosește un filtru cu histerezis pe două praguri, pentru a evita declanșările false datorită zgomotului sau vibrațiilor mici:
  
 +Starea IDLE: dacă ''​mag > GYRO_THR_START''​ (5000), se intră în starea ''​IN_HIT''​ și se înregistrează primul vârf.
 +Starea IN_HIT: se urmărește valoarea maximă (''​peak_gyro''​). Dacă ''​mag < GYRO_THR_END''​ (1500), lovitura s-a terminat → clasificare și reset.
 +Cooldown: după fiecare lovitură detectată, un contor de 1500 ms blochează detecțiile noi, pentru a lăsa timp rachetei să revină la poziția inițială fără a genera lovituri fantomă.
 +
 +Separarea pragului de intrare (5000) față de cel de ieșire (1500) formează un gap de histerezis de ~3500 unități, eliminând oscilațiile în jurul pragului.
 +=== 4. Clasificarea loviturii ===
 +La finalul unui swing, valoarea ''​peak_gyro''​ este comparată cu pragul ''​GYRO_GOOD_THR''​ (20000):
 +<code c>
 +if (peak_gyro >= GYRO_GOOD_THR) → BUNA (strong_hits++)
 +else                             → SLABA (weak_hits++)
 +</​code>​
 +=== 5. Feedback vizual prin LED RGB — degradeu roșu→verde ===
 +Funcția ''​led_from_peak()''​ mapează ''​peak_gyro''​ din intervalul [GYRO_MIN, GYRO_MAX] = [5000, 30000] pe un factor ''​f ∈ [0, 255]'':​
 +<code c>
 +f = (peak - GYRO_MIN) * 255 / (GYRO_MAX - GYRO_MIN)
 +green = f;   red = 255 - f;
 +</​code>​
 +Valorile sunt scalate la 80% din maxim (''​* 4 / 5''​) pentru a nu orbi utilizatorul. LED-ul are anod comun, deci duty cycle-ul este inversat: ''​OCRxB = 255 - valoare'',​ conform macrourilor ''​LED_SET_R()''​ și ''​LED_SET_G()''​. Semnalele PWM hardware sunt generate de Timer 0 (OC0B → verde, PD5) și Timer 2 (OC2B → roșu, PD3), fără intervenție software în buclă — exact modul Fast PWM studiat în Laboratorul 3.
 +=== 6. Debouncing software pentru buton (INT0) ===
 +Butonul pe PD2 este tratat în întreruperea externă ''​INT0_vect''​. Debouncing-ul se realizează prin compararea unui contor global de tick-uri (''​global_tick'',​ incrementat la fiecare 20 ms în bucla principală) cu momentul ultimei apăsări valide:
 +<code c>
 +if ((uint16_t)(global_tick - last_press_tick) > 3)  // > 3 × 20ms = 60ms
 +</​code>​
 +Această abordare non-blocantă este echivalentă cu fereastra de 30–50 ms recomandată în Laboratorul 2, fără a bloca execuția din ''​main''​.
 +=== 7. Afișare pe TFT ST7735 prin SPI ===
 +Driver-ul ''​st7735.c''​ folosește interfața SPI hardware (PB5=SCK, PB3=MOSI, PB2=CS) cu pini de control GPIO (PB0=DC, PB1=RST). Fontul 5×7 este stocat în memoria Flash (''​PROGMEM''​) și citit cu ''​pgm_read_byte()'',​ economisind RAM-ul limitat al ATmega328P. Actualizarea ecranului se face selectiv — doar zona numerelor (coordonate fixe) — pentru a minimiza traficul SPI și latența vizibilă.
  
 ===== Rezultate Obținute ===== ===== Rezultate Obținute =====
 +==== Stadiul actual al implementării software ====
 +Implementarea software este completă și funcțională. Toate modulele sunt integrate și validate pe hardware real:
 +
 + ​Inițializare și citire continuă MPU6050 prin I²C la 100 kHz
 + ​Detecție automată lovituri cu histerezis și cooldown
 +Clasificare binară slab/bun bazată pe peak-ul giroscopului
 +Afișare live pe TFT ST7735 (total, slabe, bune)
 +Feedback LED RGB cu degradeu roșu→verde proporțional cu intensitatea
 +Reset prin buton fizic cu debouncing software
 +Logging serial UART la 9600 baud pentru depanare și calibrare
 +
 +==== Motivația alegerii bibliotecilor ====
 +S-a optat deliberat pentru o arhitectură bare-metal, fără Arduino sau alte framework-uri de nivel înalt, din următoarele motive:
 +
 +Control precis al resurselor hardware: ATmega328P are 2 KB RAM și 32 KB Flash. Un framework de tip Arduino adaugă sute de octeți overhead pentru funcționalități nefolosite.
 +Familiaritate cu laboratoarele cursului: driver-ele ''​twi.c'',​ ''​spi.c''​ și ''​st7735.c''​ sunt extensii directe ale scheletelor din Laboratoarele 5 și 6, asigurând o înțelegere profundă a protocolelor.
 +Latență determinabilă:​ în sisteme de detecție în timp real, buclele de polling cu ''​_delay_ms()''​ și întreruperile hardware oferă timinguri predictibile,​ spre deosebire de un RTOS sau scheduler complex.
 +
 +Singura funcție din bibliotecă externă (AVR-LibC) cu potențial overhead este ''​sqrt()''​ pe ''​double''​ — acceptabil deoarece este apelată o singură dată per eșantion (la 20 ms), deci ~50 apeluri/​secundă,​ neglijabil față de ciclurile CPU disponibile la 16 MHz.
 +==== Elementul de noutate ====
 +Față de implementările academice tipice care testează un singur senzor izolat, acest proiect integrează simultan patru periferice hardware diferite pe același microcontroller (I²C + SPI + PWM × 2 + UART + GPIO interrupt), cu o logică de procesare a semnalului în timp real care produce output multimodal (vizual + serial) în același ciclu de 20 ms. Degradeul de culoare continuu al LED-ului (nu simplu roșu/verde binar) și algoritmul de histerezis cu cooldown adaptiv sunt elemente care aduc valoare practică față de o implementare banală cu prag simplu.
 +==== Justificarea utilizării funcționalităților din laborator ====
 +^ Funcționalitate ^ Laborator sursă ^ Utilizare în proiect ^
 +| UART / printf redirecționat | Laboratorul 1 | Logging serial: magnitudine giroscop, tip lovitură, contor — esențial pentru calibrarea pragurilor |
 +| Întrerupere externă INT0 + debouncing | Laboratorul 2 | Reset contor prin buton fizic, non-blocant |
 +| PWM hardware Fast PWM, Timer 0 + Timer 2 | Laboratorul 3 | Control intensitate LED RGB cu anod comun pe două canale independente |
 +| SPI hardware + driver ST7735 | Laboratorul 5 | Afișare statistici live pe TFT 1.8" color |
 +| I²C / TWI + citire registre senzor | Laboratorul 6 | Citire burst gyroscop MPU6050, același pattern ca MPL3115A2 din laborator |
 +==== Scheletul proiectului și interacțiunea dintre funcționalități ====
 +Bucla principală din ''​main()''​ rulează la o perioadă fixă de SAMPLE_MS = 20 ms și urmează un pipeline liniar:
 +<​code>​
 +[Buton ISR] ─────────────────────────────────► reset_flag
 +                                                    │
 +main loop (20ms tick): ​                             ▼
 +  1. Verifică reset_flag → resetează contoare și ecran
 +  2. mpu_read_gyro() ──I²C──► MPU6050 ──► gx, gy, gz
 +  3. gyro_magnitude() ──────────────────► mag (int32_t)
 +  4. FSM histerezis:
 +       IDLE ──mag > 5000──► IN_HIT (track peak)
 +       ​IN_HIT ──mag < 1500──► clasificare + LED + ecran update
 +  5. led_from_peak() ──PWM──► Timer0/​Timer2 ──► LED RGB
 +  6. screen_update_counts() ──SPI──► ST7735
 +  7. Debug UART la fiecare 25 iterații (~500 ms)
 +  8. _delay_ms(20) + global_tick++
 +</​code>​
 +Validarea funcționării s-a realizat în două etape:
 +
 +Validare prin UART: cu senzorul în repaus, mesajele ''​gyro_mag=XXX''​ confirmau valori < 500. Scuturând senzorul brusc, valorile depășeau 10000–30000,​ confirmând că pragurile GYRO_THR_START = 5000 separă corect zgomotul de fundal de un swing real.
 +Validare vizuală: LED-ul schimba culoarea consistent cu intensitatea mișcării (roșu pentru mișcări ușoare, verde/​galben pentru swing-uri puternice), iar ecranul TFT incrementa contorul corect la fiecare lovitură detectată.
 +
 +==== Calibrarea senzorului ====
 +MPU6050 a fost folosit în configurația implicită (fără calibrare offset a giroscopului),​ deoarece:
 +
 +Detecția se bazează pe magnitudini relative (este swing vs. nu este swing), nu pe valori absolute. Driftul de offset al giroscopului (tipic 1–3 LSB/°C) este neglijabil față de valorile de 5000–30000 atinse în swing.
 +Pragurile au fost determinate empiric prin UART logging: sistemul a fost conectat la un terminal serial și senzorul a fost mișcat cu intensități variate. S-au observat valorile tipice:
 +
 +Repaus / vibrații mici: mag ≈ 100–400
 +Mișcare lentă a mâinii: mag ≈ 800–2000
 +Swing moderat: mag ≈ 5000–12000
 +Swing puternic: mag ≈ 15000–28000
 +
 +
 +
 +Pe baza acestor observații s-au stabilit: GYRO_THR_START = 5000, GYRO_THR_END = 1500, GYRO_GOOD_THR = 20000.
 +==== Optimizări realizate ====
 +^ Optimizare ^ Unde ^ Motivație ^
 +| Font stocat în Flash (''​PROGMEM''​) | ''​st7735.c''​ | Fontul 5×7 ASCII ocupă 475 octeți; dacă ar fi în RAM, ar consuma ~23% din cei 2KB disponibili |
 +| Actualizare selectivă a ecranului | ''​screen_update_counts()''​ | Se rescrie doar zona cu numere (3 stringuri de 5 caractere), nu întregul ecran; reduce traficul SPI cu ~95% față de ''​st7735_fill()''​ complet |
 +| Padding cu spații în ''​sprintf''​ | ''​main.c''​ | ''​sprintf(buf,​ "​%-5u",​ val)''​ suprascrie cifrele vechi fără a șterge și redesena fundalul — evită flickering |
 +| Histerezis cu cooldown | ''​main.c''​ | Fără cooldown, un singur swing ar genera 5–10 detecții false; cooldown-ul de 1500 ms garantează maximum 1 lovitură per swing |
 +| Calcul magnitudine pe ''​int32_t''​ | ''​gyro_magnitude()''​ | Produsele ''​gx*gx''​ pe ''​int16_t''​ ar produce overflow (max 32767² = 1.07×10⁹ > 32767); cast la ''​int32_t''​ înainte de înmulțire previne silently wrong results |
 +| Debouncing non-blocant | ''​ISR(INT0_vect)''​ | Compararea tick-urilor nu blochează ISR-ul și nici bucla principală,​ față de un ''​_delay_ms()''​ în ISR care ar dezactiva alte întreruperi |
 +==== Script demo video ====
 +{{:​pm:​prj2026:​atoader:​demo_racheta.mp4.zip|}}
 +
  
  
Line 72: Line 283:
  
 ===== Download ===== ===== Download =====
 +{{:​pm:​prj2026:​atoader:​smart_tennis_racket.zip|}}
  
  
Line 97: Line 309:
  
   * jrowberg / i2cdevlib — bibliotecă C++ MPU6050 (referință pentru registre): [[https://​github.com/​jrowberg/​i2cdevlib/​tree/​master/​Arduino/​MPU6050]]   * jrowberg / i2cdevlib — bibliotecă C++ MPU6050 (referință pentru registre): [[https://​github.com/​jrowberg/​i2cdevlib/​tree/​master/​Arduino/​MPU6050]]
-  * "​Tennis Stroke Recognition Using Inertial Data" — articole academice pe IEEE Xplore ​(de citat ulterior, în etapa de etapa 3 documentație).+  * "​Tennis Stroke Recognition Using Inertial Data" — articole academice pe IEEE Xplore.
  
 <​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/atoader/bianca.gorgovan.1778354121.txt.gz · Last modified: 2026/05/09 22:15 by bianca.gorgovan
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