Sunteți pe pagina 1din 7

Textul si imaginile din acest document sunt licentiate

Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Codul sursa din acest document este licentiat
Public-Domain
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino software PWM
Ce este PWM ?
Termenul de PWM provine din limba engleza de la Pulse Width Modulation ceea ce inseamna
Modulatia Pulsurilor in Lungime si este o tehnica de a simula un semnal analogic folosindu-te de un
semnal digital.
Semnalul digital poate lua doar stari! "# sau "$$ % &'( sau &)( % *+ sau )+. ,n semnal
PWM te a-uta sa obtii o multime de valori cuprinse intre * si )+. .e exemplu poti obtine .*+ ceea ce
inseamna ca poti a-usta luminozitatea unui L/. sau viteza de rotatie a unui motor.
Semnalele PWM sunt utile in urmatoarele situatii! atunci cand vrei sa creezi -ocuri de lumini
daca ai la dispozitie o multitudine de L/.-uri sau matrici0 atunci cand vrei sa variezi viteza de rotatie a
unui motor sau cand vrei sa controlezi unghiul unui servomotor. 1m enumerat situatiile des intalnite
dar pot exista si altele! daca doresti sa controlezi automat temperatura unei camere si sa folosesti un
element de incalzire al carui raspuns sa fie proportional cu semnalul PWM0 ori doresti sa produci sunete
de frecvente diferite folosindu-te de un difuzor sau vrei sa a-ustezi automat tensiunea unei surse de
alimentare.
Semnalele PWM sunt foarte utile in diverse situatii iar placa 1rduino nu duce lipsa de aceasta
functie. " placa 1rduino ,#" poate genera pana la 2 semnale PWM prin pinii 30 *0 20 40 ') si ''
deoarece microcontroller-ul este echipat cu un modul hard5are special care se ocupa exclusiv de aceste
semnale.
Pentru a afla mai multe detalii despre metoda PWM acceseaza lin6-urile de mai -os!
http!77arduino.cc7en7Tutorial7PWM8.,x91W:l:uSo
http!77arduino.cc7en7;eference7analogWrite8.,x9$bvl:uSo
http!775eb.cecs.pdx.edu7<gerr=7class7/1S'4417topics7pdf7PWM:output:1rduino.pdf
Totusi placa 1rduino poate genera pana la 2 semnale si sunt cazuri cand doresti sa generezi un
numar mai mare. Spre exemplu un hexapod are un numar foarte mare de servomotoare care il pun in
miscare0 iar un robot biped a-unge pana la 3 de servomotoare care concomitent lucreaza si il a-uta sa
isi mentina echilibrul.
>n situatiile de mai sus cei 2 pini PWM sunt insuficienti asa ca vei avea nevoie de mai multi. 1ici
iti vine in a-utor o tehnica de a genera semnale PWM nu hard5are ?folosindu-te de cei 2 pini@ ci prin
soft5are. 1sta inseamna ca0 teoretic0 orice pin digital de intrare7iesire de pe placa 1rduino poate genera
semnale PWM si asta ti-ar creste semnificativ numarul de pini.
http://www.robofun.ro/forum
.e ce teoretic si nu practic A Se pare ca metoda soft5are PWM este mai greu de inteles si putin
mai complexa. .aca prin metoda hard5are PWM ?cei 2 pini enumerati mai sus@ te foloseai de cateva
functii si instructiuni0 la metoda soft5are PWM este necesar sa scrii linie cu linie codul din spatele
functiilor.
Cum generez un semnal PWM cu placa Arduino ?
/xemplu! Cum pot sa comand un motor brushless cu controller /SC ?/lectronic Speed
Controller@!
#include <Servo.h>
Servo esc;
int throttle = 0;
void setup()
{
Serial.begin(9600);
esc.attach(6);
dela(!");
esc.#rite($0);
dela(%000);
&
void loop()
{
'or (throttle = 0; throttle <=!(9; throttle)) ) {
esc.#rite(throttle);
Serial.println(throttle);
dela(*00);
&
'or (throttle = !(9; throttle >=0; throttle++ ) {
esc.#rite(throttle);
Serial.println(throttle);
dela(*00);
&
&
/xemplul de mai sus te poate a-uta sa controlezi viteza de rotatie a unui motor brushless
folosindu-te de un controller /SC. Controller-ul este responsabil cu intrepretarea semnalului PWM
provenit de la placa 1rduino si alimentarea motorului brushless.
Te vei folosi de libraria Servo pentru a realiza acest lucru.
Prima linie de cod0 directiva preprocesor0 ii spune compilatorului ce librarie vei folosi in
program0 respectiv libraria Servo.h
1 doua linie! se declara obiectul esc adica motorul pe care placa 1rduino il va comanda.
http://www.robofun.ro/forum
1 treia linie! se declara variabila throttle si se initializeaza cu ). +ariabila te va a-uta sa variezi
viteza de rotatie a motorului ?vei vedea mai -os cum@.
>n rutina setup ?@ se initializeaza Monitorul Serial0 se ataseaza motorul esc la pinul 2 ?unul din
cei 2 pini PWM@0 se executa o intarziere de '* milisecunde0 se transmite catre motor un semnal PWM
cu valoarea 3) si se asteapta secunde.
.e ce acest semnal PWM A ;aspunsul este ca /SC-urile ?controller-ul electronic de viteza@
necesita o armare inainte de a porni motorul. 1rmarea ii permite controllerului sa isi calibreze pla-a de
reactie. 1ceasta pla-a poate varia de la controller la controller ?nu exista un standard@ dar poate fi
descoperita usor. Pla-a de reactie inseamna minimul si maximul pe care il poate atinge motorul.
>n rutina loop?@ se executa o bucla for?@ care incrementeaza variabila throttle de la ) la 'B4 in
pasi de cate o unitate.
Linia esc.write(throttle) transmite motorului viteza de rotatie0 astfel ca la ) motorul nu se
misca deloc iar la 'B4 motorul se roteste cu viteza maxima. Practic bucla for?@ creste treptat viteza de
rotatie a motorului.
,ltimele linii din bucla transmite valoarea vitezei catre Monitorul Serial si introduce o
intarziere de C)) de milisecunde in asa fel incat panta de acceleratie a motorului sa nu fie abrupta.
1 doua bucla for?@ scade treptat viteza motorului in aceeasi maniera ca si prima.
Pentru a afla mai multe detalii despre motoarele brushless si tehnica de comanda a acestora
acceseaza lin6-urile de mai -os!
http!77techvalle=pro-ects.blogspot.ro7)'7)27arduino-control-escmotor-tutorial.html
http!77dronesandrovs.5ordpress.com7)'7''7C7ho5-to-control-a-brushless-motor-esc-
5ith-arduino7
Codul sursa de mai sus este perfect functional si poate fi utilizat cu succes dar exista un
dezavanta- si anume ca poti genera pana la 2 semnale PWM0 ceea ce nu te a-uta foarte mult daca doresti
sa comanzi un numar si mai mare de! motoare de curent continuu0 servomotoare sau L/.-uri.
Cum generez un semnal PWM software ?
Tehnica de generare a semnalului PWM soft5are este putin mai complexa decat exemplul
anterior. La inceput placa porneste cu iesirea PWM in &)( logic. ,rmeaza ca placa 1rduino sa activeze
un timer0 acesta sa contorizeze iar cand se &umple( sau cand a a-uns la capatul contorizarii0 timer-ul sa
genereze o intrerupere.
Ce este o intrerupere A
"rice microcontroller executa un program0 o rutina0 genereaza semnale0 citeste date0 afiseaza
informatii pe un displa=0 comanda o turbina0 s.a.m.d.
>n timpul functionarii programului pot aparea situatii neprevazute. >ata un exemplu! sa
presupunem ca placa 1rduino executa un program care este in mare parte o rutina oarecare. .ar din
cand in cand placa 1rduino trebuie sa raspunda prompt la o intamplare0 la ceva care apare din exterior
sau din interior si sa faca lucrul asta fara sa deran-eze intr-un fel executia programului.
http://www.robofun.ro/forum
;aspunsul pentru acest gen de situatii este sa folosesti intreruperile microcontrollerului. Pentru
fiecare intrerupere nou aparuta sau situatie0 microcontroller-ul sare rapid din executia programului apoi
executa programul special de intrerupere ?intr-un timp foarte rapid@ si apoi se intoarce de unde a plecat
si isi continua treaba de la care a plecat.
>n stilul asta placa 1rduino executa programul principal dar in acelasi timp poate executa si
anumite coduri specifice intreruperii.
>ata un exemplu de generare a unui semnal PWM folosind un timer si o intrerupere!
#include <avr,interrupt.h>
#include <avr,io.h>
,, -inul pe care dori. sa genera. se.nal -/0
#de'ine -/01-23 (
#de'ine -/0142561S278 "0 ,, uS
#de'ine -/01-892:; %0000 ,, uS (%0.s)
#de'ine -/0142561-892:; (int) (-/01-892:; , -/0142561S278)
volatile unsigned int ti.er%1counter = 0;
volatile unsigned int ti.er%1trigger1lo# = !"0;
2S9(42089%1:<=1vect) {
ti.er%1counter));
i'(ti.er%1counter == ti.er%1trigger1lo#) {
digital/rite(-/01-23> ?:/);
& else i'(ti.er%1counter >= -/0142561-892:;) {
ti.er%1counter = 0;
digital/rite(-/01-23> @2A@);
&
4534% = 0;
&
void setup() {
pin0ode(-/01-23> :B4-B4);
420S6% = !<<4:28%; ,, 4i.er % over'lo# interrupt enable
4534% = 0;
&
http://www.robofun.ro/forum
void loop() {
ti.er%1trigger1lo# = !00;
dela(%000);
ti.er%1trigger1lo# = %00;
dela(%000);
ti.er%1trigger1lo# = $00;
dela(%000);
ti.er%1trigger1lo# = *00;
dela(%000);
ti.er%1trigger1lo# = $00;
dela("000);
ti.er%1trigger1lo# = %00;
dela(%000);
&
Cum functioneaza codul A
Primele doua linii0 directivele preprocesor0 includ librariile responsabile cu intreruperile
microcontrollerului 1tmega si registrii acestuia. Mai -os vei vedea cum se acceseaza in mod direct
anumiti registrii din microcontroller si cum se activeaza timer-ul D intreruperea.
1 treia linie! defineste pinul pe care placa 1rduino va genera semnalul PWM. 1 fost ales un pin
pe care nu se poate genera semnal PWM hard5are.
Prin urmatoarele 3 linii se definesc cativa parametrii! primul parametru PWM:T>CE:S>F/ iti
spune ca timer-ul va contoriza pentru *) de microsecunde0 al doilea parametru PWM:P/;>". iti
spune care este perioada totala a semnalului PWM iar al treilea parametru PWM:T>CE:P/;>". se
obtine din raportul celorlalti parametrii si iti arata cand se va reseta semnalul PWM din &'( logic in
&)( logic.
,rmatoarele linii initializeaza variabile dintre care una va mentine valoarea contorului
?timer-ul@ iar cealalta mentine valoarea la care semnalul PWM sa isi schimbe nivelul logic.
$unctia >S; este apelata ori de cate ori timer-ul genereaza o intrerupere adica ori de cate ori
timer-ul a terminat de contorizat. La fiecare intrerupere gestionata de catre microcontroller se
incrementeaza timer:counter.
Pentru inceput tensiunea pe pinul B PWM este de )+. 1poi se testeaza daca variabila
incrementata este egala cu parametrul timer:trigger:lo5. .aca este egala atunci pinul B este in
continuare mentinut cu )+.
Se continua incrementarea timp in care tensiunea pinului PWM este de )+. Tensiunea se
schimba in *+ atunci cand variabila incrementata este mai mare sau egala decat parametrul
PWM:T>CE:P/;>".. Tensiunea ramane la *+0 contorul de timp este resetat si din nou incrementat.
.in nou se incrementeaza contorul la fiecare intrerupere0 timp in care tensiunea pe pinul PWM
ramane la *+. Tensiunea se schimba in )+ atunci cand se produce egalitatea intre variabila incrementata
si parametrul timer:trigger:lo5.
>n acest fel s-a generat un semnal PWM folosindu-te de un timer si o intrerupere.
>n rutina setup?@ se initializeaza pinul PWM0 intreruperea timerului prin scrierea bitului
T">/ cu valoarea logica &'( din registrul T>MSE ?am mentionat ca vei afla cum se acceseaza in mod
http://www.robofun.ro/forum
direct un registru@ si se reseteaza valoarea contorului pin scrierea registrului TC#T G )%
Pentru a demonstra ca semnalul PWM isi poate schimba factorul de umplere ?lungimea
nivelului &'(@0 in bucla loop?@ se modifica treptat la intervale de secunde valoarea parametrului
timer:trigger:lo5. 1sta inseamna ca nivelele semnalului PWM se vor declansa la momente diferite
?'))0 ))0 3))0 C))0 3))0 ))@.
.aca vrei sa studiezi in detaliu sistemul de intreruperi al microcontrollerului 1tmega3H de pe
placa 1rduino urmeaza lin6-urile de mai -os!
http!77courses.cs.5ashington.edu7courses7csep*2B7')5i7lectures7LectureB.pdf
http!77555.avr-tutorials.com7interrupts7about-avr-H-bit-microcontrollers-interrupts
http!77555.avrfrea6s.net7index.phpA
nameGP#phpIIJfileGvie5topicJtGH4HC3JstartGallJpostda=sG)JpostorderGasc
http!77555.avr-tutorials.com7interrupts7avr-external-interrupt-c-programming
http!77pla=ground.arduino.cc7Code7>nterrupts8.,x9iTvl:uSo
Tot ce iti ramane de facut este sa descoperi cum poti genera mai multe semnale PWM
folosindu-te de aceeasi tehnica soft5are de generare a semnalelor. >n principiu trebuie sa ai in vedere
declararea in plus a unor parametrii0 cate un set pentru fiecare pin PWM si rescrierea rutineri de
intrerupere in asa fel incat sa fie capabila sa gestioneze mai multi pini.
1cest lucru iti da un avanta- pentru ca poti creea miscari complexe cu servomotoare0 poti
controla motoare la viteze diferite ?poti creea o tractiune diferentala in care0 pe scurt0 rotile unei masini
trebuie sa se roteasca la viteze diferite atunci cand masina vireaza intr-o curba@ sau poti creea un -oc de
lumini cu fiecare L/. controlat independent.
http://www.robofun.ro/forum