A héten már annyi új információt kapott az agyam, hogy kezd kisülni, úgyhogy csak egy könnyebb feladatot választottunk: futófényt csináltunk ledekből. Az első nap másfél óra alatt egyedül összeraktam a vezetékezését, és éreztem, hogy mindenki jobban jár, ha a programozását a következő napra hagyom, mert féltem, hogy még egy portról sem tudtam volna megmondani, hogy mit kötöttem rá, nemhogy beprogramozni a ledeket. Még mindig krumplival fényképezek, de remélem, így is látszik, hogy miért szeretek azzal babrálni, hogy mit hova kell vezetni :)
Jól tettem, mert a latch, clock és data pin-eknek picit utána kellett olvasnom (ami azért nagy szó, mert korábban felesleges volt utánaolvasni, mert úgysem értettem egy szót sem belőle), de az, hogy előtte én dugdostam össze a vezetékeket, nagyon sokat segített. Ha látom, hogy mit hova, és mellé olvasom, hogy mit fog csinálni, jelentősen meggyorsítja a folyamatot :)
Szóval van ez az úgynevezett Shift Register (a továbbiakban SR), egy téglalap alakú kis fekete izé 16 karommal. A SR lábait - attól függően, hogy melyik katalóguskódhoz tartozik - össze kell kötni a ledekkel plusz az Arduino board-dal (aminek szintén vannak speckó lábai, amiket nem lehet bármire használni, csak, hogy egyszerű legyen az életem), aztán ezeket az összekötögetéseket kell beprogramozni.
Az sem mindegy, hogy a SR-t hogy rakjuk a board-ra, mint azt nekem azért sikerült elrontanom, először raktam rá és csak utána olvastam el, hogy fordítva kell, mert ahol a kis U-alakú bemetszés van, annak kell felül lennie (csak úgy mellékesen jegyzem meg, hogy a ledeknek meg a hosszú [pozitív] lába mutasson a chip felé, pont ellenkezőleg, ahogy én elsőre csináltam. lol.).
#notetoself: az instrukciókat mindig olvasd végig, különben két körmöd bánja a gyorsaságod.
Szóval a SR data pin-nek adjuk meg az adatokat, hogy melyik led világítson attól függően, hogy milyen értéket kapott (pl. 10000000 - az első led, mert annak az állapota 1 azaz ON, ha 01000000 - a második led, stb), a clock pin a bitek feldolgozásához szükséges, egy bizonyos ütemben olvassa be az értékeket, hogy azok elkülönüljenek egymástól, és amikor megvan a megfelelő számú bit (jelen esetben nyolc), a latch pin átengedi a ledekhez az "adatcsomagot".
És akkor jöjjön az, hogy ez programozásban hogy is néz ki:
A latch pin került itt az ötös, a clock a hatos és a data a négyes lábára az Arduino board-nak, a led alapból OFF értékkel lett megadva ("byte leds = 0" azaz a kezdő adatcsomag mind a nyolc bitje 0-ra van állítva, amire később "leds" név alatt hivatkozik), a pinMode beállítása pedig OUTPUT (írjuk az állapotát).
int latchPin = 5; int clockPin = 6; int dataPin = 4; byte leds = 0; void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); }
Ezután következik az adatok megadása és azok kiküldése a ledeknek.
Érdekességként két változatot hagyok itt:
Az elsőnél a leds = 0 azt jelenti, hogy a 0000 0000 adatcsomaggal kezd, így egyik led sem világít. A "for" ciklusban meghatározható, hogy hányszor fusson végig a program (jelen esetben nyolcszor, 0-től 7-ig), a bitSet-ben pedig az i-edik körhöz tartozó bit értékét állítom be.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void loop() { leds = 0; updateShiftRegister(); delay(100); for (int i = 0; i < 8; i++) { bitSet(leds, i); //leds=leds<<1; updateShiftRegister(); delay(100); bitClear(leds, i); } } |
A második verzió ennek pici egyszerűsítése, ahol az első led ON alapértékkel lett beállítva, mert a 0000 0001 adatcsomaggal kezd, és a "for" ciklusban a 9. sorban lévő paranccsal a biteket egy helyiértékkel balra tolja, jobbra pedig 0 kerül (0000 0001 --> 0000 0010 -- > 0000 0100 és így tovább) nyolc körön keresztül. Ez szerintem szebben is látszik, mert nem "akad" egy pillanatra meg az első lednél.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void loop() { leds = 1; updateShiftRegister(); delay(100); for (int i = 0; i < 8; i++) { //bitSet(leds, i); leds=leds<<1; updateShiftRegister(); delay(100); //bitClear(leds, i); } } |
És most szokásomhoz híven bele fogok kötni az informatikuslogikába, mert ismét fél órán keresztül kerestem a megoldást arra, hogy hol a fenébe határozom meg az adatcsomagot, mikor a helyiértékekről beszélek. Nyilván megint az van legalul...szóval így néz ki az, hogy mikor hova milyen számot kell írnia:
1 2 3 4 5 6 |
void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, leds); digitalWrite(latchPin, HIGH); } |
A digitalWrite a latchPin-t alapból kikapcsolja, amíg a shiftOut-ban behozza a dataPin-t, a clockPin-t, az MSBFIRST (most significant bit first) alapján a bal szélső bittel kezdi a bitek kiírását (1000 0000 --> 0100 0000 stb), ezt akár át is lehet állítani LSBFIRST-re, akkor a másik irányból kezdi a ledek világítását :) az utolsó tag pedig a leds változó. Amikor összeállítódott az adatcsomag, a latch pin-t ON-ra állítja és átengedi a ledeknek.
Amúgy ezt az egészet egyszerűbb volt megcsinálni, mint leírni, így sokkal bonyolultabbnak hangzik, mint amilyen valójában, érdemes ezt megcsinálni, ilyen remek játékot lehet vele összerakni:
E.