Structuri de Meniu în ESP32

Choose a study mode

Play Quiz
Study Flashcards
Spaced Repetition
Chat to Lesson

Podcast

Play an AI-generated podcast conversation about this lesson
Download our mobile app to listen on the go
Get App

Questions and Answers

Care este scopul principal al utilizării unei structuri MenuItem într-un proiect ESP32 cu meniu navigabil?

  • Pentru a oferi acces la toți pinii GPIO.
  • Pentru a reduce dimensiunea sketch-ului.
  • Pentru a accelera comunicarea SPI.
  • Pentru a gestiona facil stările și legăturile dintre itemi. (correct)

Ce membru al unei structuri de tip MenuItem indică submeniul asociat acelui item?

  • label
  • callback
  • child (correct)
  • parent

Cum se realizează afișarea unui item de meniu selectat pe un ecran LCD 16x2?

  • Serial.println(item.label);
  • Icd.print(item->label);
  • oled.display(item.label);
  • Icd.clear(); Icd.print(item->label); (correct)

Ce rol are funcția callback asociată unui item de meniu?

<p>Execută acțiunea specifică acelui item. (B)</p>
Signup and view all the answers

Care este metoda recomandată de a parcurge un meniu cu encoder rotativ?

<p>Incrementarea/decrementarea indexului curent. (A)</p>
Signup and view all the answers

Ce funcție se poate apela pentru a reveni la meniul părinte?

<p>goToParent() (D)</p>
Signup and view all the answers

Într-o structură de meniu, ce legătură asigură navigarea laterală (left/right)?

<p>previous și next (B)</p>
Signup and view all the answers

Ce tip de pointer este uzual folosit pentru a defini structura de itemi într-un meniu?

<p>MenuItem* (D)</p>
Signup and view all the answers

Cum se asigură stabilitatea afișajului când un utilizator rotește encoderul rapid?

<p>Se actualizează afișajul doar dacă poziția s-a schimbat. (A)</p>
Signup and view all the answers

Cum previi trecerea în afara limitelor meniului când se rotește encoderul?

<p>Se verifică dacă pointerul next este NULL. (C)</p>
Signup and view all the answers

Care este scopul variabilei currentMenu într-un sistem de meniu?

<p>Reprezintă pointerul la itemul curent din meniu. (B)</p>
Signup and view all the answers

Care dintre următoarele este o bună practică în definirea meniurilor statice?

<p>Inițializarea tuturor legăturilor în setup(). (D)</p>
Signup and view all the answers

Cum afișezi un meniu cu mai mult de două opțiuni pe un LCD 16x2?

<p>Schimbi pagina afișată la fiecare două itemi. (A)</p>
Signup and view all the answers

Ce tehnică este utilă pentru a implementa un meniu „circular"?

<p>if(next == NULL) next = firstItem; (D)</p>
Signup and view all the answers

Ce avantaj oferă folosirea unui pointer constant (const MenuItem*) pentru meniuri statice?

<p>Reduce memoria RAM utilizată. (D)</p>
Signup and view all the answers

De ce este preferat millis() în loc de delay() într-un proiect cu meniu și encoder?

<p><code>millis()</code> permite execuția non-blocantă (A)</p>
Signup and view all the answers

Cum se gestionează un refresh periodic al ecranului fără a bloca execuția?

<p>Se compară <code>millis()</code> cu un timestamp anterior (D)</p>
Signup and view all the answers

Ce problemă poate apărea dacă nu se resetează timestamp-ul după un millis() trigger?

<p>Evenimentul se repetă constant fără pauză. (D)</p>
Signup and view all the answers

Care dintre următoarele este o abordare corectă pentru multitasking soft cu flag-uri?

<p>if (shouldUpdate) (A)</p>
Signup and view all the answers

Cum poți evita conflictele între două procese ce folosesc același timer (millis())?

<p>Declarând două variabile timestamp separate (A)</p>
Signup and view all the answers

Ce valoare returnează millis() după aproximativ 50 de zile de uptime?

<p>Revine la 0 (A)</p>
Signup and view all the answers

Care e metoda recomandată pentru actualizarea non-blocantă a unei variabile de afișaj?

<p>if (millis() - lastRefresh &gt; 100) (C)</p>
Signup and view all the answers

Cum afectează folosirea while(true) în loop() procesele de fundal?

<p>Le oprește complet (D)</p>
Signup and view all the answers

Ce bibliotecă se poate folosi pentru multitasking simplu pe ESP32?

<p>TaskScheduler.h (C)</p>
Signup and view all the answers

Ce tip de variabile trebuie protejate în procese paralele (cu FreeRTOS)?

<p>globale modificate de mai multe taskuri (A)</p>
Signup and view all the answers

Flashcards

Scopul structurii struct MenuItem

Permite gestionarea ușoară a stărilor și a legăturilor dintre elementele meniului.

Membru 'child' în MenuItem

Indică submeniul asociat unui element de meniu.

Afișarea unui item de meniu pe LCD 16x2

Se folosește lcd.clear() pentru a curăța ecranul, apoi lcd.print() pentru afișare.

Rolul funcției callback

Funcția callback este executată când un item este selectat.

Signup and view all the flashcards

Metoda de parcurgere cu encoder rotativ

Incrementarea/decrementarea indexului curent.

Signup and view all the flashcards

Revenirea la meniul părinte

Funcția goToParent() este folosită pentru a naviga în sus în structura meniului.

Signup and view all the flashcards

Navigare laterală în meniu

previous și next sunt folosite pentru a naviga între itemi la același nivel.

Signup and view all the flashcards

Tipul de pointer pentru structura itemilor

Un pointer la structura de tip MenuItem.

Signup and view all the flashcards

Stabilitatea afișajului la rotire rapidă

Se actualizează afișajul doar dacă poziția s-a schimbat.

Signup and view all the flashcards

Prevenirea trecerii în afara limitelor meniului

Se verifică dacă pointerul next este NULL.

Signup and view all the flashcards

Scopul variabilei currentMenu

currentMenu este folosit pentru a ști ce item este selectat în mod curent.

Signup and view all the flashcards

Practică bună pentru meniurile statice

Inițializarea tuturor legăturilor în setup()

Signup and view all the flashcards

Afișarea unui meniu cu mai mult de două opțiuni pe un LCD 16x2

Se schimbă pagina afișată la fiecare două itemi.

Signup and view all the flashcards

Tehnică pentru implementarea unui meniu circular

if(next == NULL) next = firstItem;

Signup and view all the flashcards

Avantajul pointerilor constanți pentru meniuri statice

Itemii constanți pot fi stocați în flash, eliberând RAM.

Signup and view all the flashcards

millis() vs. delay() pentru meniu și encoder

millis() permite execuția non-blocantă.

Signup and view all the flashcards

Refresh periodic al ecranului non-blocant

Se compară millis() cu un timestamp anterior.

Signup and view all the flashcards

Problema lipsei resetării timestamp-ului după trigger

Evenimentul se repetă constant fără pauză.

Signup and view all the flashcards

Abordare corectă pentru multitasking software cu flag-uri

Folosirea flag-urilor (shouldUpdate, trigger, etc.).

Signup and view all the flashcards

Evitarea conflictelor între procese cu același timer

Se declară două variabile timestamp separate.

Signup and view all the flashcards

Valoarea returnată de millis() după 50 de zile

Revine la 0.

Signup and view all the flashcards

Actualizarea non-blocantă a unei variabile de afișaj

if (millis() - lastRefresh > 100)

Signup and view all the flashcards

Efectul lui while(true) în loop() asupra proceselor de fundal

Întrerupe complet procesele de fundal.

Signup and view all the flashcards

Bibliotecă pentru multitasking simplu pe ESP32

TaskScheduler.h

Signup and view all the flashcards

Variabile care trebuie protejate în procese paralele

Variabilele globale modificate de mai multe task-uri.

Signup and view all the flashcards

Study Notes

Structuri de Meniu în ESP32

  • Structurile de tip Menultem facilitează gestionarea stărilor și legăturilor logice (următor, anterior, părinte, copil) ale itemilor din meniu.
  • Membrul child dintr-o structură Menultem indică submeniul asociat.
  • Afișarea unui item de meniu selectat pe un LCD 16x2 se face prin curățarea ecranului cu Icd.clear() și apoi afișarea textului cu Icd.print(item->label).
  • Funcția callback asociată unui item de meniu execută acțiunea specifică acelui item la selectare.
  • Parcurgerea unui meniu cu un encoder rotativ se face prin incrementarea/decrementarea indexului curent.
  • Funcția goToParent() permite revenirea la meniul părinte.
  • Legăturile previous și next asigură navigarea laterală între itemi la același nivel în structura meniului.
  • Un pointer de tip Menultem* este folosit pentru a defini structura itemilor într-un meniu.
  • Stabilitatea afișajului la rotirea rapidă a encoderului se asigură prin actualizarea afișajului doar dacă poziția s-a schimbat.
  • Trecerea în afara limitelor meniului este prevenită prin verificarea dacă pointerul next este NULL înainte de accesare.
  • Variabila currentMenu reprezintă pointerul către itemul curent din meniu.
  • În definirea meniurilor statice, initializarea tuturor legăturilor în setup() este o practică bună.
  • Un meniu cu mai mult de două opțiuni pe un LCD 16x2 se afișează prin schimbarea paginii afișate la fiecare două itemi.
  • Implementarea unui meniu "circular" se face prin asignarea primului item la next atunci când se ajunge la ultimul item: if(next == NULL) next = firstItem;.
  • Folosirea unui pointer constant (const Menultem*) pentru meniuri statice reduce memoria RAM utilizată, deoarece itemii constanți pot fi stocați în flash.

Procese în Fundal

  • millis() este preferat lui delay() deoarece permite execuția non-blocantă, verificând condițiile fără a opri programul.
  • Un refresh periodic al ecranului fără blocarea execuției se realizează prin compararea millis() cu un timestamp anterior.
  • Dacă timestamp-ul nu se resetează după un trigger millis(), evenimentul se va repeta constant fără pauză.
  • Multitasking-ul soft cu flag-uri implică folosirea flag-urilor (shouldUpdate, trigger, etc.) pentru controlul execuției în loop() fără delay.
  • Conflictele între procese care folosesc același timer (millis()) sunt evitate prin declararea a două variabile timestamp separate pentru fiecare proces.
  • Valoarea returnată de millis() revine la 0 după aproximativ 49.7 zile (overflow), necesitând precauție.
  • Actualizarea non-blocantă a unei variabile de afișaj se realizează cu if (millis() - lastRefresh > 100), verificând timpul necesar fără blocare.
  • Utilizarea while(true) în loop() oprește complet procesele de fundal.
  • Biblioteca TaskScheduler.h poate fi folosită pentru multitasking simplu pe ESP32.
  • Variabilele globale modificate de mai multe task-uri trebuie protejate în procese paralele, deoarece pot crea condiții de cursă.
  • Funcția vTaskDelay() amână executarea unui task în FreeRTOS pe ESP32 fără a bloca restul sistemului.
  • Unitatea de timp implicită pentru vTaskDelay(1000) în FreeRTOS este Ticks, unde 1 tick ≠ 1 ms și depinde de frecvența sistemului.
  • Un task care rulează fără vTaskDelay() într-un sistem FreeRTOS acaparează toată execuția CPU.
  • Sincronizarea între două task-uri în ESP32/FreeRTOS se realizează cu xSemaphore sau xQueue.
  • Un task separat pentru controlul LCD-ului permite delay-uri în paralel cu restul logicii.

Controlul Afișajelor LCD

  • Orice doi pini de pe ESP32 pot fi conectați la LCD-ul I2C, fiind configurați ca SDA și SCL la inițializare prin Wire.begin(SDA, SCL).
  • Comanda corectă pentru inițializarea unui LCD I2C 16x2 este Icd.init(); Icd.backlight().
  • Curățarea afișajului LCD fără flicker se face prin Icd.setCursor(0,0); lcd.print(" ");, care suprascrie linia cu spații.
  • Poziția cursorului pe LCD se controlează cu Icd.setCursor(col, row), metoda standard.
  • Animația de scroll pe un ecran 16x2 se creează cu Icd.scrollDisplayLeft(), care derulează întregul display.
  • Comanda Icd.noBacklight() oprește iluminarea de fundal, economisind curent.
  • Suprascrierea unui text scurt peste unul mai lung pe LCD se evită prin adăugarea de spații la finalul textului.
  • Dacă se încearcă scrierea pe rândul 2 (index 1) înainte de Icd.begin(), nu apare nimic pe ecran deoarece LCD-ul trebuie inițializat corect.
  • Caractere custom pe un LCD 16x2 se crează cu Icd.createChar(nr, pattern[]), LCD-urile 16x2 suportând până la 8 caractere speciale.
  • Limita standard de caractere customizabile pentru un LCD clasic HD44780 este de 8 caractere, definite de utilizator în CGRAM.
  • Afișarea rapidă fără întârziere între caractere se asigură prin scrierea într-un buffer (string) și afișarea completă.
  • Biblioteca necesară pentru a folosi LCD-ul cu I2C în Arduino IDE este LiquidCrystal_I2C.h.
  • Dacă se scriu mai mult de 16 caractere pe un rând, textul continuă în afara ecranului, fiind invizibil.
  • Simbolul ° (grad) pe un LCD 16x2 se afișează cu lcd.print((char)223), codul ASCII 223 corespunzând simbolului de grad.
  • Consumul energetic al unui LCD când nu e necesar afișajul se reduce cu lcd.noBacklight(); şi lcd.noDisplay();, care opresc iluminarea și afișajul dar mențin conexiunea activă.

Butoane și Encodere

  • Conectarea corectă a unui buton la un pin ESP32 pentru a obține LOW la apăsare se face între pin și GND, cu activare INPUT_PULLUP, care folosește rezistența internă.
  • Efectul de "bounce" la un buton sunt apăsări false cauzate de oscilații rapide.
  • Debounce-ul software se realizează cu debounce logic cu millis(), care ignoră tranzițiile rapide.
  • Citirea butonului care evită blocarea loop() se face printr-o implementare de tip millis() non-blocking.
  • Un encoder rotativ generează două semnale digitale în cuadratură la rotire.
  • Direcția de rotație a unui encoder se determină comparând semnalele A și B.
  • Reacția imediată la o schimbare de stare a unui buton se obține cu attachInterrupt() pe pin.
  • O limitare a folosirii întreruperilor cu encodere rotative este pierderea semnalului dacă se rotește rapid, dacă codul ISR nu este optimizat.
  • Un encoder cu 3 pini utilizează două cuadraturi și un pin LOW/HI pentru buton.
  • Biblioteca Arduino frecvent utilizată pentru encodere este Encoder.h.
  • Pentru un encoder standard (20 pulsuri), se obțin 40 de stări distincte per clic dacă se citesc ambele faze (A și B).
  • Filtrarea zgomotului la encoder la nivel hardware se face cu condensatori pe semnale.
  • Asigurarea citirii corecte a encoderului în loop() fără întreruperi se face verificând fiecare pin individual și deducând rotația.
  • O abordare eficientă pentru debounce software al encoderului este millis() cu verificare de tranziție.
  • Funcția read() asigură citirea non-blocking a unui encoder în biblioteca Encoder.h, returnând poziția actuală fără a bloca rularea programului.

EEPROM

  • ESP32 folosește memoria Flash (emulare EEPROM) pentru stocarea datelor persistente, neavând EEPROM reală.
  • Biblioteca EEPROM.h trebuie inclusă pentru a folosi EEPROM pe ESP32.
  • Funcția EEPROM.begin(size) trebuie apelată pentru a începe lucrul cu EEPROM, ESP32 necesitând rezervarea memoriei în flash.
  • Scrierea unui int la adresa 0 în EEPROM pe ESP32 se face cu EEPROM.put(0, val).
  • Funcția EEPROM.commit() este esențială după scrierea în EEPROM pentru salvarea datelor în memoria flash.
  • Dimensiunea maximă ce poate fi alocată prin EEPROM.begin() pe ESP32 este de 4096 bytes (4KB).
  • Citirea unei structuri de date din EEPROM se face cu EEPROM.get(adr, var).
  • Un risc al scrierii frecvente în EEPROM este uzura memoriei flash.
  • Scrierile repetate inutile în EEPROM se evită verificând dacă valoarea s-a schimbat.
  • O structură personalizată este recomandată pentru salvarea mai multor parametri în EEPROM.
  • După salvarea datelor cu EEPROM.put(), este necesar să se apeleze EEPROM.commit() pentru salvarea fizică.
  • Datele salvate în EEPROM pot fi "șterse" prin rescrierea cu valori 0 sau default.
  • Pentru a salva 2 structuri diferite în EEPROM, este necesar să se aloce zone diferite de memorie.
  • Funcția EEPROM.get() returnează datele salvate ca referință în EEPROM.
  • Accesul concurent la EEPROM dintr-un task paralel (FreeRTOS) necesită protecție, altfel datele se pot corupe.

PWM

  • Funcția ledcAttachPin(pin, channel) asociază un canal PWM cu un pin pe ESP32.
  • ESP32 nu setează frecvență implicită a semnalului PWM – este obligatoriu să o definești cu ledcSetup().
  • Funcția ledcSetup(channel, freq, resolution) setează frecvența și rezoluția unui canal PWM.
  • Valoarea maximă a duty-cycle-ului pentru o rezoluție de 8 biți este 255.
  • ESP32 permite 16 canale PWM independente (0-15).
  • Setarea unui semnal PWM de 10kHz și 10 biți pe canalul 2 se face cu ledcSetup(2, 10000, 10).
  • Nivelul de duty-cycle pe un canal PWM se setează cu ledcWrite(channel, duty).
  • Frecvența unui canal PWM se modifică în timp real apelând ledcSetup() din nou cu noua frecvență.
  • Setearea unei rezoluții de 16 biți și a unei frecvențe mare pe PWM poate duce la instabilitatea semnalului sau la nefuncționarea acestuia, din cauza consumului ridicat de resurse.
  • Dacă două canale PWM diferite controlează același pin, doar ultimul atașat va funcționa, suprascriind legătura pinului.
  • ESP32 poate genera semnale PWM simultan pe mai multe piese hardware (e.g., LED + motor) cu canale diferite.
  • Un avantaj al PWM software față de PWM hardware este că orice pin poate fi folosit, deoarece nu este legat de timere hardware.
  • Controlul luminozității unui LED cu PWM se realizează cu ledcWrite() pe ESP32.
  • Canalele PWM care folosesc același timer pot fi sincronizate precis.

ADC

  • PWM este o metodă de modulare a duratei impulsurilor.
  • Funcția analogRead(pin) citește o valoare analogică pe ESP32.
  • Rezoluția implicită a ADC-ului pe ESP32 este de 12 biți, valoarea returnată de analogRead() fiind între 0 și 4095.
  • ADC-ul ESP32 funcționează fără calibrare specială în intervalul de tensiune 0-3.3V.
  • Funcția analogSetBits(bits) setează rezoluția ADC-ului pe ESP32, controlând câți biți are conversia analogică.
  • O problemă care apare adesea la citirea semnalelor analogice brute pe ESP32 este zgomotul și fluctuațiile mari.
  • Media mai multor citiri reduce fluctuațiile la citirea valorilor analogice.
  • Anumiți pini (GPIOs) care NU sunt folosiți de SPI/Flash sunt siguri pentru citire analogică pe ESP32.
  • Valoarea brută analogRead() poate fi convertită într-o tensiune (V) cu formula: tensiune = analogRead(pin) / 4095.0 * 3.3;.
  • Funcția analogSetAttenuation() setează factorul de atenuare al canalului ADC, crescând intervalul de tensiune măsurabil.
  • Dacă un senzor de

Studying That Suits You

Use AI to generate personalized quizzes and flashcards to suit your learning preferences.

Quiz Team

More Like This

ESP32 Board - Accessories and Programming
18 questions
ESP32: System on a Chip
12 questions

ESP32: System on a Chip

DazzlingForesight2080 avatar
DazzlingForesight2080
ESP32 Wi-Fi and Bluetooth Features
5 questions
Use Quizgecko on...
Browser
Browser