PWM képes kimenet használata

A PWM kimenetet azért találták ki, hogy ne csak kétféle állapotot (feszültséget) lehessen beállítani egy kimeneten.
Ha csak digitális kimenetünk van, akkor a világítást bekapcsolhatjuk vagy kikapcsolhatjuk, de pl. nem tudunk félhomályt beállítani a szobában, pedig ez is nagyon kellene romantikus pillanatokban! Szerencsére van “digitális” megoldás a problémára. Ha gyorsan ki és bekapcsolgatjuk a világításunkat, akkor a szemünk kb. 50-100Hz felett már nem képes követni az eseményeket, folyamatos de halványabb fénynek érzékeli a villogást. Egy villanymotor pl. úgy reagál ha kapcsolgatják a működtető feszültségét, hogy kissebb fordulatszámmal forog. Persze a világítás vagy a motor kapcsolgatásához nem használhatunk relét, hiszen az nem tud ilyen gyorsan működni. Valamilyen elektronikus teljesítmény kapcsolóra lesz szükségünk, pl. vehetünk a boltban MOSFET tranzisztor, ami erre a célra tökéletes.
Tehát a PWM jó lesz nekünk. Nem kell mást tenni a kimenettel, mint a ki és bekapcsolások idejének arányát változtatni. Az Arduino ezt 256 fokozatban tudja megtenni. A ki és bekapcsolgatások frekvenciája is állítható, alap helyzetben úgy emlékszem 400Hz, de ehhez még soha nem kellett hozzányúlnom.

Lássunk végre a egy programkódot:

Arduino C

analogWrite(x,15);       //az x kivezetés PWM képes és 15-re állítottuk x-et 0-255 intervallumban adhatjuk meg
 
A PWM képes kimenetre közvetlenül írhatsz a digitalWrite() utasítással is. Pl:

digitalWrite(5,HIGH)    //ennek az utasításnak az eredménye azonos az analogWrite(5,255) utasítással
 
BASCOM

Ez itt kicsit bonyolultabb mint C-ben. Elsőként azt kell tudnunk, hogy a hardveresen megvalósított pwm kimenetet a chip-be beépített timerek vezérlik, ezért elsőkét a timereket kell beállítani. Minden timerhez tartozik két kimenet, amit vezérelni tud. A chip kivezetés listájából derül ki, hogy melyik kimenetért melyik timer a felelős. Példaként az ATmega328 kivezetéseinek jelölését nézzük:

TIMER0:
OC0A (PD6) chip 12-es láb Arduino-n digital pin 6
OC0B (PD5) chip 11-es láb Arduino-n digital pin 5
TIMER1:
OC1A (PB1) chip 15-es láb Arduino-n digital pin 9
OC1B (PB2) chip 16-es láb Arduino-n digital pin 10
TIMER2:
OC2A (PB3) chip 17-es láb Arduino-n digital pin 11
OC2B (PD3) chip 5-es láb Arduino-n digital pin 3

Ha ezen kimenetek valamelyikét PWM módban akarod használni, akkor a megfelelő TIMER-t kel beállítani. Ehhez a következő sort kell beilleszteni a programba:

Cinfig Timer1 = PWM, Compare A PWM = Clear Down,
Compare B PWM Clear Down, Prescal = 64

Ebben a parancsban több dolog is magyarázatra szorul. A Config Timer1=PWM rész a megfelelő timer pwm felhasználását jelenti. Ekkor a timer már másra nem használható. A Compare A PWM részben a timerhez tartozó „A” komparátort állítjuk be úgy, hogy amikor a timer elért egy bizonyos értéket, akkor a kimenet jelét 1-ről 0-ra ejti. Nyilván azt a bizonyos elért értéket kell majd a programban beállítanunk. Lehet azt is, hogy a megadott értéknél kerüljön a kimenet 1-be, akkor azt kell írnunk, hogy Compare A PWM Clear Up. A másik kimenethez a másik, B jelű komparátor tartozik. Ha csak egyik vagy másik kimenetet akarjuk használni, akkor a kimenethez tartozó részt egyszerűen kihagyjuk. Pl. ha csak a B kimenet fog kelleni:

Cinfig Timer1 = PWM, Compare B PWM Clear Down, Prescal = 64

A Prescale=64 a timer bemeneti előosztóját állítja be. Gyakorlatilag ezzel a PWM jel frekvenciáját állíthatjuk be. A PWM jel frekvenciája így számítható ki: fpwm=fclk / (N*256), ahol fpwm a pwm frekvencia, fclk a chip frekvenciája, N pedig a PRESCALE rész mögé írt érték. Utóbbi lehet: 1,8,64,256,1024. Ha Prescale=1-et írunk, akkor a lehető legnagyobb a frekvencia. Ha jól sejtem ennek a beállításnak az értékei akár chip függők is lehetnek, ezért itt kelleni fog az adatlap. ATmega328 esetén a maximális érték 1024. Ha pl. a chip-re egy 16Mhz-s kvarc kristályt teszünk, akkor a frekvenciája fclk=16Mhz, és fpwm-re 61,02315Hz adódik. A Prescal=64 éerékre 976,56 Hz vagyis kb. 1Khz a PWM frekvencia! Megmértem frekvencia mérővel a kimenet PWM frekvenciáját és a következő értékeket kaptam:

Prescale (N)frekvencia
131,37 Khz
83,921 Khz
64490,2 Hz
256122,5 Hz
102430,63 Hz

És most lássuk, hogyan állítjuk be a chip kiválasztott kimenetén a PWM értékét. Egyszerűen csak ennyit kell írnunk Pl.:
Pwm1a=128      ’ekkor az OC1A kimenetet (chip 15-ös láb, Arduino-n digital pin 9)
                            ’kitöltési tényezőjét állítjuk 128/256.
Pwm2b=10        ’ekkor az OC2B kimenetet (chip 5-es láb Arduino-n digital pin 3)
                            ’kitöltési tényezőjét állítjuk 10/256-ra.

Ha működés közben szeretnél látni egy teljes példa programot ami a PWM kimeneteket vezérli, akkor kattints ide!


A kimenetet így nem analóg módon tudjuk szabályozni, csak ki be kapcsolatuk. Ha ténylegesen analóg feszültség értéket szeretnénk látni a kimeneten, akkor kössünk rá egy kondenzátort és ellenállást párhuzamosan. A kondenzátor a kimenet 1 értékénél feltöltődik, amit az ellenállás azonnal meríteni kezd. A kapacitás és ellenállás értékek megfelelő értékének kiválasztásával feszültség szintet fogunk kapni, de ez kicsit “fűrészfogas” lesz. Nekem ilyesmi még soha nem kellett, így nincs tapasztalatom. Létezik olyan kész áramkör modul is, ami konkrét feszültséget állít elő, de ez már más elven fog működni. Ilyen például az MCP4725 modul, ami I2C buszon kommunikál az Arduino-val és 12 bites felbontással (4096 lépésben) képes analóg feszültséget varázsolni a kimenetére. Ha ez a modul érdekel, akkor kattints ide!

Készítettem egy olyan demo programot, amit esetleg mások is sikerrel felhasználhatnak. Ez a program egy függvény, ami megadható bemenetet figyel, és az egyik kiválasztott pwm képes kimenetet vezérli. A bemenetre kötött nyomógombbal lehet a világítást fel-le kapcsolni, fényerőt szabályozni. Ha lekapcsolod a világítást, akkor fokozatosan csökkenti a fényerőt, és tartja egy darabig minimumon stb. A forráskódok menüpont alatt más hasonló hasznos programocskákat is elhelyeztem.

Készítettem egy lakás világítás vezérlő programot, ami PWM kimeneteket használ a fényerő beállításra. Igen bonyolult és áttekinthetetlen program lett, mert egyetlen Arduino (illetve ATmega328 chip-el) több szoba világítását is vezérlem, és ezeknek egy időben kell működniük, amit nehezen tudtam megoldani. Azonban érdemes lehet később visszatérni erre a programra. Csak nyomógombok és led-ek vannak benne.

Bár tökéletesen működő valódi analóg kimenetünk nincs, de analóg bemenet van. Meg akarod ismerni a működését? Kattints ide!

Ha timer-ek működéséről szeretnél még többet tudni, és érdekel, hogyan lehet beállítani működésüket a vezérlő belső regisztereivel, vagy szeretnéd a timereket időzítési feladatokra, led villogtatásra, időnként lefutó programrészek indítására használni, akkor kattints ide, és olvasd el az erről is szóló, sokkal részletesebb leírást!

Mennyire volt hasznos amit olvastál? Értékelés után szövegesen is leírhatod megjegyzéseidet és véleményedet!

Kattints egy csillagra az értékeléshez!

Szövegesen is leírhatod véleményedet! Ha kérdésed van, ne felejtsd el megadni az email címedet!