Avtor: mag. Vladimir Mitrović
E-pošta: vmitrovic12@gmail.com
2020_281_44
V nadaljevanju te serije člankov se bomo tokrat pozabavali z modulom KY-022. Čeprav gre za modul, na katerem je senzor z digitalnim izhodom, ga nismo uvrstili v skupino modulov z digitalnimi izhodi, ker se uporablja v posebne namene in smo zanj pripravili poseben program.
KY-022
Infrardeči senzor (KY-022 InfraredReceiver Module, slika 106)
Na KY-022 modulu se nahaja integrirano vezje VS1838B. Takšna ali podobna integrirana vezja se običajno uporabljajo v TV sprejemnikih in drugih napravah, ki jih imamo možnost upravljati z daljinskimi upravljalniki. V integriranem vezju sta infrardeči senzor in selektivni ojačevalnik, samo ohišje senzorja pa je izdelano iz takšnega materiala, ki prepušča infrardečo svetlobo, vidni del svetlobnega spektra pa bolj ali manj učinkovito zaduši. Pri vezju VS1838B je selektivni ojačevalnik nastavljen na frekvenco 38 kHz, kar pomeni, da bo znalo integrirano vezje iz množice svetlobnih signalov, ki jih zajame, izločiti infrardečo svetlobo, ki je modulirana s signalom frekvence 38 kHz. Ko zazna tak signal, bo napetost izhodnega priključka S padla na 0 V (logično nič, LO); brez signala pa bo izhodna napetost 5 V (logično ena, HI). Na KY-022 modulu imamo tudi LEDico L, ki zasveti takrat, kadar je senzor aktiviran, oziroma kadar je izhod v stanju “0”.
Ta vsebina je samo za naročnike
Daljinski upravljalniki pošiljajo sporočila sprejemnikom z različnimi načini kodiranja nosilnega vala frekvence 38 kHz (ali katere druge frekvence), o čemer smo veliko pisali v člankih Daljinski upravljalniki (1): Preberimo IC sporočilo! in Daljinski upravljalniki (2): Pošljimo IC sporočilo!, ki sta bila objavljena pred kakimi desetimi leti v reviji Svet elektronike, številka 172 in 173.
Delovanje modula KY-022 bomo preizkusili v vezju, narisanem na shemi, ki jo prikazuje slika 107.
Vezje sestavljata dve Arduino UNO ploščici in trije KY moduli:
- Arduino UNO 1 je oddajnik, ki pošilja ustrezno moduliran infrardeči žarek svetlobe s pomočjo IR diode z modula KY-005;
- Arduino UNO 2 je sprejemnik, ki sprejema ni obdeluje infrardeči žarek svetlobe s pomočjo modula KY-022, dekodira vpisano informacijo in na podlagi te informacije prižiga ali ugaša segmente RGB diode na modulu KY-016.
Arduino UNO 1 je povezan z osebnim računalnikom prek USB priključka, prek katerega se hkrati napaja in vzdržuje komunikacijo z emulatorjem terminala. Prek emulatorja terminala lahko pošiljamo ukaze s pritiski na tipke “r”, “g”, “b” in “0”. Te ukaze program nato modulira, “vdela” v pravokotni nosilni signal frekvence 38 kHz. Uporabljen je najenostavnejši način kodiranja: našteti ukazi bodo po vrsti povzročili na priključku “~10” impulze s frekvenco 38 kHz, ki bodo trajali 40, 60, 80 in 100 ms, IR dioda na modulu KY-005 pa jih bo potem v obliki infrardečega svetlobnega žarka poslala v okoliški prostor.
Na Arduino UNO 2 sta povezana dva KY modula: KY-022 in KY-016. KY-022 bo sprejel infrardeči žarek oddajnika in ga pretvoril v negativne impulze s trajanjem 40, 60, 80 in 100 ms na izhodnem priključku “S”, oziroma priključku “2” Arduino ploščice. Program mora ugotoviti prisotnost teh impulzov in izmeriti njihovo dolžino, potem pa na osnovi tega prižgati po vrsti rdeči, zeleni ali modri segment RGB diode, oziroma vse ugasniti, če je čas sprejetega impulza 100 ms. Arduino UNO 2 se lahko napaja iz prvega Arduino modula (črtkane povezave) ali na kak drug način.
Program 37in1_prog_14a.bas
Program 37in1_prog_14a.bas je napisan za Arduino UNO 1 (oddajnik). Na začetku beremo datoteko z definicijami Arduino priključkov
$include "Arduino_pins.sub"
in definiramo priključek “~10” kot vhodni priključek
Config Arduino_pin#10 = Input
Na prvi pogled je to v nasprotju z običajnim načinom koriščenja priključka “~10”, ki mora biti izhodni. Mi bomo ta priključek uporabili tudi kot OC1B izhod Timer1, ustrezno konfiguriran časovnik pa bo na tem priključku dajal impulze frekvence okrog 38 kHz:
Config Timer1 = Timer , Prescale = 1 , Compare_b = Toggle , Clear_timer = 1 Stop Timer1
Timer1 poženemo v podprogramu Start_38khz
Start_38khz: Compare1a = 210 - 1 Start Timer1 Timer_flag = 1 Return
ustavimo pa v podprogramu Stop_38khz:
Stop_38khz: Stop Timer1
Potem, ko ustavimo časovnik, moramo še zagotoviti, da izhodni priključek ne ostane v stanju “1”, ker bi v tem primeru IR dioda na KY-005 modulu brez potrebe ostala prižgana in bi ves čas svetila. Izhodno stanje OC1B izhoda Timera1 ne moremo neposredno prebrati, lahko pa ga posredno prek vhodnega bita PIND.2 PD2 priključka, oziroma prek njegovega alternativnega imena, Arduino_pin#10. Če ugotovimo, da je ta priključek ostal v stanju “1”, bomo programsko povzročili navidezni CTC dogodek in ga tako postavili v stanje “0”:
If Arduino_pin#10 = 1 Then Tccr1c.foc1b = 1 EndIf Timer_flag = 0 Return
Več o tem smo pisali v analizi programa 37in1_prog_5.bas (Svet elektronike 279). V glavni programski zanki program sprejema sporočila, ki jih prek serijskega kanala dobiva iz emulatorja terminala. Ko sprejme neko sporočilo, ga program natančno analizira v podprogramu Cmd_sub:
Do Cmd = Inkey() IfCmd<> 0 Then GosubCmd_sub EndIf Loop
Če je na primer sprejet ukaz “r” ali “R”, bo program pognal Timer1 za 40 ms:
Cmd_sub: IfChr(cmd) = "r" OrChr(cmd) = "R" Then Gosub Start_38khz Waitms 40 Gosub Stop_38khz Waitms 20 Print "red"
Za ostale dovoljene ukaze, “g” ali “G”, “b” ali “B” in “0”, bo program pognal Timer1 za 60, 80 ali 100 ms, prav tako, kot je bilo zamišljeno.
Program 37in1_prog_14b.bas
Program 37in1_prog_14b.bas je napisan za Arduino UNO 2 (sprejemnik). Na začetku preberemo datoteko z definicijami Arduino priključkov
$include "Arduino_pins.sub"
in definiramo vhodne in izhodne priključke
Config Arduino_pin#2 = Input Config Arduino_pin#11 = Output Config Arduino_pin#12 = Output Config Arduino_pin#13 = Output
Logična “1” na izhodnih priključkih po vrsti vključuje rdeči, zeleni in modri segment RGB diode. Na začetku so vsi izhodni priključki v stanju “0”, zato je LEDica ugasnjena. Program v glavni programski zanki nadzira stanje vhodnega priključka z ukazom Debounce:
Do T_ms = 25 Debounce , Arduino_pin#2 , 0 , T_sub , Sub ...
Tehnično sicer Debounce tu ni potreben, ker na vhodni priključek ni priključeno mehansko stikalo ali tipka, zato tudi ne pričakujemo vklopnih in izklopnih pojavov. Vendar pa ima Debounce vgrajeno dodatno logiko, ki zagotavlja, da se “vsak pritisk na tipko” (v tem primeru vsako aktiviranje senzorja) registrira samo enkrat. Ustrezen podprogram T_sub bo izmeril, koliko milisekund je bil senzor aktiviran:
T_sub: While Arduino_pin#2 = 0 Waitms 1 IncrT_ms IfT_ms> 200 Then Exit While EndIf Wend Return
Izmerjeno trajanje impulza je zapisano v spremenljivko T_ms, katere vrednost se preverja v glavni programski zanki. Če je na primer izmerjen čas trajanja 39-41 ms, bo program postavil Arduino_port#13 v stanje “1” in s tem vključil rdeči segment RGB diode:
Do ... IfT_ms>= 39 AndT_ms<= 41 Then Arduino_port#13 = 1 EndIf ...
S podobnim preverjanjem se bosta pri impulzih, ki trajajo 59-61 in 79-81 ms vključila zeleni in modri segment, pri impulzu, ki traja 99-101 ms, pa bodo vsi segmenti ugasnili:
IfT_ms>= 99 AndT_ms<= 101 Then Arduino_port#11 = 0 Arduino_port#12 = 0 Arduino_port#13 = 0 EndIf Loop
Pri kakršnemkoli drugem izmerjenem času ne bo program naredil ničesar. Tu je morda še treba razložiti, zakaj je začetna vrednost spremenljivke T_ms 25 in ne 0. Vzrok je ukaz Debounce, saj ta preverja stanje vhodnega priključka dvakrat z razmakom 25 ms: zaradi tega bo od trenutka, ko je bila prvič zaznana sprememba na vhodnem priključku, ko se je stanje spremenilo na “0”, do trenutka, ko bo podprogram T_sub začel meriti trajanje tega stanja, preteklo natanko 25 ms. Če z ukazom ConfigDebounce spremenite privzeto zakasnitev ukaza Debounce, je treba začetno vrednost spremenljivke T_ms uskladiti s to zakasnitvijo.
V obdobju prvih testiranj se je nepričakovano izkazalo, da programi delujejo zelo nezanesljivo, kljub temu, da sta bila oddajna IR dioda in IR senzor med sabo oddaljena le deset centimetrov. Končno se je pokazalo, da vir problemov ni niti v konceptu samega prenosa, niti v programih, ampak v dejstvu, da je bila “testna oprema” postavljena neposredno pod svetilko: takoj, ko sem IR senzor zasenčil, je vse začelo delovati tako, kot je bilo zamišljeno. Še več, na sprejemni strani so bili odčitki izmerjenih časov točno 40, 60, 80 ali 100 ms in zato v programu predvidena toleranca od ±1 ms sploh ni bila potrebna. Z oddaljevanjem oddajnika od sprejemnika je seveda treba pričakovati povečano število napak pri sprejemu; to bi lahko rešili s ponavljanjem vsakega ukaza 3-5 krat in seveda z uporabo bolj naprednih tehnik modulacije signala.
Opombe: V tem članku so programi predstavljeni zelo površno; za popolno razumevanje delovanja programa je treba vstopiti v programsko kodo in analizirati celotne programe. Datoteko Arduino_pins.sub z definicijami priključkov pri Arduino UNO, kakor tudi programe37in1_prog_14a.bas in 37in1_prog_14b.bas, lahko brezplačno dobite v uredništvu revije Svet elektronike.
Barduino-23