This shows you the differences between two versions of the page.
|
pm:prj2026:vlad.radulescu2901:paul.prodan [2026/05/10 16:47] paul.prodan |
pm:prj2026:vlad.radulescu2901:paul.prodan [2026/05/25 11:34] (current) paul.prodan |
||
|---|---|---|---|
| Line 4: | Line 4: | ||
| <note tip> | <note tip> | ||
| - | SmartRVM este un simulator miniaturizat de reverse vending machine (masina de colectat sticle PET), construit in jurul unui microcontroller ATmega328P Xplained Mini conectat la o platforma web care ruleaza pe PC. | + | SmartRVM este un simulator miniaturizat de reverse vending machine (masina de colectat sticle PET), construit in jurul unui microcontroller **ATmega328P Xplained Mini** conectat la o platforma web care ruleaza pe PC. |
| * **Ce face:** utilizatorul introduce o sticla PET, masina o scaneaza, masoara dimensiunile si decide acceptarea sau respingerea ei pe baza unei baze de date configurabile. | * **Ce face:** utilizatorul introduce o sticla PET, masina o scaneaza, masoara dimensiunile si decide acceptarea sau respingerea ei pe baza unei baze de date configurabile. | ||
| - | * **Scopul:** demonstrarea integrarii mai multor periferice hardware (UART, senzori ultrasonici, servomotor, motoare DC) si aplicarea principiilor DDD (Domain-Driven Design) atat pe firmware cat si pe platforma web. | + | * **Scopul:** demonstrarea integrarii mai multor periferice hardware (UART, SoftwareSerial, senzori ultrasonici HC-SR04, motoare DC cu L9110S H-bridge, display I2C) si aplicarea principiilor DDD (Domain-Driven Design) atat pe firmware cat si pe platforma web. |
| * **Ideea de pornire:** aparatele de colectare a ambalajelor din supermarketuri. | * **Ideea de pornire:** aparatele de colectare a ambalajelor din supermarketuri. | ||
| - | * **De ce e util:** proiectul include un framework de simulare complet — firmware-ul poate rula cu toti senzorii inlocuiti de stubs software controlabile din interfata web, permitand testarea logicii fara niciun circuit conectat. | + | * **Elementul distinctiv:** frameworkul de simulare complet — firmware-ul poate rula cu toti senzorii inlocuiti de stubs software controlabile din interfata web, permitand testarea logicii fara niciun circuit conectat. |
| </note> | </note> | ||
| - | ===== Descriere generală ===== | + | ===== Descriere generala ===== |
| <note tip> | <note tip> | ||
| - | Schema bloc a proiectului: | + | **Flux de functionare:** |
| + | |||
| + | - Operatorul porneste tranzactia din platforma web (CMD:START) | ||
| + | - ATmega detecteaza sticla prin senzorul fotoelectric (IR slot) pe PD4 | ||
| + | - 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'' | ||
| + | - 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 respinsa: motoarele pornesc in sens invers si returneaza sticla; LCD afiseaza "REJECTED" | ||
| + | - PC-ul primeste ''RESULT:ACCEPTED'' / ''RESULT:REJECTED'' si actualizeaza dashboard-ul | ||
| + | </note> | ||
| + | |||
| + | ==== Schema bloc — Arhitectura sistemului ==== | ||
| + | |||
| + | <note tip> | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_bloc.jpeg?700|Schema bloc SmartRVM}} | ||
| <code> | <code> | ||
| - | +-------------------+ USB Serial (ASCII, 9600 baud) +----------------------+ | + | flowchart TB |
| - | | ATmega328P | <-------------------------------------> | Platforma Web (PC) | | + | User([Utilizator]) -->|introduce sticla PET 0.5L| irSensor |
| - | | Xplained Mini | | | | + | |
| - | | | | Node.js / Express 5 | | + | irSensor["Senzor IR slot #1 - PD4"] |
| - | | RvmController | | SQLite + Drizzle | | + | e2100["E2100 Barcode Scanner - PD2/PD3 SoftwareSerial"] |
| - | | (masina stari) | | React 19 + Vite | | + | hcsr1["HC-SR04 #1 diametru - PD7 TRIG / PB0 ECHO"] |
| - | | | | Socket.IO | | + | hcsr2["HC-SR04 #2 inaltime - PC0 TRIG / PC3 ECHO"] |
| - | +-------------------+ +----------------------+ | + | |
| - | | | + | irSensor --> ATmega |
| - | | GPIO / UART / PWM | + | e2100 --> ATmega |
| - | | | + | hcsr1 --> ATmega |
| - | +-------+-----------------------------------------------+ | + | hcsr2 --> ATmega |
| - | | SENZORI & ACTUATORI | | + | |
| - | | E2100 Barcode Scanner (SoftwareSerial) | | + | subgraph ATmega["ATmega328P Xplained Mini"] |
| - | | HC-SR04 x2 (diametru + inaltime) | | + | rvm["RvmController - masina de stari"] |
| - | | Senzori fotoelectrici slot IR x2 (detectie sticla) | | + | lcd["LCD I2C 16x2 - PC4 SDA / PC5 SCL"] |
| - | | Servomotor MG995 (poarta accept/reject) | | + | rvm --- lcd |
| - | | Motor DC cu reductor (conveyor belt) | | + | end |
| - | | Motor DC mic (crusher) | | + | |
| - | +-------------------------------------------------------+ | + | ATmega -->|"L9110S canal A: PC1/PC2"| motorA["Motor DC #1 - conveyor perete stang"] |
| + | ATmega -->|"L9110S canal B: PD5/PD6"| motorB["Motor DC #2 - conveyor perete drept"] | ||
| + | ATmega <-->|"UART0 PD0/PD1 - ASCII 9600 baud"| web | ||
| + | |||
| + | subgraph web["Platforma Web PC"] | ||
| + | nodejs["Node.js + Express 5"] | ||
| + | sqlite["SQLite + Drizzle ORM"] | ||
| + | react["React 19 + Socket.IO"] | ||
| + | nodejs --- sqlite | ||
| + | sqlite --- react | ||
| + | end | ||
| </code> | </code> | ||
| + | </note> | ||
| - | **Flux de functionare:** | + | ==== Masina de stari (RvmController) ==== |
| - | - Operatorul porneste tranzactia din platforma web (CMD:START) | + | |
| - | - ATmega detecteaza sticla prin senzorul fotoelectric | + | <note tip> |
| - | - Scannerul E2100 citeste barcode-ul, ATmega il trimite catre PC | + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_state.jpeg?600|Masina de stari SmartRVM}} |
| - | - PC-ul cauta dimensiunile in baza de date si le trimite inapoi (DIMS:) sau DB:NOT_FOUND | + | |
| - | - HC-SR04 masoara inaltime si diametru, firmware-ul valideaza dimensiunile | + | <code> |
| - | - Daca acceptata: servomotorul deschide poarta, banda transportoare muta sticla, crusher-ul o simuleaza strivita | + | stateDiagram-v2 |
| - | - Daca respinsa: poarta ramane inchisa, sticla este returnata | + | [*] --> IDLE |
| - | - PC-ul primeste RESULT:ACCEPTED / RESULT:REJECTED si actualizeaza dashboard-ul | + | IDLE --> WAITING : CMD:START de la PC |
| + | WAITING --> SCANNING : IR detecteaza sticla | ||
| + | SCANNING --> MEASURING : BARCODE: primit + DIMS: de la PC | ||
| + | SCANNING --> IDLE : DB:NOT_FOUND sau timeout scanare | ||
| + | MEASURING --> TRANSPORTING : dimensiuni in toleranta | ||
| + | MEASURING --> RETURNING : dimensiuni invalide | ||
| + | TRANSPORTING --> IDLE : motoare STOP - RESULT:ACCEPTED trimis | ||
| + | RETURNING --> IDLE : motoare STOP - RESULT:REJECTED trimis | ||
| + | TRANSPORTING --> IDLE : timeout JAM - ERROR:JAM trimis | ||
| + | IDLE --> IDLE : CMD:STOP / CMD:RESET | ||
| + | </code> | ||
| </note> | </note> | ||
| ===== Hardware Design ===== | ===== Hardware Design ===== | ||
| - | <note tip> | + | ==== Lista de componente ==== |
| - | **Lista de componente:** | + | |
| + | <note tip> | ||
| ^ Componenta ^ Rol ^ Pret ^ | ^ Componenta ^ Rol ^ Pret ^ | ||
| | ATmega328P Xplained Mini | Microcontroller principal (AVR 8-bit, 16 MHz, 2KB RAM, 32KB Flash) | existent in laborator | | | ATmega328P Xplained Mini | Microcontroller principal (AVR 8-bit, 16 MHz, 2KB RAM, 32KB Flash) | existent in laborator | | ||
| | E2100 Barcode Scanner | Citire coduri de bare 1D/2D prin UART TTL (SoftwareSerial 9600 baud) | 59.90 RON | | | E2100 Barcode Scanner | Citire coduri de bare 1D/2D prin UART TTL (SoftwareSerial 9600 baud) | 59.90 RON | | ||
| - | | HC-SR04 ultrasonic (x2) | Masurare inaltime si diametru sticla (2-450 cm, 0.3 cm precizie) | 11.30 RON | | + | | Adaptor FPC 12 pini (x2) | Conectare cablu FPC al modulului E2100 la pini standard 2.54mm | 7.37 RON | |
| - | | Senzor fotoelectric slot IR (x2) | Detectie prezenta sticla la intrare (break-beam, iesire digitala) | 5.80 RON | | + | | HC-SR04 senzor ultrasonic (x2) | Masurare inaltime si diametru sticla (pulseIn, 2-450 cm, 0.3 cm precizie) | 11.30 RON | |
| - | | Servomotor MG995 | Actionare poarta accept/reject (PWM 50 Hz, 0-90 grade) | 26.14 RON | | + | | Senzor fotoelectric slot IR (x2) | Detectie prezenta sticla la intrare (iesire digitala, LOW = sticla) | 5.80 RON | |
| - | | Motor DC cu reductor 1:48 | Banda transportoare (conveyor) | 7.26 RON | | + | | Motor DC 3V-6V cu reductor 1:48 (x2) | Doua motoare pe peretii opusi ai cutiei pentru antrenarea conveyor belt-ului | 14.52 RON | |
| - | | Motor DC mic | Simulare crusher (strivire sticla) | 1.74 RON | | + | | Modul L9110S H-Bridge dual | Driver pentru ambele motoare DC (canal A motor #1, canal B motor #2) | 8.17 RON | |
| - | | Modul L9110S H-Bridge | Driver pentru motoarele DC | 8.17 RON | | + | | Kit Breadboard 830p + 65 jumpers + sursa | Prototipare + modul sursa de alimentare 5V cu intrare barrel jack | 42.94 RON | |
| - | | Modul IRF520 MOSFET | Control PWM motor crusher | 4.14 RON | | + | | 40x fire Dupont mama-tata 20cm | Interconectare placa cu module | 16.17 RON | |
| - | | Kit Breadboard 830p + sursa | Prototipare + alimentare 5V | 42.94 RON | | + | | Rezistori 220 ohm (x10) | Current limiting pentru IR si semnale de control | 1.20 RON | |
| - | | Fire Dupont, rezistori, condensatori, diode | Interconectare si filtrare | ~27 RON | | + | | Rezistori 10k ohm (x10) | Pull-up / pull-down pe intrari digitale | 1.20 RON | |
| - | | **Total** | | **~201 RON + livrare** | | + | | Condensatori ceramici 100nF (x10) | Decuplare alimentare langa module | 2.42 RON | |
| + | | Condensatori electrolitici 100uF 25V (x10) | Filtrare bulk pe linia de alimentare a motoarelor | 2.72 RON | | ||
| + | | Diode 1N4148 (x4) | Protectie flyback pe bobinele motoarelor | 2.18 RON | | ||
| + | | LCD I2C 16x2 (driver PCF8574, backlight albastru) | Display local pentru starea masinii si rezultatul tranzactiei | 14.90 RON | | ||
| + | | **Total comanda online** | | **~158 RON + livrare** | | ||
| + | </note> | ||
| - | **Mapare pini ATmega328P Xplained Mini:** | + | ==== Mapare pini (ATmega328P Xplained Mini) ==== |
| + | |||
| + | <note tip> | ||
| + | Placa ATmega328P Xplained Mini are debugger/programator onboard (mEDBG) hardwired pe UART0 (PD0/PD1). Pinii PD5/PD6 (eliberati din configuratia anterioara) sunt folositi pentru motorul de conveyor #2. PC4/PC5 sunt dedicati I2C hardware. | ||
| <code> | <code> | ||
| - | Pin Functie Modul conectat | + | Pin Functie Modul conectat |
| ------------------------------------------ | ------------------------------------------ | ||
| - | PD0 UART0 RX mEDBG USB (serial la PC) | + | PD0 UART0 RX mEDBG USB (serial la PC) |
| - | PD1 UART0 TX mEDBG USB (serial la PC) | + | PD1 UART0 TX mEDBG USB (serial la PC) |
| - | PD2 SoftwareSerial RX E2100 TX | + | PD2 SoftwareSerial RX E2100 TX |
| - | PD3 SoftwareSerial TX E2100 RX | + | PD3 SoftwareSerial TX E2100 RX |
| - | PD4 GPIO input Senzor fotoelectric slot #1 | + | PD4 GPIO input Senzor fotoelectric slot #1 (LOW = sticla detectata) |
| - | PD5 PWM (Timer0) MG995 Servo | + | PD5 GPIO output L9110S B-IA (motor conveyor #2 directie A) |
| - | PD6 PWM (Timer0) IRF520 MOSFET (crusher) | + | PD6 GPIO output L9110S B-IB (motor conveyor #2 directie B) |
| - | 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 IN1 (conveyor) | + | PC1 GPIO output L9110S A-IA (motor conveyor #1 directie A) |
| - | PC2 GPIO output L9110S IN2 (conveyor) | + | 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) | ||
| + | PC5 I2C SCL LCD I2C 16x2 (display stare masina) | ||
| </code> | </code> | ||
| + | </note> | ||
| - | **Schema de alimentare:** | + | ==== Justificarea alegerii pinilor ==== |
| - | ATmega328P Xplained Mini este alimentat prin USB de la PC (5V). Motoarele, servo si senzorii activi sunt alimentati separat de pe o sina 5V a modulului de breadboard (incarcator 5V 2A), cu GND comun cu ATmega. Separarea previne varfurile de curent ale motoarelor sa destabilizeze microcontrollerul. | + | <note tip> |
| + | ^ Pin ^ Tip ^ De ce acest pin ^ | ||
| + | | **PD0 / PD1** | UART0 RX/TX | Singurul UART hardware al ATmega328P este hardwired la mEDBG. Nu poate fi reasignat. | | ||
| + | | **PD2 / PD3** | SoftwareSerial | INT0/INT1 — singurele pini cu intreruperi externe bine suportate, necesare pentru receptie SoftwareSerial fiabila la 9600 baud. | | ||
| + | | **PD4** | GPIO input | Semnal digital simplu de la senzorul IR (nu necesita PWM, ADC sau intreruperi). | | ||
| + | | **PD5 / PD6** | GPIO output (motor #2) | Eliberati din configuratia anterioara. Raman in Port D, consistent cu restul actuatorilor. | | ||
| + | | **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. | | ||
| + | | **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. | | ||
| + | | **PC4 / PC5** | I2C SDA/SCL | **Singura optiune posibila**: TWI (I2C hardware) al ATmega328P este implementat fix pe acesti doi pini. Nu exista alternativa hardware. | | ||
| </note> | </note> | ||
| + | |||
| + | ==== Schema electrica ==== | ||
| + | |||
| + | <note tip> | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_schema.jpeg?750|Schema electrica SmartRVM - Wokwi}} | ||
| + | |||
| + | |||
| + | **Tabel conexiuni:** | ||
| + | |||
| + | ^ Componenta ^ Pin componenta ^ Pin ATmega ^ Note ^ | ||
| + | | E2100 Scanner | TX | PD2 | SoftwareSerial 9600 baud | | ||
| + | | E2100 Scanner | RX | PD3 | | | ||
| + | | IR Slot Sensor #1 | OUT | PD4 | LOW = sticla prezenta | | ||
| + | | HC-SR04 #1 (diametru) | TRIG | PD7 | Puls 10µs HIGH | | ||
| + | | HC-SR04 #1 (diametru) | ECHO | PB0 | pulseIn(HIGH), 58µs/cm | | ||
| + | | HC-SR04 #2 (inaltime) | TRIG | PC0 | Puls 10µs HIGH | | ||
| + | | HC-SR04 #2 (inaltime) | ECHO | PC3 | pulseIn(HIGH) | | ||
| + | | L9110S H-Bridge | A-IA | PC1 | Motor #1 directie A | | ||
| + | | L9110S H-Bridge | A-IB | PC2 | Motor #1 directie B | | ||
| + | | L9110S H-Bridge | B-IA | PD5 | Motor #2 directie A | | ||
| + | | L9110S H-Bridge | B-IB | PD6 | Motor #2 directie B | | ||
| + | | LCD I2C 16x2 | SDA | PC4 | TWI hardware, adresa 0x27 | | ||
| + | | LCD I2C 16x2 | SCL | PC5 | | | ||
| + | |||
| + | > **Nota alimentare:** Motoarele si LCD-ul sunt alimentate de pe sina 5V a breadboard-ului (incarcator 5V 2A), nu de pe ATmega (limitat la 500mA USB). GND comun intre surse. | ||
| + | </note> | ||
| + | |||
| + | ===== Dovezi de Functionare ===== | ||
| + | |||
| + | ==== Componente conectate ==== | ||
| + | |||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_1.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_2.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_3.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_4.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_5.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_6.jpeg?700|Circuit SmartRVM pe breadboard}} | ||
| + | {{:pm:prj2026:vlad.radulescu2901:prodan_paul_7.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}} | ||
| ===== Software Design ===== | ===== Software Design ===== | ||
| Line 105: | Line 202: | ||
| **Arhitectura firmware (DDD pe ATmega):** | **Arhitectura firmware (DDD pe ATmega):** | ||
| - | Codul este structurat in patru straturi: | + | * ''common/'' — ''FixedString'' (string pe stack, fara alocare dinamica), ''RingBuffer'', ''Timer'' |
| - | + | * ''domain/'' — interfete pure C++: ''ICommChannel'', ''IScanner'', ''IBottleDetector'', ''IHeightSensor'', ''IDiameterSensor'', ''ITransport'', ''IDisplay'' | |
| - | * ''common/'' — utilitare reutilizabile fara dependinte hardware: ''FixedString'' (string pe stack, fara alocare dinamica), ''RingBuffer'', ''Timer'' (non-blocking, bazat pe ''millis()'') | + | * ''application/'' — ''RvmController'' (masina de stari IDLE→WAITING→SCANNING→MEASURING→TRANSPORTING/RETURNING→IDLE), ''BottleValidator'' |
| - | * ''domain/'' — interfete pure C++ si value types, zero dependinte Arduino. Contine: ''ICommChannel'', ''IScanner'', ''IBottleDetector'', ''IHeightSensor'', ''IDiameterSensor'', ''ITransport'', ''IServoGate'', ''ICrusher'', enum-uri si structuri de date | + | * ''infrastructure/'' — ''UartProtocol'', ''Gm65Scanner'' (E2100), ''IrBreakBeam'', ''DcConveyor'' (L9110S dual motor), ''LcdI2cDisplay'' (PCF8574) |
| - | * ''application/'' — ''RvmController'': masina de stari principala (IDLE→WAITING→SCANNING→MEASURING→TRANSPORTING/RETURNING→CRUSHING→IDLE), complet non-blocking. ''BottleValidator'': functie pura de validare dimensiuni | + | * ''stubs/'' — ''StubScanner'', ''StubHeightSensor'', ''StubDiameterSensor'', ''StubBottleDetector'', ''StubTransport'', ''StubDisplay'', ''SimBridge'' |
| - | * ''infrastructure/'' — drivere reale: ''UartProtocol'', ''Gm65Scanner'' (E2100), ''IrBreakBeam'', ''ServoGate'', ''DcCrusher'', drivere HC-SR04 | + | |
| - | * ''stubs/'' — implementari false controlabile prin comenzi ''SIM:'' de pe PC, pentru simulare fara hardware | + | |
| **Decizii cheie firmware:** | **Decizii cheie firmware:** | ||
| * Niciun ''delay()'' in logica aplicatiei — toate operatiile sunt non-blocking cu ''tick()'' | * Niciun ''delay()'' in logica aplicatiei — toate operatiile sunt non-blocking cu ''tick()'' | ||
| - | * Fara alocare dinamica (nu exista ''new'', ''String'', ''std::vector'') — pe 2KB RAM fragmentarea heap-ului e fatala | + | * Fara alocare dinamica (nu exista ''new'', ''String'', ''std::vector'') — pe 2KB RAM, fragmentarea heap-ului e fatala |
| * Erori returnate prin enum-uri, nu exceptii (compilat cu ''-fno-exceptions'') | * Erori returnate prin enum-uri, nu exceptii (compilat cu ''-fno-exceptions'') | ||
| + | * ''DcConveyor'' controleaza simultan ambele motoare: inainte (ACCEPT), inapoi (RETURN), stop | ||
| **Platforma web (Node.js + React):** | **Platforma web (Node.js + React):** | ||
| - | Monorepo pnpm cu trei pachete: | ||
| * ''shared'' — tipuri TypeScript comune (protocol serial, DTO-uri REST) | * ''shared'' — tipuri TypeScript comune (protocol serial, DTO-uri REST) | ||
| * ''server'' — Node.js 22, Express 5, SQLite + Drizzle ORM, serialport, Socket.IO 4, Zod | * ''server'' — Node.js 22, Express 5, SQLite + Drizzle ORM, serialport, Socket.IO 4, Zod | ||
| * ''client'' — React 19, Vite, Tailwind CSS v4, shadcn/ui, Recharts | * ''client'' — React 19, Vite, Tailwind CSS v4, shadcn/ui, Recharts | ||
| - | Pagini: **Dashboard** (status live, control START/STOP), **Barcodes** (CRUD), **Transactions** (istoric + filtrare), **Statistics** (grafice Recharts), **Simulation** (control stubs in timp real) | + | Pagini: **Dashboard** (status live, START/STOP), **Barcodes** (CRUD), **Transactions** (istoric), **Statistics** (grafice), **Simulation** (control stubs) |
| **Protocol serial ASCII (ATmega ↔ PC):** | **Protocol serial ASCII (ATmega ↔ PC):** | ||
| <code> | <code> | ||
| - | PC → ATmega: | + | PC → ATmega: CMD:START / CMD:STOP / CMD:RESET |
| - | CMD:START / CMD:STOP / CMD:RESET | + | DIMS:220:65:10 (inaltime:diametru:toleranta in mm) |
| - | DIMS:220:65:10 (inaltime_mm:diametru_mm:toleranta_mm) | + | DB:NOT_FOUND |
| - | DB:NOT_FOUND | + | |
| - | ATmega → PC: | + | ATmega → PC: STATUS:IDLE / WAITING / SCANNING / MEASURING / TRANSPORTING / RETURNING |
| - | STATUS:IDLE / WAITING / SCANNING / MEASURING / TRANSPORTING / CRUSHING / RETURNING | + | BARCODE:5941234567890 |
| - | BARCODE:5941234567890 | + | MEASURED:H=218:D=63 |
| - | MEASURED:H=218:D=63 | + | RESULT:ACCEPTED / RESULT:REJECTED:oversized |
| - | RESULT:ACCEPTED | + | ERROR:JAM / ERROR:SCANNER_FAIL |
| - | RESULT:REJECTED:oversized | + | |
| - | ERROR:JAM / ERROR:SCANNER_FAIL | + | |
| - | Protocol simulare (build xplained_mini_sim): | + | Simulare: SIM:BEAM:ON/OFF SIM:BARCODE:<val> SIM:HEIGHT:<mm> |
| - | SIM:BEAM:ON/OFF SIM:BARCODE:<val> SIM:HEIGHT:<mm> | + | SIM:DIAM:<mm> SIM:JAM SIM:RESET_STUBS |
| - | SIM:DIAM:<mm> SIM:JAM SIM:RESET_STUBS | + | ATmega: SIM:ACK:<msg> / SIM:ERR:<motiv> |
| - | → ATmega raspunde cu SIM:ACK:<mesaj> sau SIM:ERR:<motiv> | + | |
| </code> | </code> | ||
| </note> | </note> | ||
| - | ===== Rezultate Obţinute ===== | + | ===== Rezultate Obtinute ===== |
| <note tip> | <note tip> | ||
| * Firmware-ul compileaza fara warninguri in ambele configuratii (productie si simulare) | * Firmware-ul compileaza fara warninguri in ambele configuratii (productie si simulare) | ||
| - | * Build-ul de simulare a fost testat pe ATmega328P Xplained Mini: comunicatia seriala, masina de stari si SimBridge functioneaza corect | + | * Build-ul de simulare testat pe ATmega328P Xplained Mini: comunicatia seriala, masina de stari si SimBridge functioneaza corect |
| - | * Platforma web este functionala cu toate cele cinci pagini: dashboard live, simulare, CRUD barcodes, tranzactii, statistici | + | * Platforma web functionala cu toate cele cinci pagini |
| - | * S-a implementat un script custom Python pentru a rezolva o limitare a PlatformIO cu protocolul mEDBG (interfata USB HID in loc de port serial clasic) | + | * Script custom Python (''set_upload_port.py'') rezolva limitarea PlatformIO cu protocolul mEDBG |
| - | * Componentele hardware au fost comandate; dupa sosire urmeaza constructia fizica si calibrarea constantelor (distante senzori, durata transport) | + | * Componentele hardware au sosit; urmeaza conectarea fizica si calibrarea |
| </note> | </note> | ||
| - | ===== Concluzii ===== | + | ===== Milestone 3 — Implementare Software ===== |
| - | Separarea clara intre domain si infrastructure s-a dovedit o necesitate practica, nu un lux: fara ea nu ar fi fost posibila testarea logicii masinii de stari inainte de sosirea hardware-ului. Frameworkul de simulare, implementat in cateva zile, va economisi saptamani de debugging ulterior. | + | ==== 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 ===== | ||
| - | Constrangerea de memorie (2KB RAM) a impus decizii concrete de design: ''FixedString'' in loc de ''String'', alocare exclusiv statica, fara exceptii. Pe platforma web, SQLite + Drizzle a oferit zero configurare si schema TypeScript-first, portabila complet. | + | Separarea clara intre domain si infrastructure a permis testarea logicii masinii de stari inainte de sosirea hardware-ului. ''DcConveyor'' controleaza ambele motoare printr-o singura interfata ''ITransport'', mentinand logica aplicatiei independenta de hardware. Frameworkul de simulare (stubs + SimBridge + pagina web Simulation) a validat integral fluxul de tranzactie. |
| ===== Download ===== | ===== Download ===== | ||
| <note warning> | <note warning> | ||
| - | Structura proiectului: | ||
| <code> | <code> | ||
| SmartRVM/ | SmartRVM/ | ||
| device/ -- firmware ATmega (PlatformIO) | device/ -- firmware ATmega (PlatformIO) | ||
| platform/ -- platforma web (pnpm monorepo) | platform/ -- platforma web (pnpm monorepo) | ||
| - | DOCUMENTATION.md | + | wokwi/ -- schema electrica Wokwi (diagram.json) |
| - | SHOPPING_LIST.md | + | DOCUMENTATION.md -- documentatie Markdown (diagrame Mermaid) |
| + | DOKUWIKI.txt -- versiune DokuWiki pentru OCW | ||
| </code> | </code> | ||
| - | Compilare si upload firmware: | ||
| - | <code bash> | ||
| - | cd device | ||
| - | pio run -e xplained_mini # build productie | ||
| - | pio run -e xplained_mini_sim -t upload # upload simulare | ||
| - | </code> | ||
| - | |||
| - | Pornire platforma web: | ||
| <code bash> | <code bash> | ||
| + | cd device && pio run -e xplained_mini_sim -t upload | ||
| cd platform && pnpm install | cd platform && pnpm install | ||
| - | pnpm --filter server dev # port 3000 | + | pnpm --filter server dev && pnpm --filter client dev |
| - | pnpm --filter client dev # port 5173 | + | |
| </code> | </code> | ||
| </note> | </note> | ||
| - | ===== Bibliografie/Resurse ===== | + | ===== Bibliografie / Resurse ===== |
| <note> | <note> | ||
| Line 200: | Line 404: | ||
| * [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42287-ATMEGA328P-Xplained-Mini_UserGuide.pdf|ATmega328P Xplained Mini User Guide]] | * [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42287-ATMEGA328P-Xplained-Mini_UserGuide.pdf|ATmega328P Xplained Mini User Guide]] | ||
| * [[https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf|HC-SR04 Datasheet]] | * [[https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf|HC-SR04 Datasheet]] | ||
| - | * [[http://www.electronicoscaldas.com/datasheet/MG995_Tower-Pro.pdf|MG995 Servo Datasheet]] | + | * [[https://ardushop.ro/ro/electronica/752-motor-dc-3v-6v-cu-reductor-1-48-6427854009609.html|Motor DC 3V-6V cu reductor 1:48 (ArduShop)]] |
| + | * [[https://www.nxp.com/docs/en/data-sheet/PCF8574_PCF8574A.pdf|PCF8574 I2C Expander Datasheet (LCD driver)]] | ||
| * [[https://www.elecrow.com/download/datasheet-l9110.pdf|L9110S H-Bridge Datasheet]] | * [[https://www.elecrow.com/download/datasheet-l9110.pdf|L9110S H-Bridge Datasheet]] | ||
| Line 206: | Line 411: | ||
| * [[https://docs.platformio.org|PlatformIO Documentation]] | * [[https://docs.platformio.org|PlatformIO Documentation]] | ||
| * [[https://avrdudes.github.io/avrdude/avrdude_4.html|avrdude xplainedmini protocol]] | * [[https://avrdudes.github.io/avrdude/avrdude_4.html|avrdude xplainedmini protocol]] | ||
| + | * [[https://www.arduino.cc/en/Reference/SoftwareSerial|Arduino SoftwareSerial Library]] | ||
| + | * [[https://github.com/johnrickman/LiquidCrystal_I2C|LiquidCrystal_I2C Library]] | ||
| * [[https://serialport.io/docs/|serialport npm package]] | * [[https://serialport.io/docs/|serialport npm package]] | ||
| * [[https://orm.drizzle.team/docs/overview|Drizzle ORM Documentation]] | * [[https://orm.drizzle.team/docs/overview|Drizzle ORM Documentation]] | ||
| * [[https://socket.io/docs/v4/|Socket.IO Documentation]] | * [[https://socket.io/docs/v4/|Socket.IO Documentation]] | ||
| * [[https://ui.shadcn.com/|shadcn/ui Components]] | * [[https://ui.shadcn.com/|shadcn/ui Components]] | ||
| - | * [[https://recharts.org/en-US/|Recharts Documentation]] | + | * [[https://wokwi.com|Wokwi — simulator Arduino online (schema electrica)]] |
| **Cursuri PM relevante:** | **Cursuri PM relevante:** | ||
| - | * Cursul 1 (UART): comunicatie seriala ATmega-PC si SoftwareSerial pentru scanner | + | * Cursul 1 (UART): comunicatie seriala ATmega-PC prin UART0 si SoftwareSerial pentru scanner (PD2/PD3) |
| - | * Cursul 3 (Timere, PWM): PWM pentru servomotor (50 Hz) si control motor DC | + | * Cursul 4 (Timere, PWM): Timer0 pentru timeout-urile non-blocking din RvmController |
| + | * 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 2 (Debugging, UART): debug prin Serial.println in faza de simulare | * Cursul 2 (Debugging, UART): debug prin Serial.println in faza de simulare | ||
| </note> | </note> | ||
| <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> | ||
| - | |||