This shows you the differences between two versions of the page.
pm:lab:lab3-2021 [2021/03/28 22:00] alexandru.predescu |
pm:lab:lab3-2021 [2021/04/02 10:55] (current) alexandru.predescu [4. Exerciții] |
||
---|---|---|---|
Line 83: | Line 83: | ||
Astfel, tensiunea medie care ajunge la dispozitiv este dată de relația: D * Vcc. | Astfel, tensiunea medie care ajunge la dispozitiv este dată de relația: D * Vcc. | ||
- | {{.:lab3:avr_pwm_01.jpg?600|Figura 8. Semnal PWM cu diferiți factori de umplere}} | + | {{.:lab3:avr_pwm_01.jpg?700|Figura 8. Semnal PWM cu diferiți factori de umplere}} |
Modularea folosește variația factorului de umplere a unui semnal dreptunghiular pentru a genera la ieșire o tensiune analogică. Considerând o formă de undă dreptunghiulară //f(t)// cu o valoare minimă //ymin=0// și o valoare maximă //ymax// și factorul de umplere //D// (ca în figură) valoarea medie a formei de undă e dată de relația: | Modularea folosește variația factorului de umplere a unui semnal dreptunghiular pentru a genera la ieșire o tensiune analogică. Considerând o formă de undă dreptunghiulară //f(t)// cu o valoare minimă //ymin=0// și o valoare maximă //ymax// și factorul de umplere //D// (ca în figură) valoarea medie a formei de undă e dată de relația: | ||
Line 160: | Line 160: | ||
<note important> | <note important> | ||
- | Frecvența semnalului PWM depinde de prescaler și de frecvența oscilatorului. Din secțiunea 15.9.3 (pag 102), formula de calcul a frecvenței în modul Fast PWM este: | + | Frecvența semnalului PWM depinde de prescaler și de frecvența oscilatorului. Din secțiunea 15.9.3 (pag 102), formula de calcul a frecvenței în modul Fast PWM 8-bit este: |
\begin{equation} | \begin{equation} | ||
- | f_{OCnX}=\frac{f_{clk}}{N \cdot 256} | + | f_{OCnX}=\frac{f_{clk}}{N \cdot (TOP + 1)}=\frac{f_{clk}}{N \cdot 256} |
\end{equation} </note> | \end{equation} </note> | ||
Line 206: | Line 206: | ||
===== 3. Aplicații cu PWM în Arduino ===== | ===== 3. Aplicații cu PWM în Arduino ===== | ||
- | În continuare, ne vom folosi de biblioteca Arduino pentru a testa rapid niște aplicații ale semnalelor PWM: controlul unui LED RGB și controlul poziției unui servomotor hobby. Alternativ, pentru cei care doresc să aprofundeze modul de programare la nivel de registre, se pot realiza aplicațiile folosind timer-e în modul Fast PWM și/sau CTC în loc de bibliotecile din Arduino (//analogWrite//, //Servo//). | + | În continuare, ne vom folosi de biblioteca Arduino pentru a realiza niște aplicații ale semnalelor PWM: controlul unui LED RGB și controlul poziției unui servomotor hobby. Alternativ, pentru cei care doresc să aprofundeze modul de programare la nivel de registre, se pot realiza aplicațiile folosind timer-e în modul Fast PWM și/sau CTC în loc de bibliotecile din Arduino (//analogWrite//, //Servo//). |
==== AnalogWrite ==== | ==== AnalogWrite ==== | ||
- | Funcția //analogWrite// din Arduino, configurează de fapt un timer în modul Fast PWM pe 8 biți și poate genera semnal PWM (doar) pe pinii asociați unuia dintre timer-e. ''analogWrite(pin_arduino, value_0_255)'' De exemplu, pe Atmega328p avem următorii pini care pot genera semnal PWM folosind funcția //analogWrite//: | + | Funcția //analogWrite// din Arduino, configurează de fapt un timer în modul Fast PWM pe 8 biți și poate genera semnal PWM (doar) pe pinii asociați unuia dintre timer-e. ''analogWrite(pin_arduino, value_0_255)'' De exemplu, pe Arduino/Atmega328p avem următorii pini care pot genera semnal PWM folosind funcția //analogWrite//: |
^ Pin Arduino ^ Pin Atmega328p ^ Timer output ^ Frecvența PWM (default) ^ | ^ Pin Arduino ^ Pin Atmega328p ^ Timer output ^ Frecvența PWM (default) ^ | ||
Line 219: | Line 219: | ||
| 3 | PD3 | OC2B (Timer2) | 490 Hz | | | 3 | PD3 | OC2B (Timer2) | 490 Hz | | ||
- | Este posibil să avem nevoie să modificăm frecvența semnalului PWM, caz în care trebuie să configurăm explicit Timer-ul (prescaler, TOP) folosind registre. [[https://www.arduino.cc/en/pmwiki.php?n=Tutorial/SecretsOfArduinoPWM|SecretsOfArduinoPWM]] | + | Este posibil să avem nevoie să modificăm frecvența semnalului PWM, caz în care trebuie să configurăm explicit Timer-ul (ex. prescaler, TOP) folosind registre. [[https://www.arduino.cc/en/pmwiki.php?n=Tutorial/SecretsOfArduinoPWM|SecretsOfArduinoPWM]] |
==== LED RGB ==== | ==== LED RGB ==== | ||
Line 225: | Line 225: | ||
Un LED RGB este compus din 3 diode care emit culori diferite: una roșie, una verde și una culoare albastră. Cu acest LED se poate obține orice culoare printr-o combinație de intensități pe fiecare diodă în parte. | Un LED RGB este compus din 3 diode care emit culori diferite: una roșie, una verde și una culoare albastră. Cu acest LED se poate obține orice culoare printr-o combinație de intensități pe fiecare diodă în parte. | ||
Cele trei LED-uri sunt conectate astfel: | Cele trei LED-uri sunt conectate astfel: | ||
- | * ''OC1A'' este asociat timer-ului 1 (pinul ''PB1'' sau pinul 9 de pe Arduino) și controlează LED-ul ''roșu''. | + | * ''OC1A'' este asociat timer-ului 1 (''PB1'' sau pinul 9 de pe Arduino) și controlează LED-ul ''roșu''. |
- | * ''OC1B'' este asociat timer-ului 1 (pinul ''PB2'' sau pinul 10 de pe Arduino) și controlează LED-ul ''verde''. | + | * ''OC1B'' este asociat timer-ului 1 (''PB2'' sau pinul 10 de pe Arduino) și controlează LED-ul ''verde''. |
- | * ''OC2A'' este asociat timer-ului 2 (pinul ''PB3'' sau pinul 11 de pe Arduino) și controlează LED-ul ''albastru''. | + | * ''OC2A'' este asociat timer-ului 2 (''PB3'' sau pinul 11 de pe Arduino) și controlează LED-ul ''albastru''. |
În funcție de LED-ul RGB folosit, LED-urile individuale se pot conecta în modul catod comun/"active-high" (LED-ul este aprins atunci cand pinul aferent este HIGH, si stins atunci cand pinul este LOW) sau anod comun/"active-low" (LED-ul este aprins atunci cand pinul aferent este LOW, si stins atunci cand pinul este HIGH). În ambele cazuri, se folosește câte o rezistență de limitare a curentului pentru fiecare culoare. | În funcție de LED-ul RGB folosit, LED-urile individuale se pot conecta în modul catod comun/"active-high" (LED-ul este aprins atunci cand pinul aferent este HIGH, si stins atunci cand pinul este LOW) sau anod comun/"active-low" (LED-ul este aprins atunci cand pinul aferent este LOW, si stins atunci cand pinul este HIGH). În ambele cazuri, se folosește câte o rezistență de limitare a curentului pentru fiecare culoare. | ||
Line 271: | Line 271: | ||
===== 4. Exerciții ===== | ===== 4. Exerciții ===== | ||
- | === Task 0 (Întreruperi și butoane) === | + | === Task 0 (întreruperi / butoane) === |
Folosiți întreruperi externe (INT și/sau PCINT) pentru a detecta apăsarea unui buton conectat la ''PD2'' (pin 2) și a unuia conectat la ''PD4'' (pin 4). Modificați starea unui LED conectat la ''PD7'' (pin 7) în ISR. | Folosiți întreruperi externe (INT și/sau PCINT) pentru a detecta apăsarea unui buton conectat la ''PD2'' (pin 2) și a unuia conectat la ''PD4'' (pin 4). Modificați starea unui LED conectat la ''PD7'' (pin 7) în ISR. | ||
Line 300: | Line 300: | ||
=== Task 1a (LED RGB) === | === Task 1a (LED RGB) === | ||
- | Conectați un LED RGB la pinii 9, 10, 11 de pe Arduino folosind câte o rezistență de 330ohm și rulați programul de mai jos: | + | Conectați un LED RGB catod comun la pinii 9, 10, 11 de pe Arduino folosind câte o rezistență de 330ohm și rulați programul de mai jos: |
* Observați modificarea culorii LED-ului | * Observați modificarea culorii LED-ului | ||
Line 345: | Line 345: | ||
</file> | </file> | ||
- | === Task 1b (LED RGB/extra) === | + | === Task 1b (LED RGB / HSV) === |
Modificați programul folosind functia //setLedColorHSV//: | Modificați programul folosind functia //setLedColorHSV//: | ||
* Funcția //setLedColorHSV// permite modificarea culorii folosind reprezentarea alternativă HSV (Hue Saturation Value), fiind mai ușor apoi de modificat culoarea, saturația și intensitatea luminoasă. {{:pm:lab:lab3_2021:hsv.txt|setLedColorHSV}} | * Funcția //setLedColorHSV// permite modificarea culorii folosind reprezentarea alternativă HSV (Hue Saturation Value), fiind mai ușor apoi de modificat culoarea, saturația și intensitatea luminoasă. {{:pm:lab:lab3_2021:hsv.txt|setLedColorHSV}} | ||
+ | * Setați valorile pentru saturație (s) și intensitate (v) pe 1 și modificați culoarea (h) în intervalul 0-360 | ||
Pentru a urmări corespondența dintre cele 2 reprezentări (RGB și HSV) există selectoare de culori precum: | Pentru a urmări corespondența dintre cele 2 reprezentări (RGB și HSV) există selectoare de culori precum: | ||
Line 359: | Line 360: | ||
- | === Task 2 (LED RGB/Serial) === | + | === Task 2 (LED RGB / Serial) === |
Scrieți un program care primește comenzi pe serială (USART) și setează o anumită culoare a LED-ului RGB, în funcție de valorile primite pentru fiecare canal, separate prin virgulă (R,G,B). Formatul de tip [[https://en.wikipedia.org/wiki/Comma-separated_values|CSV]] reprezintă o variantă simplă și flexibilă (deși mai puțin eficientă decât transmiterea în format binar, sub formă de octeți) de codificare a datelor trimise pe serială. | Scrieți un program care primește comenzi pe serială (USART) și setează o anumită culoare a LED-ului RGB, în funcție de valorile primite pentru fiecare canal, separate prin virgulă (R,G,B). Formatul de tip [[https://en.wikipedia.org/wiki/Comma-separated_values|CSV]] reprezintă o variantă simplă și flexibilă (deși mai puțin eficientă decât transmiterea în format binar, sub formă de octeți) de codificare a datelor trimise pe serială. | ||
Line 393: | Line 394: | ||
- | === Task 3 (Servo/sweep) === | + | === Task 3 (Servo / sweep) === |
Conectați un servo la pinul 9 și rulați exemplul standard din Arduino, prin care se modifică în mod "continuu" poziția (0-180) | Conectați un servo la pinul 9 și rulați exemplul standard din Arduino, prin care se modifică în mod "continuu" poziția (0-180) | ||
Line 413: | Line 414: | ||
void setup() { | void setup() { | ||
myservo.attach(9); // attaches the servo on pin 9 to the servo object | myservo.attach(9); // attaches the servo on pin 9 to the servo object | ||
- | setup_interrupts(); | ||
// test led | // test led | ||
DDRD |= (1 << PD7); | DDRD |= (1 << PD7); | ||
Line 436: | Line 436: | ||
</hidden> | </hidden> | ||
- | === Task 4 (Servo/buton) === | + | === Task 4 (Servo / buton) === |
- | Folosind întreruperile de la **Task 0**, modificați incremental poziția servomotorului (0-180): | + | Folosind întreruperile de la **Task 0**, modificați incremental poziția servomotorului (0-180) |
| | ||
{{:pm:lab:lab3_2021:button_servo.png?600|}} | {{:pm:lab:lab3_2021:button_servo.png?600|}} | ||
Line 444: | Line 444: | ||
* Atenție la limite (min, max). Depășirea acestora poate avaria servomotorul. | * Atenție la limite (min, max). Depășirea acestora poate avaria servomotorul. | ||
* Dacă lucrați pe placă, folosiți debouncing pentru a obține o funcționare corectă (o apăsare va incrementa o singură dată poziția) | * Dacă lucrați pe placă, folosiți debouncing pentru a obține o funcționare corectă (o apăsare va incrementa o singură dată poziția) | ||
- | * Există și servomotoare care folosesc un alt interval de comenzi (ex. 700-2300), se poate folosi funcția //writeMicroseconds// pentru a controla direct durata pulsului. [[https://www.arduino.cc/en/Reference/ServoWriteMicroseconds|Servo.writeMicroseconds]] | + | * Există și servomotoare care folosesc un alt interval de comenzi (ex. 0.7ms-2.3ms), se poate folosi funcția //writeMicroseconds// pentru a controla direct durata pulsului. [[https://www.arduino.cc/en/Reference/ServoWriteMicroseconds|Servo.writeMicroseconds]] |
<hidden> | <hidden> |