This shows you the differences between two versions of the page.
|
pm:lab:lab0-2024 [2026/02/22 17:07] florin.stancu |
pm:lab:lab0-2024 [2026/02/27 15:46] (current) florin.stancu |
||
|---|---|---|---|
| Line 379: | Line 379: | ||
| <code> upload_protocol = urclock </code> | <code> upload_protocol = urclock </code> | ||
| + | |||
| + | Dacă doriți să folosiți alt editor de text (e.g., ''vim''), pur și simplu instalați PlatformIO din package manager-ul distribuției voastre și utilizați CLI-ul: | ||
| + | |||
| + | <code sh> | ||
| + | pio init --board ATmega324P | ||
| + | # creați src/main.c, editați codul, adăugați în platform.ini ca mai sus | ||
| + | # apoi, pentru a compila + uploada pe placă folosiți comanda: | ||
| + | pio run -t upload | ||
| + | </code> | ||
| === 4.3.1 Alternativă la PlatformIO: instalare separată avr-gcc toolchain === | === 4.3.1 Alternativă la PlatformIO: instalare separată avr-gcc toolchain === | ||
| Line 477: | Line 486: | ||
| <note info> | <note info> | ||
| Observați comportamentul: la apăsări scurte ale butonului, există șanse ca programul să rateze schimbarea de stare și să nu aibe nici un efect. | Observați comportamentul: la apăsări scurte ale butonului, există șanse ca programul să rateze schimbarea de stare și să nu aibe nici un efect. | ||
| - | Acest lucru se întâmplă deoarece funcția de delay (''_sleep_ms'') este blocantă (defapt face busy-waiting pe procesor) iar codul cu interogarea instantanee a stării GPIO-ului de input să nu apuce să fie executat! | + | Acest lucru se întâmplă deoarece funcția de delay (''_sleep_ms'') este blocantă (de fapt, face busy-waiting pe procesor) iar codul cu interogarea instantanee a stării GPIO-ului de input să nu apuce să fie executat! |
| Vom afla abia la [[:pm:lab:lab3-2023-2024|laboratorul 3]] (Timers) o soluție elegantă de a face acest lucru independent și asincron. | Vom afla abia la [[:pm:lab:lab3-2023-2024|laboratorul 3]] (Timers) o soluție elegantă de a face acest lucru independent și asincron. | ||
| Line 491: | Line 500: | ||
| * Hint: folosiți un automat finit de stări pentru a implementa această funcționalitate ;) | * Hint: folosiți un automat finit de stări pentru a implementa această funcționalitate ;) | ||
| * Hint2: pentru a obține culoarea galben, este nevoie ca și LED-ul roșu și cel verde să fie aprinse simultan! | * Hint2: pentru a obține culoarea galben, este nevoie ca și LED-ul roșu și cel verde să fie aprinse simultan! | ||
| - | * **Bonus**: la long button press (e.g., timp de 2 secunde) să reseteze iar spre RED (hard: fără timere pentru cine știe deja :D)! | + | * **Bonus**: la long button press (e.g., timp de 2 secunde) să reseteze iar spre RED (însă fără a utiliza timere hardware)! |
| <note hint> | <note hint> | ||
| Line 500: | Line 509: | ||
| while True: | while True: | ||
| - | if state == SEM_OFF: | + | if state == SEM_RED: |
| if btn_pressed(BTN1): | if btn_pressed(BTN1): | ||
| state = SEM_YELLOW | state = SEM_YELLOW | ||
| Line 507: | Line 516: | ||
| sleep(1ms) | sleep(1ms) | ||
| - | if state == SEM_GREEN: | + | if state == SEM_YELLOW: |
| # aici nu avem verificarea btn_pressed(BTN1)... | # aici nu avem verificarea btn_pressed(BTN1)... | ||
| - | # TODO: aprindem led-ul verde, așteptăm blocant... | + | # TODO: aprindem led-ul galben, așteptăm blocant, apoi se trece in starea: |
| - | # după 10s delay, avansăm starea: | + | sleep(2sec) |
| - | state = SEM_YELLOW | + | state = SEM_GREEN |
| - | if state == SEM_YELLOW: | + | if state == SEM_GREEN: |
| # TODO: facem blink timp de 2sec și trecem în starea RED | # TODO: facem blink timp de 2sec și trecem în starea RED | ||
| - | # folosiți altă variabilă pentru a contoriza cele 2 secunde din fragmente | + | # eventual, folosiți altă variabilă pentru a contoriza cele 2 secunde din fragmente |
| # (trebuie să faceți blink la LED!) | # (trebuie să faceți blink la LED!) | ||
| Line 530: | Line 539: | ||
| isLedBlinking = 0 | isLedBlinking = 0 | ||
| ledCurrentState = 0 | ledCurrentState = 0 | ||
| - | lastBlinkTicks = 0 # "data" (în ticks) ultimei schimbări de stare a LED-ului | + | lastBlinkTicks = 0 # timestamp-ul (în ticks) ultimei schimbări de stare a LED-ului |
| while True: | while True: | ||
| Line 536: | Line 545: | ||
| # inversare booleană | # inversare booleană | ||
| isLedBlinking = !isLedBlinking | isLedBlinking = !isLedBlinking | ||
| + | |||
| if isLedBlinking: | if isLedBlinking: | ||
| # testăm dacă s-a scurs timpul (500ms) de la ultima schimbare de stare | # testăm dacă s-a scurs timpul (500ms) de la ultima schimbare de stare | ||
| if (ticks - lastBlinkTicks) > 50: # ATENȚIE: 50 ticks == 500ms! | if (ticks - lastBlinkTicks) > 50: # ATENȚIE: 50 ticks == 500ms! | ||
| - | lastBlinkTicks = ticks # salvăm "ticks" curent | + | lastBlinkTicks = ticks # salvăm timestampul evenimentului |
| ledCurrentState = !ledCurrentState # inversăm starea LED-ului | ledCurrentState = !ledCurrentState # inversăm starea LED-ului | ||
| # apoi, *mereu*, aplicăm starea curentă a LED-ului: | # apoi, *mereu*, aplicăm starea curentă a LED-ului: | ||
| gpio_set(LED, ledCurrentState) | gpio_set(LED, ledCurrentState) | ||
| + | |||
| else: | else: | ||
| # ne asigurăm că LED-ul e stins | # ne asigurăm că LED-ul e stins | ||
| Line 554: | Line 565: | ||
| </code> | </code> | ||
| - | Cum ne ajută contorizarea ticks-urilor pentru pentru determinarea unui long press? Simplu: verificăm starea butonului la fiecare loop (deci 10ms) și reținem numărul consecutiv de bucle pentru care butonul era apăsat! Dacă acest contor ajunge să depășească 200 (ticks, deci 2000 ms) înseamnă că a avut loc evenimentul de long press. Dacă butonul a fost lăsat între timp (mai mare de 10ms pentru ca acea verificare să aibe loc), acest contor se va reseta! | + | Cum ne va ajuta contorizarea ticks-urilor pentru pentru determinarea unui long press? Simplu: putem verifica starea butonului la fiecare loop (deci 10ms) și reținem numărul consecutiv de bucle pentru care butonul era apăsat! Dacă acest contor ajunge să depășească 200 (ticks, deci 2000 ms) înseamnă că a avut loc evenimentul de long press. Dacă butonul a fost lăsat între timp (mai mare de 10ms pentru ca acea verificare să aibe loc), acest contor se va reseta! |
| </note> | </note> | ||
| Line 570: | Line 581: | ||
| * [[jan.vaduva@upb.ro | Alex Văduva]] | * [[jan.vaduva@upb.ro | Alex Văduva]] | ||
| | | ||
| - | |||