Differences

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

Link to this comparison view

iothings:laboratoare:lab2 [2022/02/11 16:58]
laura.ruse removed
iothings:laboratoare:lab2 [2022/03/23 09:58] (current)
cosmin.chenaru [Exerciții]
Line 1: Line 1:
-====== Comunicația radio în Rețele ​de Senzori Wireless ======+===== Laborator 02. Sistem ​de fișiere pe ESP32 =====
  
-===== Sistemul de senzori ​de pe nodul Sparrow v3 =====+În laboratorul ​de astăzi vom folosi flash-ul intern al plăcuței ESP32 pe post de sistem de fișiere.
  
-Nodul senzorial Sparrow este echipat cu trei tipuri de senzori: temperatură,​ umiditate și luminozitate ambientală +=== 1Memoria flash a plăcuței ESP32 ===
-Senzorul de luminozitate este analogic și furnizează o tensiune direct proporțională cu nivelul iluminării ambientale. Această tensiune poate fi citită de către microcontrollerul ATMega128RFA1 de pe portul F, pinul 2 (PF2).+
  
-Tot pe portul F, pinul PF0 puteți citi și tensiunea ​de alimentare a nodului senzorialValoarea tensiunii citite ​este divizată cu 2, a că va trebui să o adjustați.+Chip-ul ESP32 de la Espressif are în interior o memorie externă (flash) cu o capacitate de 4MBEa este folosită pentru ​salva programele ​și datele programelor. Memoria externă este conectată la procesor prin intermediul bus-ului de SPI (Serial Peripheral Interface), iar procesorul poate accesa maxim 16MB de memorie externă.
  
-Senzorul de umiditate și temperatură este de tipul [[http://www.sensirion.com/​fileadmin/​user_upload/​customers/​sensirion/​Dokumente/​Humidity/​Sensirion_Humidity_SHT21_Datasheet_V3.pdf ​SHT21]] și este conectat la interfața I2C a microcontroller-ului.+{{:iothings:​laboratoare:​lab2_external_flash.png?300|}}
  
-<note tip> Descărcați scheletul ​de cod de {{:​iothings:​wiki:​tema1.zip| aici}} ​și completați TODO-urile astfel încât să citiți date de la toate tipurile ​de senzori. </​note>​+Pentru a putea face diferența intre partea ​de programe ​și partea de date, memoria externă este impărțită in partiții. Tabela ​de partiții se află la offset-ul 0x8000 față ​de adresa de început a memoriei externe, și poate arăta astfel:
  
 +  * app (type 0) - partiția ce conține aplicațiile (programele)
 +  * data (type 1) - partiția ce conține datele
  
-===== Stări de low power pentru Sparrow v3 =====+Dimensiunea fiecărei partiții poate fi modificată,​ dar aplicații precum Arduino IDE au aceste dimensiuni predefinite. Offset-ul fiecărei partiții poate fi definit într-un header, iar compilatorul aranjează codul în așa fel încât accesul la partiția ​de programe sau cea de date să poată fi diferențiat. ​
  
-Dat fiind faptul că rezervele ​de energie din bateria proprie sunt limitate, nodul senzorial poate fi programat să ruleze într-o stare de consum redus sau sleep pentru a minimiza consumul de energie. Aceasta poate fi realizată prin dezactivarea tuturor senzorilor externi (bitul PE7 pe 0 logic) apoi trecerea microcontroller-ului însuși în sleep. ​+=== 2. Ce este un sistem ​de fișiere ===
  
-<note tip>​Descărcați scheletul de cod de {{:​iothings:​wiki:​tema2.zip| aici}} ​și completați TODO-urile astfel încât să citiți date de la toate tipurile ​de senzori la intervale regulate de timpapoi să intrați în sleep.</​note>​ +Un sistem ​de fișiere este asemănător cu o bază de dateastfel incât mai multe fișiere ​să poată fi organizate ierarhic iar datele dintr-un fișier să nu corupă (suprascrie) datele din alt fișier.
-===== Transceiver-ul de pe ATMega128RFA1 =====+
  
-Transceiver-ul de pe microcontroller-ul ATMega128RFA1 permite acestuia să transmită în diferite benzi din 2.4GHz. Permite viteze de transmisie de 250kbps, 1Mbps și 2 Mbps. Are două moduri de funcționare,​ Basic și Extended. Modul Extended include multe funcționalități prevăzute de obicei în nivelele de acces la mediu. În acest caz, funcționalitățile sunt cele necesare pentru implementarea IEEE 802.15.4+{{:​iothings:​laboratoare:​lab2_fs.png?300|}}
  
 +Deoarece sistemul de fișiere consumă spațiu adițional de pe memoria externă (ex. numele fișierului),​ în sistemele embedded cu puțin spațiu se folosesc sisteme de fișiere cât mai simple.
  
-==== Interfața cu microcontroller-ul ==== +=== 3Implementarea SPIFFS ​===
- +
-Interfața cu microcontroller-ul este necesară pentru a comanda transceiver-ul din program și pentru a obține/​trimite date către acestaÎn cazul RFA1, avantajul major de a avea transceiver-ul și microcontroller-ul pe același chip înseamnă că se pot face transferuri foarte rapide între acestea. RFA1 pune la dispoziție următoarea interfață:​ +
- +
-  * Regiștrii de comandă: Sunt tratați ca orice alt registru I/O și sunt accesați la fel de rapid. Sunt folosiți pentru a trimite comenzi către transceiver sau a obține informații punctuale despre funcționarea acestuia. Exemple sunt: ''​TRX_STATE'',​ ''​TRX_STATUS'',​ ''​PHY_RSSI''​. Folosirea acestor regiștri este posibilă doar atunci când ceasul transceiver-ului nu este oprit +
-  * Frame buffer: Este o zonă de memorie de 128 bytes în care se recepționează/​din care se transmit pachete. Este accesibilă din microcontroller tot ca o zonă de regiștri I/O de 128bytes, începutul este ''​TRXFBST''​ și sfârșitul este ''​TRXFBEND''​. Scrierea/​Citirea în/din framebuffer va dura întotdeauna un ciclu de ceas, adică avem maxim 128Mbps! **Atenție!** Scrierea și citirea în/din buffer se face în mod diferit, conform tabelului de mai jos: +
- +
-^  **Operații pe frame buffer** ​ ||| +
-^Operație ^ Date ^ Lungime | +
-| Scriere | TRXFBST+1 .. TRXFBEND | TRXFBST | +
-| Citire | TRXFBST .. TRXFBEND-1| TST_RX_LENGTH | +
- +
-  * Registrul ''​TRXPR'':​ Moștenire din timpurile în care microcontroller-ul și transceiver-ul erau în chip-uri separate, ''​TRXPR''​ este registrul care deține două flag-uri (în trecut doi pini) care afectează transceiver-ul chiar dacă acesta este în sleep. +
-      * Bit-ul TRXRST Care poate reseta oricând transceiver-ul +
-      * Bit-ul SLPTR, care controlează atât starea de sleep a transceiver-ului cât și startul transmisiei unui pachet +
-  * Întreruperi:​ Transceiver-ul poate fi configurat să genereze mai multe întreruperi microcontroller-ului,​ dintre care amintim: +
-      * TRX24_RX_START:​ A început recepția unui pachet. Se poate începe imediat citirea frame buffer-ului +
-      * TRX24_TX_END:​ Semnalează sfârșitul transmisiei +
-==== Mașina de stări ==== +
- +
-Transceiver-ul de pe RFA1 folosește o mașină de stări pentru a reșine care este modul de operare curent (dacă transmite, recepționează,​ dacă este în standby, dacă se pregătește să transmită, etc.) Stările care apar sunt: +
-  * **SLEEP** Transceiver-ul este în stare de hibernare, nu consumă curent  +
-  * **RESET** Transceiver-ul tocmai a fost restartat +
-  * **TRX_OFF** Starea de standby, în care nu se ascultă mediul pentru pachete +
-  * **RX_ON** Starea în care se ascultă mediul +
-  * **BUSY_RX** Se recepționează un pachet +
-  * **PLL_ON** Starea în care componenta de transmisie este activă și pregătită +
-  * **BUSY_TX** Se transmite un pachet +
- +
-Tranzițiile între stări sunt fie declanșate de evenimente exterioare, și atunci sunt subliniate cu verde, fie prin comandă de la microcontroller (și atunci sunt fie colorate cu albastru, fie cu roșu). +
- +
-{{ :​wiki:​rfa1_basic_states.png?​nolink&​900 |}} +
- +
-Regiștrii care se ocupă de controlul și observarea mașinii de stări sunt ''​TRX_STATE''​ și ''​TRX_STATUS''​. ''​TRX_STATE''​ conține biții ce comandă tranzițiile dintre stări (omitem stările ce nu le vom folosi în cadrul laboratorului,​ pentru o listă completă consultați datasheet-ul):​ +
- +
-^ ''​TRX_STATE'':​ | TRAC_STATUS2..0 | **TRX_CMD4..0** | +
- +
-^ Biți ^ Valoare ^ Înțeles ^ Macro GCC ^ Detalii | +
-| ''​TRX_CMD''​ | ''​0x00''​ | NOP  | | | +
-| ::: | ''​0x02''​ | TX_START ​ | CMD_TX_START | Comandă ce pornește transmiterea pachetelor, similar cu SLPTR | +
-| ::: | ''​0x03''​ | FORCE_TRX_OFF ​ | CMD_FORCE_TRX_OFF | Transceiver-ul trece imediat în TRX_OFF (delay depinde de starea curentă) | +
-| ::: | ''​0x04''​ | FORCE_PLL_ON ​ | CMD_FORCE_PLL_ON | Similar, forțează trecerea în starea ''​PLL_ON''​ | +
-| ::: | ''​0x06''​ | RX_ON  | CMD_RX_ON | Trecerea în ''​RX_ON''​ | +
-| ::: | ''​0x08''​ | TRX_OFF ​ | CMD_TRX_OFF | Trecerea în ''​TRX_OFF'',​ ce presupune și terminarea activităților curente | +
-| ::: | ''​0x09''​ | PLL_ON ​ | CMD_PLL_ON | Trecerea în starea din care se poate transmite | +
- +
- +
-^ ''​TRX_STATUS'':​ | CCA_DONE | CCA_STATUS | TST_STATUS | **TRX_STATUS4..0** | +
- +
-^ Biți ^ Valoare ^ Înțeles ^ Detalii | +
-| ''​TRX_STATUS''​ | ''​0x01''​ | BUSY_RX | Transceiver-ul este ocupat cu primirea unui pachet | +
-| :::            | ''​0x02''​ | BUSY_TX | Transceiver-ul trimite un pachet | +
-| :::            | ''​0x06''​ | RX_ON   | Starea curentă este ''​RX_ON''​| +
-| :::            | ''​0x08''​ | TRX_OFF | Starea curentă este ''​TRX_OFF''​| +
-| :::            | ''​0x09''​ | PLL_ON ​ | Starea curentă este ''​PLL_ON''​| +
-| :::            | ''​0x0F''​ | SLEEP   | Transceiver-ul este în starea de ''​SLEEP''​| +
-| :::            | ''​0x1F''​ | STATE_TRANSITION_IN_PROGRESS | Mașina de stări execută o tranziție | +
- +
-Accesul la acești biți se poate face la fel ca la orice registru I/O.  +
- +
-<code c> +
-TRX_STATE &= 0xe0; // masca corespunzătoare biților TRAC_STATUS2..0 +
-TRX_STATE |= CMD_FORCE_TRX_OFF;​ +
-</​code>​ +
- +
-Dat fiind că biții TRAC_STATUS2..0 sunt read-only, putem prescurta la: +
-<code c> +
-TRX_STATE = CMD_FORCE_TRX_OFF;​ +
-</​code>​ +
- +
-Folosind structuri:​ +
- +
-<code c> +
-TRX_STATE_struct.TRX_CMD = CMD_FORCE_TRX_OFF;​ +
-</​code>​ +
- +
- +
-==== Procedura de tranziție între stări ==== +
- +
-  - Se setează starea dorită în ''​TRX_STATE''​ +
-  - Se așteaptă până când ''​TRX_STATUS''​ nu mai contine TRANSITION_IN_PROGRESS in campul de biti **TRX_STATUS4..0** +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
-==== Procedura de transmisie a unui pachet ==== +
- +
-  - Se intră în starea ''​PLL_ON''​. Acest lucru garantează că nu se va începe recepția unui pachet peste frame buffer între momentul în care scriem în buffer și momentul în care pornim transmisia +
-  - Copiem datele în buffer  +
-    * Primul octet reprezintă dimensiunea pachetului +
-    * Urmează pachetul, maxim 127 bytes +
- +
-  - Pornim transmisia (prin bit-ul ''​SLPTR''​ sau prin comanda ''​TX_START''​) +
- +
- +
-==== Procedura de recepție a unui pachet ==== +
- +
-  - Se intră în starea ''​RX_ON''​ +
-  - Se primește întreruperea ''​RX_START''​ sau ''​RX_END''​ +
-  - Se începe citirea frame-buffer-ului +
-      * Pachetul este în frame-buffer începând cu primul octet +
-      * Dimensiunea este în ''​TST_RX_LENGTH''​ +
- +
- +
- +
-===== Particularități Avrora ===== +
- +
-Pentru a cunoaște identificatorului nodului din program, trebuie declarată variabila ''​node_address''​ în felul următor (datorită unui defect-?- de compilator prima variabilă declarată nu ajunge în .data chiar dacă se cere explicit):​ +
-<code c> +
-uint8_t nod1_address __attribute__((section("​.data"​))) = 0; +
-uint8_t node_address __attribute__((section("​.data"​))) = 0; +
-</​code>​ +
- +
-Nodurile își vor avea trecut identificatorul în ''​node_address''​ dacă se rulează avrora cu opțiunea ''​update-node-id=true''​. Această funcționalitate este asemănătoare cu citirea din EEPROM la un nod real. +
  
 +Sistemul de fișiere SPIFFS (SPI Flash File System) a fost început de Peter Andersson, pentru a adresa particularitățile memoriilor flash (NOR flash), care în special sunt afectate de scrierile repetate la aceeași adresă.
  
 +Repository-ul principal este disponibil pe GitHub ([[https://​github.com/​pellepl/​spiffs|SPIFFS]]),​ dar Arduino IDE are deja suportul precompilat pentru ESP32.
  
 +API-ul sistemului de fișiere include funcții precum SPIFFS_open() sau SPIFFS_write(),​ dar Arduino IDE ofera un API de abstractizare a sistemului de fișiere si putem apela funcții precum fs.open() și fs.write(). Programul "​SPIFFS_test"​ din Arduino IDE este un astfel de exemplu.
 ===== Exerciții ===== ===== Exerciții =====
-Folosiți scheletul de laborator - {{:​iothings:​wiki:​schelet_labwsn2.zip|}}. 
-  - Transmiteți un pachet de la nodul 1 la nodul 0 
-      * Hint: Utilizați macro-ul TRX_FRAME_BUFFER 
-      * Hint2: Ultimii doi octeți dintr-o transmisie reprezintă un CRC adăugat/​verificat automat de transceiver 
-      * verificarea se face cu flag-ul ''​RX_CRC_VALID''​ din registrul ''​PHY_RSSI''​ 
-      * dezactivarea CRC-ului automat se face din registrul ''​TRX_CTRL_1'',​ flag-ul ''​TX_AUTO_CRC_ON''​ 
-  - În rețeaua cu 4 noduri cu topologia dată în fișierul .top, transmiteți un pachet de la nodul 1 la nodul 0 
-      * Hint: Pentru a ajunge de la 1 la 0, un pachet trebuie să treacă prin nodurile intermediare 2 si 3 
- 
- 
- 
- 
- 
- 
- 
- 
- 
  
 +=== Agendă personală cu ESP32 ===
  
 +Ne propunem să implementăm o agendă personală care va scrie și citi informațiile pe sistemul de fișiere SPIFFS. Datele de intrare vor fi introduse de utilizator prin intermediul unui smartphone care se va conecta la plăcuta ESP32 prin Bluetooth.
  
 +Plecând de la exemplul "​SPIFFS_test"​ și "​SerialToSerialBT"​ din Arduino IDE, putem folosi smartphone-ul pentru a trimite date și comenzi prin Bluetooth către ESP32. În funcția principală "​loop()"​ dorim o dată să citim mesajul de la telefon, iar apoi să putem scrie sau citi către memoria externă.
  
 +{{:​iothings:​laboratoare:​lab2-agenda.png?​200|}}
 +===== Resurse =====
  
 +  * https://​randomnerdtutorials.com/​esp32-bluetooth-classic-arduino-ide/​
 +  * https://​play.google.com/​store/​apps/​details?​id=de.kai_morich.serial_bluetooth_terminal&​hl=en&​gl=US
 +  * https://​www.lucadentella.it/​en/​2016/​12/​22/​esp32-4-flash-bootloader-e-freertos/​
 +  * https://​www.espressif.com/​sites/​default/​files/​documentation/​esp32-wroom-32_datasheet_en.pdf
 +  * https://​github.com/​pellepl/​spiffs
iothings/laboratoare/lab2.1644591506.txt.gz · Last modified: 2022/02/11 16:58 by laura.ruse
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