Differences

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

Link to this comparison view

pm:lab:lab3-2023 [2023/03/26 14:26]
alexandru.predescu [4. Exerciții]
pm:lab:lab3-2023 [2023/03/27 11:26] (current)
narcis_florin.caroi [4. Exerciții]
Line 3: Line 3:
  * ~~SHOWSOLUTION~~  * ~~SHOWSOLUTION~~
  */  */
-~~SHOWSOLUTION~~ 
  
-====== Laboratorul 3: Timere. PWM (work in progress) ​======+====== Laboratorul 3: Timere. PWM ======
  
 Acest laborator are ca scop familiarizarea voastră cu lucrul cu întreruperile hardware generate de timer-ele prezente în microcontroller-ul Atmega328p. Vom folosi timer-ele pentru a număra intervale de timp și pentru a genera semnale periodice. Folosind semnale PWM vom controla intensitatea luminoasă a unui LED și poziția unui servomotor. Acest laborator are ca scop familiarizarea voastră cu lucrul cu întreruperile hardware generate de timer-ele prezente în microcontroller-ul Atmega328p. Vom folosi timer-ele pentru a număra intervale de timp și pentru a genera semnale periodice. Folosind semnale PWM vom controla intensitatea luminoasă a unui LED și poziția unui servomotor.
Line 350: Line 349:
  
 ===== 4. Exerciții ===== ===== 4. Exerciții =====
 +{{:​pm:​lab:​schema-intreruperi-pwm.jpeg?​600|}}
 +=== 4.1. Task 0 ===
  
-=== 4.1. Timere ===+Folosind Timer de pe Arduino și operațiile cu regiștri, afișați pe interfața serială un mesaj la alegerea voastră o dată la 5 secunde.
  
 <note tip> <note tip>
 +
 +Timerul de pe Arduino nu poate cronometra perioade atât de lungi. Veți fi nevoiți să afișați mesajul după un anumit număr de perioade, de lungime aleasă de voi. Ex: perioadă de 0.5s (2Hz), afișăm mesajul la fiecare a doua intrare în funcția asociată întreruperii de timer; perioadă de 0.1s (10Hz), afișăm mesajul la fiecare a 10-a intrare.
 +
 Alegerea parametrilor pentru timer pentru setările registrelor:​ Alegerea parametrilor pentru timer pentru setările registrelor:​
  
Line 363: Line 367:
 </​file>​ </​file>​
  
-Dacă frecvența de bază a procesorului este de 16 MHz și prescalerul 256 atunci timerul are frecvența de 62500 Hz deci se va incrementa cu 1 la fiecare 1/62500 Hz = 16 μs. O întrerupere va fi generată când valoarea din timer va fi egală cu cea din registrul OCR1A (31249). 16μs×31250 = 0.5s 
 </​note>​ </​note>​
  
-**Task 1** (1p) Rulați exemplul de mai jos. +=== 4.2. Task 1 ===
-  * Ce mod de funcționare folosește timer-ul? Dar prescaler-ul?​+
  
-<file c> +Folosind codul de la exercițiul anterior, la fiecare 5 secunde veți alterna între două stări de redare a unei melodii pe buzzer-ul din montaj: 
-#define BTN 2 +  * viteză normală și octavă normală 
-#define LED 11+  * viteză dublă (noteDuration / 2) și octavă superioară ​
  
-volatile int ledState = 0;+Creșterea unei octave se realizează dublând frecvența notelor. Pentru redarea unei note veți folosi funcția [[https://​www.arduino.cc/​reference/​en/​language/​functions/​advanced-io/​tone/​|tone()]]. Urmăriți exemplele de pe acest repository [[https://​github.com/​robsoncouto/​arduino-songs|arduino-songs]] și alegeți o melodie.
  
-void setup() { +<note tip> 
-  ​pinMode(BTN, INPUT_PULLUP)+Realizați redarea melodiei în funcția loop() pentru a putea folosi întreruperile generate de timer și pentru a reda continuu melodia. 
-  pinMode(LED,​ OUTPUT); +</note>
-  digitalWrite(LED,​ ledState);​ +
-  +
-  // configurare ​timer +
-  ​cli();​ +
-  TCCR1A = 0; +
-  TCCR1B = 0; +
-  TCNT1  = 0; +
-  OCR1A = 31249; +
-  TCCR1B |= (1 << WGM12);  +
-  TCCR1B |= (1 << CS12); +
-  TIMSK1 |= (1 << OCIE1A); +
-  sei(); +
-}+
  
-ISR(TIMER1_COMPA_vect) { +=== 4.3. Task 2 ===
-  /​*digitalWrite(LED,​ ledState);​ +
-  ledState ​!ledState;​*/​ +
-  PORTB ^(1 << PB3); +
-}+
  
-void loop() +Folosind Timer 0, ciclați led-ul RGB între mai multe culori și mișcați servo-motorul câte 10° la fiecare x secunde ​(alegeți voi o perioadă potrivită pentru urmărirea schimbărilor). Nu uitați de sugestia de la primul task (va trebui să numărați un număr de perioade mult mai scurte decât cea dorită).
-+
-   +
-+
-</​file>​+
  
-{{:​pm:​lab:​lab3_2023:task1.png?​direct&​500|}}+<note warning>​Atenție la limitele de unghi ale servo-motorului. Depășirea acestora poate avaria servomotorul. Verificați ca unghiul să nu depășească intervalul [0°, 180°] (sau [0, pi] pentru cei ce își amintesc cu plăcere de trigonometrie ​:-P). 
 +</​note>​
  
-**Task 2** (2p) Dorim să vizualizăm efectele prescaler-ului asupra frecvenței cu care se aprinde LED-ul. +La acest task veți afișa diverse culori cu ajutorul PWM-ului și veți controla un servo-motor:
-  * Vom folosi butonul legat la PD2 pentru a cicla prin valorile posibile ale prescaler-ului.+
  
 +  * Cu funcția [[https://​www.arduino.cc/​reference/​en/​language/​functions/​analog-io/​analogwrite/​|analogWrite]] veți seta factorul de umplere PWM pentru fiecare culoare
 +  * Exemplu pentru controlul unui servo-motor ce oscilează în intervalul [0°, 180°]
  
-<​solution>​ +<​file>​
-<​hidden>​ +
-<spoiler Rezolvare > +
-<​file ​c> +
-#define BTN 2 +
-#define LED 11 +
-  +
-volatile int ledState = 0; +
-int lastBtnState = 0; +
-  +
-void setup() { +
-  Serial.begin(9600);​ +
-  pinMode(BTN,​ INPUT_PULLUP);​ +
-  pinMode(LED,​ OUTPUT); +
-  digitalWrite(LED,​ ledState);​ +
-  +
-  // configurare timer +
-  cli(); +
-  TCCR1A = 0; +
-  TCCR1B = 0; +
-  TCNT1  = 0; +
-  OCR1A = 31249; +
-  TCCR1B |= (1 << WGM12);  +
-  TCCR1B |= (1 << CS12); +
-  TIMSK1 |= (1 << OCIE1A); +
-  sei(); +
-+
-  +
-ISR(TIMER1_COMPA_vect) { +
-  /​*digitalWrite(LED,​ ledState);​ +
-  ledState = !ledState;​*/​ +
-  PORTB ^= (1 << PB3); +
-+
- +
-int ps = 1; +
-  +
-void loop() +
-+
-  if(digitalRead(BTN) == LOW){ +
-    if(!lastBtnState){ +
-      lastBtnState = 1; +
-      delay(200);​ +
-      TCCR1B &= ~(1 << CS12 | 1 << CS11 | 1 << CS10); +
-      TCCR1B |= ps; +
-      Serial.println(ps);​ +
-      ps += 1; +
-      if (ps > 5){ +
-        ps = 1; +
-      } +
-    } +
-  } else { +
-    lastBtnState = 0; +
-  } +
-+
-</​file>​ +
-</​spoiler>​ +
-</​hidden>​ +
-</​solution>​ +
- +
- +
-**Task 3** (3p) Conectați un buzzer la pinul 9 (PB1). Folosind notele muzicale definite în repo-ul ​ [[https://​github.com/​robsoncouto/​arduino-songs|arduino-songs]] sau biblioteca Melody, implementați un cântec la alegere.  +
-  * Din Arduino IDE: File > Examples > Digital > toneMelody +
-  * Fiecare notă muzicală are asociată o frecvență (de ex. La - 440 Hz) +
-  * Atunci când butonul (legat la PD2) va fi apăsat, notele vor fi ridicate cu o octavă (frecvență dublă a notelor), și vor reveni la normal atunci când butonul nu mai este apăsat. Hint: folosiți intreruperi externe. (1p) +
- +
- +
-{{:​pm:​lab:​lab3_2023:​task2.png?​direct&​500|}} +
- +
-=== 4.2. PWM === +
- +
-** Task 1 ** (2p) Folosind un semnal PWM, modificați progresiv intensitatea luminoasă a LED-ului conectat la Arduino. +
-  * LED-ul trebuie să se aprindă complet la intervale de 2 s. +
-  * Modificați factorul de umplere a semnalului PWM la intervale de 100 ms. +
- +
-** Task 2 ** (2p) Rulați exemplul standard din Arduino prezentat mai jos, prin care se modifică în mod “continuu” poziția unui servomotor în intervalul (0-180). Adăugați un indicator al poziției servomotorului,​ folosind LED-ul conectat la Arduino: +
-  * Implementați un semnal PWM proporțional cu poziția servomotorului (0 = 0%, 180 = 100%) +
-  * Vă puteți folosi de funcția ''​map()''​ din Arduino pentru a translata intervalele:​ [[https://​www.arduino.cc/​reference/​en/​language/​functions/​math/​map/​|map()]] +
- +
-<file c>+
 #include <​Servo.h>​ #include <​Servo.h>​
  
Line 497: Line 402:
  
 void setup() { void setup() {
-  myservo.attach(9);  // attaches the servo on pin to the servo object+  myservo.attach(3);  // attaches the servo on pin to the servo object
   // test led   // test led
   DDRD |= (1 << PD7);   DDRD |= (1 << PD7);
Line 516: Line 421:
 </​file>​ </​file>​
  
-Servomotoarele sunt construite pe baza unui motor DC sau Brushless DC, au angrenaje integrate și un arbore (ax) care poate fi controlat cu precizie. Servo-urile standard permit poziționarea arborelui la diferite unghiuri, de obicei între 0 ș180 de grade. Există și variante cu rotație continuă ce permit modificarea precisă a vitezei de rotație a arborelui. +Bonus : modificați programul folosind functia ​//setLedColorHSV()//
- +
-Servomotoarele hobby ([[https://en.wikipedia.org/wiki/Servo_(radio_control)|Servo]]) sunt în mod uzual comandate printr-un semnal PWM cu frecvența de 50 Hz și perioada semnalului T_on în intervalul 1-2 ms, unde 1.5 ms reprezintă poziția de centru. Practic, semnalul PWM este folosit pentru a codifica și transmite poziția dorită către microcontroller-ul integrat care se ocupă de poziționarea efectivă servomotorului. +
- +
-{{:​pm:​lab:​lab3_task2.png?​direct&​300|}} +
-  ​+
  
 +  * 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 [[https://​colorpicker.me/#​3237b9|Online Color Picker]]
 +{{ :​pm:​lab:​hue-wheel.png?​direct&​400 |}}
 ===== 5. Resurse ===== ===== 5. Resurse =====
  
Line 528: Line 432:
   * Arduino UNO pinout   * Arduino UNO pinout
 {{:​pm:​lab:​uno.jpg?​direct&​600|pinout Arduino UNO}} {{:​pm:​lab:​uno.jpg?​direct&​600|pinout Arduino UNO}}
-  * Responsabili:​ [[alexandru.predescu@upb.ro | Alexandru Predescu]]+ 
 + Responsabili: ​ 
 +  * [[alexandru.predescu@upb.ro | Alexandru Predescu]] 
 +  * [[enedragos99@gmail.com | Dragos Ene]] 
 +  * [[narciscaroi24@gmail.com | Narcis Caroi]]
  
 <​solution>​ <​solution>​
-<​hidden>​https://​www.tinkercad.com/​things/​4VwiEuamlWp</​hidden>​+<​hidden>​{{:pm:​lab:​lab3pm.rar|}}</​hidden>​
 </​solution>​ </​solution>​
  
Line 537: Line 445:
  
   * [[http://​www.nongnu.org/​avr-libc/​user-manual/​group__avr__interrupts.html|AVR Libc - interrupt.h]]   * [[http://​www.nongnu.org/​avr-libc/​user-manual/​group__avr__interrupts.html|AVR Libc - interrupt.h]]
 +  * [[https://​www.arduino.cc/​en/​Tutorial/​BuiltInExamples/​Debounce|debouncing]]
 +  * [[https://​www.arduino.cc/​en/​pmwiki.php?​n=Tutorial/​SecretsOfArduinoPWM|SecretsOfArduinoPWM]]
   * [[https://​en.wikipedia.org/​wiki/​Servo_control|Servo control]]   * [[https://​en.wikipedia.org/​wiki/​Servo_control|Servo control]]
-  * [[https://​www.arduino.cc/​en/​pmwiki.php?​n=Tutorial/​SecretsOfArduinoPWM|SecretsOfArduinoPWM]] 
-  * [[https://​www.arduino.cc/​en/​Tutorial/​BuiltInExamples/​Debounce|debouncing]] 
-  * [[https://​www.arduino.cc/​en/​Reference/​ServoWriteMicroseconds|Servo.writeMicroseconds]] 
- 
pm/lab/lab3-2023.1679829965.txt.gz · Last modified: 2023/03/26 14:26 by alexandru.predescu
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