This shows you the differences between two versions of the page.
|
pm:prj2026:vlad.radulescu2901:paul.prodan [2026/05/18 14:42] 127.0.0.1 external edit |
pm:prj2026:vlad.radulescu2901:paul.prodan [2026/05/25 11:34] (current) paul.prodan |
||
|---|---|---|---|
| Line 21: | Line 21: | ||
| - Scannerul E2100 citeste barcode-ul prin SoftwareSerial (PD2/PD3), ATmega il trimite catre PC | - Scannerul E2100 citeste barcode-ul prin SoftwareSerial (PD2/PD3), ATmega il trimite catre PC | ||
| - PC-ul cauta dimensiunile in baza de date si le trimite inapoi (''DIMS:'') sau ''DB:NOT_FOUND'' | - PC-ul cauta dimensiunile in baza de date si le trimite inapoi (''DIMS:'') sau ''DB:NOT_FOUND'' | ||
| - | - HC-SR04 masoara inaltimea (PD7/PB0) si diametrul (PC0/PC3), firmware-ul valideaza dimensiunile | + | - HC-SR04 masoara inaltimea (PB1/PB2) si diametrul (PD7/PB0), firmware-ul valideaza dimensiunile |
| - Daca acceptata: cele doua motoare DC (L9110S canal A PC1/PC2 + canal B PD5/PD6) pornesc inainte si antreneaza banda conveyor; LCD afiseaza "ACCEPTED" | - Daca acceptata: cele doua motoare DC (L9110S canal A PC1/PC2 + canal B PD5/PD6) pornesc inainte si antreneaza banda conveyor; LCD afiseaza "ACCEPTED" | ||
| - Daca respinsa: motoarele pornesc in sens invers si returneaza sticla; LCD afiseaza "REJECTED" | - Daca respinsa: motoarele pornesc in sens invers si returneaza sticla; LCD afiseaza "REJECTED" | ||
| Line 128: | Line 128: | ||
| PD7 GPIO output HC-SR04 #1 TRIG (diametru) | PD7 GPIO output HC-SR04 #1 TRIG (diametru) | ||
| PB0 GPIO input HC-SR04 #1 ECHO (diametru) | PB0 GPIO input HC-SR04 #1 ECHO (diametru) | ||
| - | PC0 GPIO output HC-SR04 #2 TRIG (inaltime) | + | PB1 GPIO output HC-SR04 #2 TRIG (inaltime) |
| PC1 GPIO output L9110S A-IA (motor conveyor #1 directie A) | PC1 GPIO output L9110S A-IA (motor conveyor #1 directie A) | ||
| PC2 GPIO output L9110S A-IB (motor conveyor #1 directie B) | PC2 GPIO output L9110S A-IB (motor conveyor #1 directie B) | ||
| - | PC3 GPIO input HC-SR04 #2 ECHO (inaltime) | + | PB2 GPIO input HC-SR04 #2 ECHO (inaltime) |
| PC4 I2C SDA LCD I2C 16x2 (display stare masina) | PC4 I2C SDA LCD I2C 16x2 (display stare masina) | ||
| PC5 I2C SCL LCD I2C 16x2 (display stare masina) | PC5 I2C SCL LCD I2C 16x2 (display stare masina) | ||
| Line 147: | Line 147: | ||
| | **PD7** | GPIO output | TRIG necesita doar puls simplu 10µs — orice GPIO functioneaza. | | | **PD7** | GPIO output | TRIG necesita doar puls simplu 10µs — orice GPIO functioneaza. | | ||
| | **PB0** | GPIO input | ICP1 (Input Capture Pin al Timer1) — permite migrare la masurare hardware precisa cu timer capture fara a modifica pinout-ul. | | | **PB0** | GPIO input | ICP1 (Input Capture Pin al Timer1) — permite migrare la masurare hardware precisa cu timer capture fara a modifica pinout-ul. | | ||
| - | | **PC0 / PC3** | GPIO (HC-SR04 #2) | Port C (analogic), folosit ca GPIO digital. Grupat logic cu PC1/PC2 pentru coerenta in cod. | | + | | **PB1 / PB2** | GPIO (HC-SR04 #2 TRIG/ECHO) | Pini digitali Port B liberi. Relocati de la PC0/PC3 dupa ce acestia au dovedit probleme hardware pe board. Adiacenti cu PB0 (ECHO senzor #1), grupand logic toti pinii HC-SR04 in Port B. | |
| | **PC1 / PC2** | GPIO output (motor #1) | Consecutivi cu PC0/PC3 — toata sectiunea sensor+motor grupata in Port C. | | | **PC1 / PC2** | GPIO output (motor #1) | Consecutivi cu PC0/PC3 — toata sectiunea sensor+motor grupata in Port C. | | ||
| | **PC4 / PC5** | I2C SDA/SCL | **Singura optiune posibila**: TWI (I2C hardware) al ATmega328P este implementat fix pe acesti doi pini. Nu exista alternativa hardware. | | | **PC4 / PC5** | I2C SDA/SCL | **Singura optiune posibila**: TWI (I2C hardware) al ATmega328P este implementat fix pe acesti doi pini. Nu exista alternativa hardware. | | ||
| Line 191: | Line 191: | ||
| {{:pm:prj2026:vlad.radulescu2901:prodan_paul_8.jpeg?700|Circuit SmartRVM pe breadboard}} | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_8.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| {{:pm:prj2026:vlad.radulescu2901:prodan_paul_9.jpeg?700|Circuit SmartRVM pe breadboard}} | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_9.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| - | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_10.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| ===== Software Design ===== | ===== Software Design ===== | ||
| Line 251: | Line 250: | ||
| * Componentele hardware au sosit; urmeaza conectarea fizica si calibrarea | * Componentele hardware au sosit; urmeaza conectarea fizica si calibrarea | ||
| </note> | </note> | ||
| + | |||
| + | ===== Milestone 3 — Implementare Software ===== | ||
| + | |||
| + | ==== Stadiul actual ==== | ||
| + | |||
| + | <note tip> | ||
| + | Tot codul este finalizat si functional. Firmware-ul compileaza in toate trei configuratiile: | ||
| + | |||
| + | ^ Environment ^ Scop ^ | ||
| + | | ''xplained_mini'' | hardware real | | ||
| + | | ''xplained_mini_sim'' | simulare cu stubs software | | ||
| + | | ''xplained_mini_diag'' | diagnostic senzori fara actuatori | | ||
| + | |||
| + | Masina de stari trece corect prin toate starile, motoarele sunt controlate prin ''DcConveyor'', LCD-ul afiseaza starea si rezultatul. | ||
| + | |||
| + | Pe platforma web: server Express + SQLite functional cu toate rutele REST, WebSocket cu update-uri in timp real (< 50ms), toate paginile operationale — Dashboard, Barcodes, Transactions, Statistics, Simulation si ''/diag''. | ||
| + | </note> | ||
| + | |||
| + | ==== Biblioteci folosite ==== | ||
| + | |||
| + | <note tip> | ||
| + | **Firmware:** | ||
| + | |||
| + | * **SoftwareSerial** — UART0 e ocupat de mEDBG (USB la PC), deci scannerul E2100 a trebuit conectat pe PD2/PD3 (INT0/INT1) prin SoftwareSerial. INT0/INT1 sunt necesare pentru receptie fiabila prin intreruperi. | ||
| + | * **LiquidCrystal_I2C** — LCD-ul are driver PCF8574 si comunica prin I2C. Varianta 4-bit paralel ar fi consumat 6 pini in plus, inacceptabil pe ATmega328P. | ||
| + | * **FixedString<N>, RingBuffer<T,N>, Timer** (proprii) — clasa ''String'' din Arduino aloca dinamic si fragmenteaza heap-ul. Pe 2KB RAM asta se termina cu crash dupa ore de rulare. Toate stringurile sunt pe stack. | ||
| + | |||
| + | **Platforma web:** | ||
| + | |||
| + | * **serialport** — singura biblioteca Node.js serioasa pentru USB serial cross-platform. | ||
| + | * **Socket.IO** — serverul impinge evenimentele la browser imediat ce le primeste de la ATmega (3-8ms latenta pe localhost), fara polling. | ||
| + | * **Drizzle ORM** — schema TypeScript-first, SQLite embedded, zero configurare server. | ||
| + | * **Zod** — validare body request; schema e si tip TypeScript direct, fara duplicare. | ||
| + | * **Vite, Tailwind v4, shadcn/ui, Recharts** — development rapid, componente accesibile, grafice SVG native React. | ||
| + | </note> | ||
| + | |||
| + | ==== Ce e diferit la proiect ==== | ||
| + | |||
| + | <note tip> | ||
| + | **Framework de simulare integrat in firmware.** Inainte sa soseasca componentele, ''xplained_mini_sim'' rula pe placa cu toti senzorii inlocuiti de stubs controlabile din interfata web: | ||
| + | |||
| + | <code> | ||
| + | SIM:BEAM:ON → ATmega simuleaza detectia sticlei | ||
| + | SIM:BARCODE:5941 → StubScanner returneaza barcode-ul | ||
| + | SIM:HEIGHT:220 / SIM:DIAM:65 → dimensiuni simulate | ||
| + | → RESULT:ACCEPTED (fara nicio piesa conectata) | ||
| + | </code> | ||
| + | |||
| + | Asta a permis testarea integrala a masinii de stari — timeout, jam, barcode inexistent — cu saptamani inainte de hardware. Aceeasi logica din ''RvmController'' ruleaza identic in ambele build-uri. | ||
| + | |||
| + | **Arhitectura DDD pe ATmega cu 2KB RAM.** Domain, application, infrastructure si stubs sunt straturi separate; niciun header Arduino nu ajunge in logica de business. Mai greu de pus la punct, dar debugging-ul a fost mult mai simplu. | ||
| + | |||
| + | **Firmware de diagnostic separat.** ''xplained_mini_diag'' trimite snapshot-uri cu toti senzorii la 500ms fara sa activeze actuatori. Prin pagina ''/diag'' am verificat fiecare senzor individual si am descoperit rapid ca pinul PC0 era defect pe board — HC-SR04 #2 a fost mutat pe PB1/PB2. | ||
| + | </note> | ||
| + | |||
| + | ==== Functionalitatile din laborator ==== | ||
| + | |||
| + | <note tip> | ||
| + | ^ Laborator ^ Cum e folosita ^ | ||
| + | | **Lab 1 — UART** | UART0 (PD0/PD1) pentru protocolul ATmega↔PC (''CMD:'', ''DIMS:'', ''BARCODE:'', ''RESULT:''). SoftwareSerial pe PD2/PD3 pentru scannerul E2100. | | ||
| + | | **Lab 2 — Debugging** | Toate tranzitiile vizibile in Serial Monitor. ''MockConnection'' pe server injecteaza secvente fara ATmega conectat. | | ||
| + | | **Lab 4 — Timere** | Timeout-urile din ''RvmController'' (scanare 5s, masurare 2s, transport 10s) folosesc ''Timer::elapsed()'' cu ''millis()''. Niciun ''delay()'' — loop la ~0.3ms/iteratie. | | ||
| + | | **Lab 5 — GPIO** | TRIG HC-SR04 (PD7, PB1): puls 10µs. ECHO (PB0, PB2): ''pulseIn()''. IR slot (PD4): ''digitalRead()''. L9110S (PC1, PC2, PD5, PD6): directia motoarelor. | | ||
| + | | **Lab 7 — I2C/TWI** | LCD I2C cu driver PCF8574 pe TWI hardware (PC4/PC5), adresa 0x27. | | ||
| + | </note> | ||
| + | |||
| + | ==== Structura si interactiunea dintre componente ==== | ||
| + | |||
| + | <note tip> | ||
| + | <code> | ||
| + | device/lib/ | ||
| + | common/ FixedString, RingBuffer, Timer | ||
| + | domain/ interfete pure: IScanner, ITransport, IDisplay, ICommChannel... | ||
| + | application/ RvmController (masina de stari), BottleValidator | ||
| + | infrastructure/ UartProtocol, Gm65Scanner, HcSr04Sensor, DcConveyor, LcdI2cDisplay | ||
| + | stubs/ StubScanner, StubHeightSensor, StubTransport, SimBridge | ||
| + | device/src/ main.cpp / main_sim.cpp / main_diag.cpp | ||
| + | |||
| + | platform/ | ||
| + | shared/ serial-protocol.ts (tipuri comune server+client) | ||
| + | server/ domain, application, infrastructure (serial, db, websocket), routes | ||
| + | client/ Dashboard, Barcodes, Transactions, Statistics, Simulation, SensorDiag | ||
| + | </code> | ||
| + | |||
| + | **Flux normal:** sticla → IR(PD4) → ''RvmController.tick()'' → E2100 → ''BARCODE:'' pe UART0 → server cauta in SQLite → ''DIMS:'' inapoi → ATmega masoara HC-SR04 → ''MEASURED:'' → validare → motoare → ''RESULT:'' → server salveaza → Socket.IO emite catre browser. | ||
| + | |||
| + | **Validare in trei pasi:** | ||
| + | |||
| + | - //Simulare firmware// (''xplained_mini_sim''): CMD:START → SIM:BEAM:ON → SIM:BARCODE: → SIM:HEIGHT: → SIM:DIAM: → RESULT:ACCEPTED testata inainte de hardware. | ||
| + | - //Mock connection server//: ''MockConnection'' injecteaza fluxuri predefinite, a permis testarea WebSocket si a persistentei SQLite independent de placa. | ||
| + | - //Firmware diagnostic// (''xplained_mini_diag''): fiecare senzor verificat individual prin ''/diag'', fara masina de stari. | ||
| + | </note> | ||
| + | |||
| + | ==== Demo ==== | ||
| + | |||
| + | <note tip> | ||
| + | **[[https://youtu.be/1xtFSNZKUFE?is=iKtrRqGKyOqfioa-|Video demonstratie SmartRVM]]** — pornire sistem, conectare seriala, pagina Simulation cu stubs, pagina Sensor Diag cu citire live senzori si control motoare. | ||
| + | </note> | ||
| + | |||
| + | ==== Calibrare senzori ==== | ||
| + | |||
| + | <note tip> | ||
| + | **HC-SR04:** formula ''distanta_mm = durata_us / 58 * 10''. Testat la distante cunoscute (50, 100, 200mm) — eroare ±3mm la 100mm, conform specificatiei. Offsetul de montaj a fost masurat empiric si adaugat ca ''constexpr'' in ''main.cpp''. ''pulseIn'' are timeout de 30ms — fara el, o citire invalida ar bloca loop-ul pana la 1 secunda. | ||
| + | |||
| + | **IR slot:** activ LOW (LOW = sticla prezenta). Debounce 20ms in ''RvmController'' pentru a ignora tranzitiile false la introducerea sticlei. | ||
| + | |||
| + | **E2100:** 9600 baud, EAN-13 terminat CR+LF. ''Gm65Scanner'' elimina CR+LF si returneaza sirul pur. Timp de raspuns ~100ms de la detectia sticlei. | ||
| + | </note> | ||
| + | |||
| + | ==== Optimizari ==== | ||
| + | |||
| + | <note tip> | ||
| + | **Fara alocare dinamica.** ''FixedString<N>'' in loc de ''String'', buffere si cozi statice. La build, avr-gcc raporteaza ~980 bytes SRAM din 2048 — cu ''String'' am fi ajuns la overflow dupa ore de rulare. | ||
| + | |||
| + | **Non-blocking loop.** Niciun ''delay()'' in logica aplicatiei. Toate timeout-urile folosesc ''Timer::elapsed()'' cu ''millis()''. Loop la ~0.3ms/iteratie indiferent de starea masinii. | ||
| + | |||
| + | **Alimentare separata pentru motoare.** La pornire, un motor poate trage > 1A. Prin USB, ATmega are 500mA — varful de curent ii scade tensiunea si il reseteaza (brownout). Dupa separarea pe sina dedicata 5V 2A, problema a disparut. | ||
| + | |||
| + | **Tip-safe protocol intre server si client.** ''shared/serial-protocol.ts'' defineste toate tipurile de mesaje. Daca serverul emite un camp cu alt nume decat ce asteapta clientul, TypeScript raporteaza eroare la compilare, nu la runtime. | ||
| + | |||
| + | **WebSocket in loc de polling.** Serverul emite evenimentele imediat la primirea de la ATmega. Latenta medie: 3-8ms pe localhost, fata de 0-1s cu polling REST. | ||
| + | </note> | ||
| + | |||
| ===== Concluzii ===== | ===== Concluzii ===== | ||
| Line 300: | Line 422: | ||
| * Cursul 1 (UART): comunicatie seriala ATmega-PC prin UART0 si SoftwareSerial pentru scanner (PD2/PD3) | * Cursul 1 (UART): comunicatie seriala ATmega-PC prin UART0 si SoftwareSerial pentru scanner (PD2/PD3) | ||
| * Cursul 4 (Timere, PWM): Timer0 pentru timeout-urile non-blocking din RvmController | * Cursul 4 (Timere, PWM): Timer0 pentru timeout-urile non-blocking din RvmController | ||
| - | * Cursul 5 (ADC): pinii PC0-PC3 analogici folositi ca GPIO digital pentru HC-SR04 | + | * Cursul 5 (GPIO): pinii PB1/PB2 GPIO digital pentru HC-SR04 #2; PC1/PC2 GPIO pentru motoare |
| * Cursul 7 (I2C): bus I2C hardware TWI pe PC4/PC5 pentru LCD-ul PCF8574 | * Cursul 7 (I2C): bus I2C hardware TWI pe PC4/PC5 pentru LCD-ul PCF8574 | ||
| * Cursul 2 (Debugging, UART): debug prin Serial.println in faza de simulare | * Cursul 2 (Debugging, UART): debug prin Serial.println in faza de simulare | ||