Shield-A, učni pripomoček za programiranje mikrokontrolerjev (10).
Avtorja: Vladimir Mitrović in Robert Sedak
E-pošta: vmitrovic12@gmail.com
2021-297-40
Nadaljujemo s preučevanjem večbarvnih (RGB) svetlobnih diod, ki so na razvojnem sistemu Shield-A označene z D8-D11 (slika 36 iz prejšnjega članka).
Razmislili smo, kako optimalno povezati njihovih 16 priključkov, hkrati pa kako bi ohranili možnost neodvisnega krmiljenja rdečih, zelenih in modrih čipov znotraj teh diod s čim manj priključki mikrokontrolerja, in opozorili na težave, ki se pojavljajo.
Ko je razvojni sistem Shield-A nameščen na plošči Arduino Uno, so priključki LED-ic D8-D11 povezani s priključki mikrokontrolerja ATmega328P, kot je prikazano na sliki 39.
Zavedamo se, da gre za povezavo, ki doseže polno funkcionalnost le v multipleksiranem načinu. Priključki mikrokontrolerja PB0-PB3 (8-11 v zapisu Arduino) se uporabljajo za izbiro diode, PD5-PD7 (5-7 v zapisu Arduino) pa za izbiro barv. Upori 560 Ω omejujejo tok skozi en RGB diodni čip na približno 6 mA.
Tu moramo še pojasniti izbiro vrednosti teh uporov. Sprva bi rekli, da bi morali za najboljše ravnovesje med barvami imeti enake vrednosti. V ravnovesju verjamemo, da nobena barva ni opazno močnejša ali šibkejša od drugih. Na žalost to ni vedno tako. Prva težava je, da padci napetosti na rdečem, zelenem in modrem čipu niso enaki: padci napetosti na rdečem čipu so okoli 2 V, na modrem okoli 2,8 V in na zelenem nekje med tema vrednostima. Zato bo pri napajalni napetosti 5 V tok skozi rdeči čip 36% močnejši od toka skozi modri čip. In četudi so ti tokovi enaki, obstaja še en, še večji problem: jakosti svetlobe, ki jih oddajajo rdeči, zeleni in modri čipi pri istem toku, niso enake; s poceni RGB diodami “brez imena” so lahko tudi zelo različne. Zato bomo optimalne vrednosti uporov najbolje izbrali eksperimentalno z uporabo preprostega vezja s slike 40.
Ta vsebina je samo za naročnike
Diode na razvojnem sistemu bomo najpogosteje opazovali z majhne razdalje, zato ne želimo, da svetijo premočno. Zato bomo najprej izbrali 2,2 kΩ upore za Rr, Rg in Rb, kjer je tok skozi čipe približno 1 mA. Vklopimo vsa tri stikala in če dobimo (približno) belo svetlobo želene jakosti, smo dosegli to, kar iščemo. Pogostejši primer je, da je ena barva bolj izrazita, nato pa je treba povečati upornost njenega upora. V mojem primeru sta bili rdeča in modra že od začetka dobro uravnoteženi, toda zelena je bila tako intenzivna, da sem moral njen upor povečati na 11 kΩ! Tega ne bi smeli jemati kot splošno priporočilo, ampak se je treba nekoliko potruditi pri optimalni izbiri: doseči moramo, da so vse tri barve, ko jih vključimo eno za drugo, “na oko” približno enake intenzivnosti, da kombinacije dveh barv dajo čudovito oranžno vijolično in modrozeleno in da je ob vključitvi vseh treh barv svetloba čim bolj podobna beli. Opomba: Če so položaji rdečih, zelenih in modrih čipov jasno vidni skozi ohišje RGB diode, je primerno, da diode pokrijete s kosom tanjšega, prosojnega belega papirja.
Ko izberemo optimalne vrednosti uporov, jih razdelimo na štiri (zaradi multipleksiranja je srednja vrednost toka skozi vsako diodo četrtina največjega toka!) in jih namestimo na Shield-A. Na originalnem tiskanem vezju je Rr označen z R11, Rb = R12 in Rg = R13. V mojem konkretnem primeru sem za R11 in R12 izbral 470 Ω upore, medtem ko sem za R13 vgradil 2,7 kΩ. Pri drugem tipu RGB diode je bila zelena barva manj izrazita, zato je bila optimalna vrednost “zelenega” upora R13 1 kΩ. Vredno se je potruditi, da izberemo vrednost teh uporov, saj je končna izkušnja odvisna od dobrega ravnovesja barv!
Ko bomo izbrali in namestili optimalne upore za RGB diode, bomo napisali prvi program, ki jih bo “oživel”.
13. programska naloga: Na RGB diodi D8 je treba vklopiti rdečo, zeleno in modro luč, ponovite enako na D9, D10 in D11 in nato na vseh štirih diodah hkrati. Poleg tega morajo biti na diodah prižgane barvne kombinacije v enakem vrstnem redu: vijolična (= rdeča + modra), oranžna (= rdeča + zelena), modro-zelena (= modra + zelena) in bela (= rdeča + zelena + modra )
Bascom-AVR rešitev
(program Shield-A_13a.bas)
Najprej bomo kot izhodne konfigurirali vse priključke mikrokontrolerja, na katere so priključeni priključki RGB diod:
Config Portd.5 = Output Config Portd.6 = Output Config Portd.7 = Output Config Portb.0 = Output Config Portb.1 = Output Config Portb.2 = Output Config Portb.3 = Output
Spomnimo se, da smo to lahko storili le z dvema ukazoma:
Config Portd = &B11100000 Config Portb = &B00001111
Nato bomo nastavili vse priključke, na katere so priključene katode RGB diod postavili v stanje logične enice:
Portb = &B00001111
Ostali priključki so v stanju logične nič (standardno, razen če ni drugače nastavljeno), zato bodo vse RGB diode obratno polarizirane in nobena ne bo zasvetila. Učinek je enak, kot da bi priključke pustili “v zraku”, ta izraz smo pojasnili v prejšnjem nadaljevanju.
Bascom-AVR ponuja možnost dodelitve nadomestnih imen posameznim delom mikrokontrolerja, zato bomo priključke PB0 do PB3 poimenovali glede na oznake diod, ki so z njimi povezane:
Led8 Alias Portb.0 Led9 Alias Portb.1 Led10 Alias Portb.2 Led11 Alias Portb.3
Podobno bodo priključki PD5 do PD7 poimenovani po barvah, ki vključujejo:
Crvena Alias Portd.5 Plava Alias Portd.6 Zelena Alias Portd.7
To ni potrebno, vendar je program bolj berljiv. Spremenili bomo barve v podprogramu Boje, ki se nahaja na koncu programa. Najprej bomo vklopili rdeči čip, počakali eno sekundo in ga nato izklopili:
Boje: Crvena = 1 Wait 1 Crvena = 0
Isto bomo ponovili z zelenim, in nato tudi z modrim čipom:
Zelena = 1 Wait 1 Zelena = 0 Plava = 1 Wait 1 Plava = 0 Return
Ukaz Return nas vrača v glavni program, kjer vklopimo po eno RGB diodo. Najprej bomo vklopili diodo D8, poklicali podprogram Boje, ki bodo nanjo “postavili” rdečo, zeleno in modro barvo, nato pa D8 takoj izklopili:
Do Led8 = 0 Gosub Boje Led8 = 1
Isto bomo ponovili z diodami D9-D11:
Led9 = 0 Gosub Boje Led9 = 1 Led10 = 0 Gosub Boje Led10 = 1 Led11 = 0 Gosub Boje Led11 = 1
Končno bomo vključili vse LED-ice, poklicali podprogram Boje in jih nato izključili:
Portb = Portb And &B11110000 Gosub Boje Portb = Portb Or &B00001111 Loop
Ker se glavni program nahaja znotraj neskončne Do-Loop zanke, se bo ponavljal, dokler programa ne izbrišemo ali izklopimo napajanja.
Bascom-AVR rešitev dodatne naloge
(program Shield-A_13b.bas)
Če želimo prikazati barvne kombinacije na RGB diodi, bomo morali hkrati vklopiti dva ali vse tri čipe. Z drugimi besedami, vse binarne kombinacije od 001 do 111 bomo morali pripeljati na priključke D7, D6 in D5 (izključimo kombinacijo 000, ker bi bila potem dioda izklopljena). Za to bomo potrebovali samo eno For-Next zanko v podprogramu Boje:
Boje: For Portd = &B00100000 To &B11100000 Step &B00100000 Waitms 500 Next Return
Preostali del programa je enak programu Shield-A_13a.bas!
Arduino rešitev
(program Shield-A_13a.ino)
Ker v programskem jeziku C ni ukaza alias, bomo za lažje branje programske kode uporabili spremenljivke z samoumevnimi imeni. Njihova vrednost bo število priključkov:
byte led8 = 8; byte led9 = 9; byte led10 = 10; byte led11 = 11; byte crvena = 5; byte plava = 6; byte zelena = 7;
Po tem bomo v funkciji setup() kot izhodne konfigurirali vse priključke mikrokontrolerja, na katere so priključeni priključki RGB diode:
pinMode(crvena, OUTPUT); pinMode(plava, OUTPUT); pinMode(zelena, OUTPUT); pinMode(led8, OUTPUT); pinMode(led9, OUTPUT); pinMode(led10, OUTPUT); pinMode(led11, OUTPUT);
Enako lahko storimo s funkcijama DDRB in DDRD (DDR pomeni Data Direction Register): DDRB (za register B, oziroma za priključke PB0-PB5) in DDRD (za register D, oziroma za priključke PD0-PD7). Te funkcije uporabljamo za neposreden nadzor priključkov. Vrednost 0 pomeni, da je priključek konfiguriran kot vhodni, vrednost 1 pa, da je priključek konfiguriran kot izhodni. Za lažjo vizualizacijo konfiguracije, ki bo dodeljena vsakemu priključku, uporabljamo binarni prikaz vrednosti, ki jih dodelimo registru. Na primer, konfiguracija priključkov D0 ali PD0 je definirana s funkcijo DDRD in skrajno desno številko binarne številke. Konfiguracija priključka D7 ali PD7 je definirana s funkcijo DDRD in skrajno levo številko binarne številke.
DDRD = B11100000; DDRB = B00001111;
Nato bomo vse priključke, na katere so spojene katode RGB diod postavili na stanje logične enice:
digitalWrite(led8, HIGH); digitalWrite(led9, HIGH); digitalWrite(led10, HIGH); digitalWrite(led11, HIGH);
Enako lahko naredimo tudi s funkcijo PORTB (PORT je oznaka za Port Data Register, B pa je oznaka registra):
PORTB = B00001111;
S pomočjo te funkcije neposredno nadzorujemo stanje priključkov. Vrednost 0 pomeni, da je priključek v stanju logične ničle, vrednost 1 pa, da je priključek v stanju logične enice. Binarni prikaz vrednosti, ki jih dodelimo registru, uporabljamo za enostavnejšo vizualizacijo vrednosti, ki bodo dodeljene vsakemu priključku. Na primer, vrednost priključka D8 ali PB0 je definirana s funkcijo PORTB in skrajno desno številko binarne številke. Konfiguracija priključka D11 ali PB3 je definirana s pomočjo funkcije PORTB in četrte številke od desne proti levi binarne številke.
Barve bomo menjali v funkciji boje(), nameščeni na koncu programa. Najprej bomo vključili rdeči čip, počakali 1 sekundo in ga nato izključili:
void boje(){ digitalWrite(crvena, HIGH); delay(1000);
Isto bomo ponovili z zelenim, in nato tudi z modrim čipom:
digitalWrite(crvena, LOW); digitalWrite(zelena, HIGH); delay(1000); digitalWrite(zelena, LOW); digitalWrite(plava, HIGH); delay(1000); digitalWrite(plava, LOW); }
Nato bomo v funkciji loop() vklapljali eno za drugo RGB diodo. Najprej bomo vključili diodo D8, poklicali funkcijo boje() ki bo na njej “zvrstili” rdečo, zeleno in modto barvo in takoj nato iuključili D8:
void loop() { digitalWrite(led8, LOW); boje(); digitalWrite(led8, HIGH);
Isto bomo ponoviti z diodami D9-D11:
digitalWrite(led9, LOW); boje(); digitalWrite(led9, HIGH); digitalWrite(led10, LOW); boje(); digitalWrite(led10, HIGH); digitalWrite(led11, LOW); boje();
Na koncu bomo vklopili vse LED, poklicali funkcijo boje() in jih nato izklopili:
PORTB &= B11110000; boje(); PORTB |= B00001111; }
Ker je glavni program znotraj loop() funkcije, se bo ponavljal, dokler programa ne izbrišemo ali izklopimo napajanja.
Arduino rešitev dodatne naloge
(program Shield-A_13b.ino)
Kot pri rešitvi z Bascom-AVR bomo spremenili samo funkcijo boje() z uporabo for zanke, preostali del programa pa bo ostal enak. Najprej spremenimo vrednost spremenljivke in nato vrednost spremenljivke posredujemo v podatkovni register vrat D s funkcijo PORTD. To je priporočljiv način dela z registri za lažje spremljanje programske logike in način delovanja for funkcije na vrsto spremenljivke. O podrobnih primerih lahko pišemo v ločenem članku.
void boje(){ for (int i = B00100000; i <= B11100000; i += B00100000){ PORTD = i; delay(1000); } }
***
Če dobro pogledate, boste opazili, da je jakost svetlobe posamezne diode šibkejša, ko so vklopljene vse štiri diode. To je v skladu z našimi pričakovanji, saj ta postopek ne uporablja postopka multipleksiranja. Spoznali ga bomo v naslednjem poglavju!
Opomba: Programi Shield-A_13a.bas, Shield-A_13a.ino, Shield-A_13b.bas in Shield-A_13b.ino se lahko brezplačno dobijo od uredništva revije Svet elektronike.
Shield-A_Mitrovic_10