Med pospravljanjem Frižiderja sem naletel na tole čudo: trinadstropno kocko s po 3×3 LED v vsakem nadstropju. O elektroniki vem ravno toliko, da sem lahko začel ugibati.
Najprej pozabimo, da imamo tri nadstropja, glejmo le eno. Na ploščico peljejo žice, ki gredo prek uporov do diod; za zdaj torej le devet diod, razporejenih v mrežo 3×3 in vezanih tako, kot jih zna vezati vsak otrok, ki zna vezati diode (in celo jaz). Edina posebnost je, da katode (prikrajšane nožice teh diod) niso vezane naravnost na žico, ki bi šla na GND (če bi to delal vsak otrok ali jaz), temveč na trinog obsekan valj, v katerem ne-elektronik jaz prepoznam tranzistor. Vsaj tako se mi zdi.
Na domnevnem tranzistorju piše NP2222A. Google pravi, da imam prav: gre za tranzistor. Točneje NPN tranzistor. Več o njem izvem v dokumentaciji proizvajalca. Pravzaprav ne kaj dosti: izvem, kako so poimenovane nožice, namreč kolektor, baza in emitor. Moje nadstropje diod je povezano s kolektorjem.
Vse to sem že velikokrat vedel, a, ubog računalnikar, nikoli zares uporabil, zato nadaljujem na Wikipediji, na strani o tranzistorjih, razdelku o NPN tranzistorjih. Tam pravijo takole: če je napetost na bazi večja od te na emitorju, bo tranzistor pustil tok, da teče s kolektorja na emitor. Lepo razlago najdemo tudi na strani o tranzistorju na slovenski Wikipediji.
Vsako nadstropje ima svoj tranzistor. Njihovi emitorji so povezani skupaj; očitno jih bo potrebno priključiti na GND. Če bom na bazo pripeljal dovoljšnjo napetost (na Arduinu bo to HIGH z nekega pina), bo tranzistor odprl tok med pripadajočim nadstropjem diod in GNDjem.
Če bi bile diode povezane “po otročje”, bi moral postaviti na HIGH en sam pin – tistega, ki gre na pripadajoči upor in naprej na to diodo. Pri tej vezavi, moram postaviti na HIGH še pin, ki gre na bazo v tranzistorju, ki prepušča tok iz tega nadstropja (prek kolektorja v emitor in od ondod) v GND.
Čemu ti zapleti s tranzistorji? Drugo in tretje nadstropje je nad prvem: anode vseh treh diod, ki so ena nad drugo, so povezane med sabo. Torej, tok bo tekel z upora na vse tri diode, v stolpcu. Svetila pa bo le tista (oziroma tiste) pri katerih bom odprl tudi tok iz njenega (oziroma njenih) nadstropij.
Zapleteno? Tri, štiri slike bodo pojasnile vse. Reč sem priključil na Arduina, kot kaže desna slika. Pini od 5 do 13 gredo na upore, pini od 2 do 4 na tranzistorje. Poleg tega je emitor tranzistorjev povezan na GND.
Takle pa je pogled od zgoraj. Pin 5 gre prek upora na vse tri diode v stolpcu levo zadaj. Pin 6 na vse tri diode, ki so zadaj na sredi. In tako naprej.
Pogled s strani: zgornje nadstropje gre na tranzistor, ki ga odpre pin 4. Srednje gre na nadstropje, ki ga odpira tranzistor na pinu 3. Spodnje na tranzistor na pinu 2.
Kako torej prižgemo posamezno diodo? Potrebno je prek upora spraviti tok v ustrezno vrstico in jo odpeljati prek ustreznega tranzistorja. Za diodo na sliki je potrebno postaviti na HIGH pina 11 in 2.
Funkcija, ki prižge diodo na “koordinatah” (x, y, z) je torej
void nastavi(char x, char y, char z, char stanje) {
digitalWrite(5 + x + 3 * y, stanje);
digitalWrite(2 + z, stanje);
}
Le brž jo preskusimo! Tale program po vrsti prižiga vse diode.
void setup() {
for(int i = 2; i < 14; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
}
void nastavi(char x, char y, char z, char stanje) {
digitalWrite(2 + z, stanje);
digitalWrite(5 + x + 3 * y, stanje);
}
void loop() {
for(int z = 0; z < 3; z++) { // gremo prek vseh nadstropij
for(int y = 0; y < 3; y++) { // vseh y
for(int x = 0; x < 3; x++) { // in vseh x
nastavi(x, y, z, HIGH); // prizgemo diodo (x, y, z)
delay(100); // pocakamo
nastavi(x, y, z, LOW); // in ugasnemo
}
}
}
}
# Več diod
Kaj pa, če želim prižgati več diod hkrati? Dokler so vse v istem nadstropju, je stvar preprosta. Če gre, recimo, za diode v srednjem nadstropju, postavimo pin 3 na HIGH, 2 in 4 pa na LOW, ter vključimo ustrezne diode na pinih 5-13.
Kaj pa, če niso v istem nadstropju? Recimo, da želimo prikazati tridimenzionalno “šahovnico”? Dobra in slaba novica. Slaba je, da se tega s tem vezjem ne da storiti. Dobra pa, da je možno z njim tako dobro goljufati, da nas ne bo nihče spregledal. Takle program napišemo.
void setup() {
for(int i = 2; i < 14; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
}
void loop() {
for(int z = 0; z < 3; z++) {
digitalWrite(2 + z, HIGH); // prizigamo diode v z-tem nadstropju
for(int y = 0; y < 3; y++) { // prizgemo, kar želimo prizgati
for(int x = 0; x < 3; x++) {
digitalWrite(5 + x + 3 * y, (x + y + z) % 2 == 1 ? HIGH : LOW);
}
}
delay(3); // trenutek pocakamo, da imajo diode cas posvetiti
digitalWrite(2 + z, LOW); // ugasnemo to nadstropje
}
}
Šahovnico dobimo tako, da diodo na koordinatah (x, y, z) prižgemo, če je vsota koordinat liha, (x + y + z) % 2 == 1
. A to je nepomemben detajl. Pomembno je, da nadstropja prižigamo eno za drugim: najprej pokažemo prvo nadstropje, nato ga ugasnemo in pokažemo drugo nadstropje, nato tretje. Ker to počnemo tako hitro, ne bo nihče opazil, da diode v resnici utripajo.
# Podvig?
Z Arduinovimi 11 pini nam je uspelo nadzorovati 27 diod. A to pravzaprav ni nič takega: videli smo že zaslone s 64 LED diodami, ki smo jih prav tako nadzirali z Arduinom. Ali pa sedemsegmentne zaslone z osmimi števkami, kar nanese, hm, sedem segmentov s piko je 8 diod, pri osmih števkah je to 8×8, torej spet 64 diod.
Ti zasloni vsebujejo čip MAX7219, ki počne natančno isto reč kot naš program. Eno za drugo prikazuje, recimo, posamezne vrstice matrike z 8×8 diodami, ali eno samo števko sedemsegmentnega zaslona, vendar to počne tako hitro, da ne opazimo, da vidimo le eno naenkrat. Katere diode naj svetijo, pa čipu povemo s takšnim načinom prenosa podatkov, ki zahteva le tri pine.