This shows you the differences between two versions of the page.
si:iot2025:lab02 [2025/08/07 20:18] robert_ionut.alexa |
si:iot2025:lab02 [2025/08/11 12:53] (current) dan.tudose [DRV2605L - senzor haptic] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Laboratorul 02. I2C - Haptics ===== | + | ===== Laboratorul 02. I2C - Haptics, Accelerometru, Giroscop ===== |
+ | |||
+ | În laboratorul de astăzi veți învăța cum să interactionați cu diferite periferice prin I2C și cum datele de la hardware sunt transmise utilizatorului prin diferite niveluri de redirectare. Vom explora atât noțiuni low-level cât și aspecte mai high-level (arhitectura software a driver-elor in NuttX) construite peste. | ||
+ | |||
+ | Un modul de kernel (sau un device driver) este o bucată specializată de cod care este compilată și adăugată la kernel-ul sistemului de operare. În acest mod, sistemul de operare are posibilitatea de a interacționa cu diferite periferice - în absența driverelor, un kernel nu ar putea accesa lumea exterioară CPU-ului. De exemplu, dacă ne dorim ca sistemul nostru să poată transfera date prin controller-ul de I2C, avem nevoie de un driver pentru I2C care să programeze aceste tranzacții de transfer de date. Analog, dacă ne dorim să interacționăm cu un senzor, avem nevoie de un device driver care știe să programeze acel senzor. | ||
+ | |||
+ | <note tip> | ||
+ | Aproximativ 80% din codul unui sistem de operare este format din codul pentru drivere. | ||
+ | </note> | ||
+ | |||
+ | Din punct de vedere al user-ului, driverele pot să fie expuse în două moduri: | ||
+ | |||
+ | * **char device driver** - în Linux sunt folosite pentru mouse și tastatură, de exemplu, iar în NuttX pentru senzori, printre altele. Pe scurt, dispozitive cu rată mică de transfer de date, care functionează la nivel de caracter (byte). | ||
+ | * **block device driver** - folosite pentru hdd-uri, sdd-uri, device-uri care au nevoie să transfere date la nivel de blocuri (4KB de obicei). | ||
+ | |||
+ | ==== I2C ==== | ||
+ | |||
+ | I2C (Inter-Integrated Circuit) este un protocol de comunicație serială dezvoltat de Philips (acum NXP) în anii ’80, folosit pe scară largă pentru a conecta microcontrolere cu senzori, memorii, afișaje și alte periferice. Este foarte popular în proiecte embedded datorită simplității și numărului redus de pini necesari. | ||
+ | |||
+ | I2C este un protocol care functioneaza sub paradigma master-slave prin care un "master" (de obicei microcontroller-ul, in cazul nostru ESP32S3-ul) citeste sau scrie date de pe un device denumit "slave" (cele mai comune device-uri de acest fel in lumea embedded fiind senzorii). | ||
+ | |||
+ | Astfel, magistrala (bus-ul) este definita din doua linii de comunicatie: | ||
+ | * SDA (Serial Data) - folosita pentru transmisia datelor. | ||
+ | * SCL (Serial Clock) - folosita pentru propagarea ceasului dupa care se face esantionarea datelor. | ||
+ | |||
+ | Transmisia datelor se face in mod bidirectional (master -> slave in cazul operatiei de write si slave -> master in caz de read), insa nu este full-duplex - doar un singur device poate sa detina controlul SDA-ului in orice moment de timp. SCL-ul este intotdeauna generat de master-ul comunicatiei si este propagat catre toate dispozitivele de tip slave. | ||
+ | |||
+ | Fiecare dispozitiv slave este identificat printr-o adresa pe 7 biti la care se adauga un bit pentru R/W. Astfel: | ||
+ | * pentru operatiile de write, master-ul pune pe magistrala si datele de transmis, iar slave-ul este in modul de "listening". | ||
+ | * pentru operatiile de read, dupa transmisia adresei si a bit-ului de R/W, slave-ul preia controlul SDA-ului, iar master-ul intra in modul de "listening" pentru a receptiona datele. | ||
+ | |||
+ | {{ :si:iot2025:i2c-communication-how-it-works.png?500 }} | ||
+ | |||
+ | ==== DRV2605L - driver haptic ==== | ||
+ | |||
+ | DRV2605L este un driver haptic proiectat cu scopul de a controla motoare de vibratie care in final sa poata oferi feedback utilizatorului prin vibratii. Avantajul acestui device este ca, desi poate fi programat sa genereze vibratii constante, vine cu o biblioteca interna de efecte haptice, fara a fi nevoie ca user-ul sa creeze trenul de vibrații manual. | ||
+ | |||
+ | In cadrul NuttX, arhitectura software prin care o aplicatie interactioneaza cu senzorul DRV2605L presupune mai multe niveluri de redirectare: | ||
+ | |||
+ | {{ :si:iot2025:screenshot_2025-08-09_at_21.19.01.png?200 }} | ||
+ | |||
+ | Codul este impartit in doua componente, upper half driver si lower half driver. Deoarece majoritatea codului unui driver poate fi refolosit, a fost introdus upper half driver pentru a oferi un API uniformizat si standardizat pentru toate device-urile. Componenta care este particulara fiecarui device si se ocupa de accesul efectiv la hardware este driver-ul lower half, neaccesibil user-ului in mod direct. Acesta este invocat de catre driver-ul upper half printr-un API intern. | ||
+ | |||
+ | ==== LSM6DSL - accelerometru si giroscop ==== | ||
+ | |||
+ | LSM6DSL este un senzor 3D care combina in acelasi dispozitiv un accelerometru si un giroscop. Desi pe sistemul nostru este conectat prin I2C, acesta poate comunica si prin SPI. | ||
+ | * accelerometrul detecteaza schimbarile de viteza si poate determina inclinarea dispozitivului (desi nu este atat de precis fara folosirea giroscopului). Dispozitivul masoara acceleratia in **m/s²**, insa in NuttX datele obtinute sunt exprimate in mg (mili-g), unde 1g este echivalent cu acceleratia gravitationala (9.81 m/s²). | ||
+ | * giroscopul masoara cat de repede se roteste dispozitivul in jurul propriilor axe folosind **dps** (degrees per second), iar in NuttX datele obtinute de la senzor sunt exprimate in mdps (mili-dps). | ||
+ | |||
+ | Spre deosebire de DRV2605L, arhitectura software este mai simpla in cazul acestui device, sistemul de operare oferind doar un singur nivel de redirectare: | ||
+ | |||
+ | {{ :si:iot2025:screenshot_2025-08-09_at_21.53.41.png?200 }} | ||
+ | |||
+ | Apelurile de sistem sunt interceptate de catre driver-ul dispozitivului prin char device-ul expus in ''/dev/lsm6dsl'', iar mai apoi comenzile de read/write sunt trimise direct device-ului hardware, fara a mai exista o componenta intermediara uniforma pentru toate device-urile. Acest API este imprumutat din Linux si este considerat "obsolete" in NuttX, doar device-urile "legacy" utilizand aceasta abordare. | ||
===== Exerciții ===== | ===== Exerciții ===== | ||
- | Pentru a putea rula exercitiile, este nevoie să compilați NuttX folosind ''hacktorwatch:iot'', la care va trebui sa activati manual cateva config-uri folosindu-va de sistemul de build (''make menuconfig''): | + | Pentru a putea rula exercitiile, este nevoie să compilați NuttX folosind ''hacktorwatch:iot'', la care va trebui sa activati manual cateva config-uri folosindu-va de sistemul de build (''make menuconfig''). Astfel, veti activa atat compilarea codului de driver si initializarea efectiva a hardware-ului, cat veti si incarca pe placa aplicatii de demo pe care le puteti rula. |
- | Pentru a putea folosi device-ul de haptics: | + | Ca sa folositi senzorul de haptics, aveti nevoie de urmatoarele config-uri: |
* CONFIG_FF_DRV2605L | * CONFIG_FF_DRV2605L | ||
* CONFIG_DRV2605L_TS2200_LIBRARY_A | * CONFIG_DRV2605L_TS2200_LIBRARY_A | ||
Line 18: | Line 71: | ||
</note> | </note> | ||
- | Pentru a avea acces la accelerometru si giroscop: | + | Cele doua config-uri de mai jos va vor oferi access la accelerometru si giroscop: |
* CONFIG_SENSORS_LSM6DSL | * CONFIG_SENSORS_LSM6DSL | ||
* CONFIG_EXAMPLES_LSM6DSL_READER | * CONFIG_EXAMPLES_LSM6DSL_READER | ||
<note important> | <note important> | ||
- | La fel ca in cazul device-ului de haptics, atentie la dependintele acestui config. | + | La fel ca in cazul device-ului de haptics, atentie la dependintele acestor config-uri. |
+ | </note> | ||
+ | |||
+ | **1.** Pentru a va acomoda cu API-ul pe care NuttX il ofera pentru a interactiona cu cele doua device-uri, in cadrul acestui exercitiu va trebui sa inspectati codul si sa rulati aplicatiile de demo disponibile in repository-ul ''nuttx-apps''. | ||
+ | - ''nuttx-apps/examples/drv2605l/'' initializeaza device-ul cu anumite efecte de vibrare (''upload_rom_effect'', ''upload_constant_effect''). Apelarea acestora se face ulterior, "on demand", prin ''play_effect''. | ||
+ | - ''nuttx-apps/examples/lsm6dsl_reader'' afiseaza la consola o data la doua secunde datele obtinute de la accelerometru si giroscop. Observati modul de interactiune cu senzorul: acesta este expus printr-o intrare in ''/dev/'' care va trebui folosita in cadrul apelului de sistem ''open'', iar mai apoi folosim apeluri de ''ioctl'' pentru a interactiona cu hardware-ul. | ||
+ | - Cautati definitiile pentru structurile de date folosite in ambele aplicatii. | ||
+ | |||
+ | <note important> | ||
+ | Toate fișierele de tip header le puteți găsi în ''nuttx/include/nuttx/''. Puteți căuta recursiv din linia de comandă folosind ''grep -r <string>''. | ||
+ | </note> | ||
+ | |||
+ | **2.** In cadrul acestui exercitiu, vrem ca ceasul sa ne ofere informatii (prin vibrare) atunci cand viram stanga, respectiv dreapta. | ||
+ | - Folosindu-ne de ''lsm6dsl_reader'' vom citi datele oferite de accelerometru si vom determina directia de mers. | ||
+ | - Daca ceasul este nemiscat sau merge inainte nu va oferi niciun fel de feedback utilizatorului. | ||
+ | - ''drv2605l'' are o biblioteca interna de efecte de vibrare pe care o puteti consulta [[https://www.ti.com/lit/ds/symlink/drv2605l.pdf|aici]], la pagina 63. Alegeti doua efecte din acest tabel si incarcati-le pe ceas. | ||
+ | - In functie de directia de mers, vom rula in mod constant unul dintre cele doua efecte pana cand ceasul va reveni in stare initiala (ceasul este nemiscat sau sau se misca doar inainte). | ||
+ | |||
+ | <note tip> | ||
+ | **Hint:** pentru a opri un efect, trebuie sa scrieti o functie care realizeaza inversul lui ''play_effect''. Parametrul care ne intereseaza si trebuie modificat este ''play.value'' (trebuie sa fie setat pe 0 - disabled). | ||
+ | </note> | ||
+ | |||
+ | <note tip> | ||
+ | **Hint:** pentru a putea face polling mai des pe senzor si sa obtineti date mai accurate este nevoie sa folositi ''usleep''. | ||
</note> | </note> | ||
- | **1.** Inspectati codul si rulati exemplele default oferite de repository-ul nuttx-apps: | + | **3. (Bonus)** La exercitiul anterior, intensitatea de vibrare era absoluta (on/off). Ne dorim sa avem un mecanism mai complex prin care sa folosim vibrare graduala in functie de nivelul acceleratiei - cu cat acceleratia este mai mare, cu atat vibratia va fi mai puternica. |
- | * lsm6dsl (''nuttx-apps/examples/lsm6dsl/'')- afiseaza periodic la consola datele oferite de accelerometru si giroscop | + | |
- | * drv2605l (''nuttx-apps/examples/drv2605l/'') - programeaza senzorul de haptics pentru a vibra in diferite moduri | + | |
- | **2.** | + | ===== Resurse ===== |
+ | * [[https://www.ti.com/lit/ds/symlink/drv2605l.pdf|DRV2605L Effect library]] |