PWM - Lassabban vagy gyorsabban?

A DM-es részben sokszor szórakoztunk azzal, hogy a ledek fényességét az analogWrite-al állítottuk. Valójában ez nem kisebb megy nagyobb villanyt tesz a portra, hanem nagyon gyorsan be-ki kapcsolgatja.

Ezt a trükköt úgy nevezik, hogy impulzus-szélesség moduláció, na mondd utánam gyorsan: impulzus-szélesség moduláció, impulzus-szélesség moduláció, jajj! Ennek az angol neve Pulse Width Modulation, ezért a PWM sokkal hálásabb rövidítés, mint az impulzus-szélesség moduláció.

De mi az az impulzus?

Az impulzus egy rövid jelecske: bekapcsolás, majd kikapcsolás. Ha becsengetsz valahova, akkor a csengő egy impulzust kap.

Mi az az impulzus-szélesség?

Azt jelenti, hogy milyen hosszú ideig tart egy impulzus. Ha becsengetsz valahova, lehet, hogy röviden nyomod meg a csengőt: ilyenkor úgy 500ms-es impulzust produkálsz. Ha el sem engeded 5 másodpercen át, akkor meg 5 másodperc az impulzus szélessége.

Mi az a moduláció?

A moduláció azt jelenti, hogy valamit megváltoztatni.

Mi az a PWM?

Na akkor tegyük össze: ez azt jelenti, hogy impulzusok, amiknek a hosszát megváltoztatjuk. Valahogy így:

A PWM Forrás:pyroelectro.com

Amit itt látunk, az egy idődiagram, azaz egy olyan grafikon, aminek az X tengelye az idő, az Y tengelye pedig a villany. A mikrokontroller be-ki kapcsolja a kimenetét, így egyszer van rajta villany, egyszer meg nincs. Ha több ideig van bekapcsolva, mint kikapcsolva, akkor úgy tűnik, hogy a led erősebben világít. Ha végig be van kapcsolva, akkor teljes fénnyel világít. Ha az idő felében ki, felében be van kapcsolva, akkor meg fél fénnyel világít.

Ez akkor most villog is?

Remek kérdés! Voltaképpen ha mondjuk 50%-on van, akkor ugyanaz az idődiagram, mint amikor szépen villogtatjuk a ledet. Egy a különbség: mi lassan villogtatjuk a ledet, ez a PWM pedig sokkal gyorsabban történik.

Miért nem villog?

Az idődiagram szerint itt be-ki kapcsolgatás van, tehát ez villog. Mégis, úgy tűnt korábban, hogy a dolog nem villog, hanem szépen világít. Most akkor mi van?

Az van, hogy az ember szeme igazából nem tud minden villogást érzékelni. A lassú villogással jók vagyunk, de ha egyre gyorsabban villogunk, akkor egyszercsak a szem kiátlagolja a dolgot. Másodpercenként 25-30 villogástól gyorsabb sebességnél már nem vesszük észre a villogást.

Mit veszünk észre a villogás helyett? A szemünk kiátlagolja, hogy mennyi fényt érzékelt. Ha az idő felében be van kapcsolva, felében ki van kapcsolva a led, akkor azt hisszük, hogy a led 50% fénnyel világít. Ha mondjuk az idő 10%-ában van bekapcsolva, és 90%-ban kikapcsolva, akkor azt hisszük hogy kicsit világít.

A mikrokontrollerünk ezt a trükköt pedig másodpercenként 1000 be-ki kapcsolással csinálja, így jó, hogy nem vettük észre a villogást.

A mozi ezt a trükköt másodpercenként 24 felvillanással csinálja. (Láttál már filmet vetítő mozigépet? Átmegy a fény egy filmkockán, utána egy kis tárcsa eltakarja a fény útját, eközben a következő kockára teker, utána a tárcsa továbbfordul, és az új képkocát világítja meg a fény. Bámulatos, hogy 70 éves technológia, és nincs benne program!)

Nos, hát az analogWrite az pont ezt csinálja nekünk.

Miért nem megy minden porton az analogWrite?

Ezt a gyors PWM dolgot a mikrokontroller belsejében külön kis részegység csinálja, és ilyenből nem tettek bele túl sokat, csak 5 darabot. Ezért csak azokon a portokon megy az analogWrite, amiken van ilyen, ezeket a portokat kis hullámos vonal jelöli a Pololu panelen a port sorszáma alatt.

Hm, de mi van, ha nekem 10 PWM kell? A PWM csak be-ki kapcsolgatás: voltaképpen programból is meg lehet csinálni bármennyi portra. Ez egy nagy for-ciklus, meg sok-sok if, és kész is van. Úgy nevezik ezeket a megoldásokat, hogy szoftveres pwm, vagy soft-pwm, mivel programoból szimuláljuk a PWM működését. Sajnos a soft-pwm nem tud olyan gyors lenni, mint az igazi hardveres pwm, de ledekre, és sok más dologra használható.

Forogjunk lassabban!

Foglaljuk össze hogy mit tudunk! Tehát az analogWrite valójában PWM, ami valójában csak be-ki kapcsolás. Mivel a FET-el is pont be-ki kapcsolni tudunk, így a FET-tel is tudjuk a motor sebességét változtatni! Csak analogWrite kell neki!

Mondjuk, próbáld ki ezt, ez háromféle sebességet csinál:

#define MOTOR 9

void setup() {
    pinMode(MOTOR, OUTPUT);
}

void loop() {
    delay(1000);
    analogWrite(MOTOR,100);
    delay(1000);
    analogWrite(MOTOR,200);
    delay(1000);
    analogWrite(MOTOR,255);
}

Ne feledd, hogy valójában a motor nem kap kevesebb, vagy több villanyt. A motor ugyanúgy 4.5V-ot kap, csak okosan be-ki kapcsolgatva. Pontosan úgy, ahogy az ember szeme kiátlagolja a villogó fényt, a motor (és bármi más mechanikus eszköz) kiátlagolja a hirtelen mozgásokat - és a motor a ráküldött be-ki kapcsolgatás átlagának megfelelő sebességgel forog.

Mi a leglassabb sebesség?

Az analogWrite(MOTOR,0)? Neem, a 0 esetén nincs semennyi impulzus (0 a hossza), így a motor megáll. Akkor az analogWrite(MOTOR,1)? Jó próbálkozás! De nem! Azt fogod tapasztalni, hogy úgy 0..50 között a motor meg se nyikkan - na várjunk, másképp mondom: meg sem mozdul, csak épp nyikkan: egy magas hangú halk visítást hallat.

Miért nem mozdul meg? Azért nem, mert olyan pici a motorra jutó energia átlaga, hogy ez nem elég, hogy legyőzze a motor belső részeiben a súrlódást, és látható elmozdulást produkáljon.

Miért visít? Mert fél! Hehe, nem is. Igaziból egyáltalán semmi baj nincs, csak a PWM jel elég kicsi még, hogy láthatóan megmozdítsa a motort, de arra elég nagy, hogy ici-pici mozdulatot produkáljon: oda-vissza jár a motor tengelye, megtéve szemmel láthatatlan 0.000000001 foknyi fordulatot. Nem megy sehova, de mozog. Ami mozog, az meg lökdösi a levegőt. Ami a levegőt lökdösi, az meg hangot ad. Elvégre is a piezo hangszóró is pont ezt csinálta!

Miért pont ilyen magas hangon visít? Mert a PWM frekvenciája nagyjából 1000Hz - ez pont ez a magas hang. Tekerj vissza a PWM-es animációra! A PWM során a frekvencia nem változik: egy másodperc alatt ugyanannyi impulzus lesz mindig. Csak az impulzusok hossza változik - ebből lesz az "energia", a fény, a forgás, az elmozdulás ezzel arányos.

Feladat: Csinálj nyikorgást!

Csinálj egy for-ciklust, amiben egyre nagyobb értékeket írsz az analogWrite-al. Minden érték után várj úgy legalább 20ms-ot, hogy a motor tényleg elkezdjen olyan sebességgel mozogni.

Mi a PWM?

Egy port okos be-ki kapcsolgatása, ami olyan hatást kelt, mintha tudnánk változtatni a portból kijövő villany nagyságát - így a rákötött led fényerejét, a motor sebességét.