Az épülő szimulátorban több helyen is szükség lesz 7 szegmenses LED kijelzők használatára. Amíg csak egy számjegyünk van, addig elég egyszerű a vezérlése, minden szegmenst külön ledként kezelve megjelenítjük a kívánt értéket. Amikor már több számjegy megjelenítésére alkalmas a kijelzőnk, akkor ügyeskedni kell egy picit. Rövid utánanézés és egy remek arduino library találása után ez meglepően egyszerű feladat.
De nézzük is hogyan működik egy többdigites LED kijelző.
forrás: https://e-radionica.com/productdata/LD3361BS.pdf
Bekötés szempontjából kétféle létezik: az egyik, amikor a ledek anódja van egy közös lábra kivezetve (common anode) a másik amikor a katódjukkal teszik mindezt (common cathode). Az előbbi ábra egy közös anódos 3 digites 7 szegmenses (+ a pont) kijelző adatait tartalmazza.
Ami látszik belőle, hogy a szegmensek (LED) katódjai vannak kivezetve külön lábakra, viszont mindhárom számjegyhez ugyanazokat a lábakat használja (A:11, B:7, stb...). A digitenkénti közös anódok természetesen külön lábakon vannak (12, 9, 8).
A vezérlése tehát úgy történhet, hogy megjeleníteni kívánt szegmens katódjait földeljük, majd a kívánt digit anód lábát megemeljük pozitív feszültségre. Ugye ilyenkor egy számjegyet jelenítünk csak meg. Ha a többi digit anód lábát is felemeljük pozitívra, akkor mindhárom számjegyen ugyanaz fog megjelenni.
Itt tehát a folyamatos megjelenítésre már nincs lehetőség, át kell verni az ember szemét. Erre két féle megoldás létezik. Az egyik az, amikor egyszerre csak egy szegmenst villantunk fel. Ahogy a LED felvillan, ki is kapcsoljuk és megjelenítjük a következő szegmenst. Ahogy egy számjegy szegmenseivel végeztük lépünk a következőre... majd kezdjük elölről az egészet. Mindezt olyan gyorsan, hogy az emberi szem ne vegyen észre belőle villogást és akkor folyamatosnak fog tűnni. Ehhez a megoldáshoz az alábbi bekötés javasolt:
A 12, 9 és 8-as lábak a kijelzőn a 3 digit anódjai. Ilyenkor elegendő ide rakni egy ellenállást, mivel egyszerre mindig csak egy LED fog világítani.
A megjelenítést gyorsabbá tehetjük, ha nem szegmensenként, hanem digitenként villantjuk fel a ledeket. Ilyenkor először beállítjuk (földeljük) a megjeleníteni kívánt szegmens lábakat és csak ezután adunk az anódra pozitív jelet. Ehhez azonban feltétlen szükséges, hogy berakjunk egy ellenállást minden szegmens elé, hogy a ledek bizonyosan azonos fényerővel világítsanak. Ilyenkor természetesen az anódokat már közvetlenül köthetjük az arduinóra, valahogy így:
Innen már csak egy lépés, hogy több kijelzőt, vagy több digites kijelzőt használjunk. A lényeg, hogy az ellenállások után a többi kijelző szegmenseit kössük rá ugyanúgy mint az elsőét, az anódokat pedig vezessük vissza egy arduino lábra.
Nincs más hátra, mint kódolni. Találtam egy remek arduino library-t ehhez(SevSeg), így a vezérlés gyerekjáték.
Az alábbi kóddal két darab 3 digites kijelzőt vezérlek (a második kijelzőből csak az első digitet használtam. Ez a kód nem a fenti bekötéshez készült, mindjárt részletezem mire figyeljünk ha copy/paste akarjuk kipróbálni.
#include "SevSeg.h"
#include <stdio.h>
SevSeg sevseg;
int displayValue;
char* strToLed = new char[8];
void setup() {
byte numDigits = 4;
byte digitPins[] = { 10, 11, 12, 13 };
byte segmentPins[] = {9, 2, 3, 5, 6, 8, 7, 4};
bool resistorsOnSegments = false;
byte hardwareConfig = COMMON_ANODE;
delay(2000);
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
}
void loop() {
displayValue = analogRead(A0);
sprintf(strToLed, "%04d.", displayValue );
sevseg.setChars(strToLed);
sevseg.refreshDisplay();
delay(2);
}
A setup() -ban a configuráljuk a könyvtárat, hogy milyen kijelzőt használunk (sevseg.begin(.... ), a következő paraméterekkel:
byte hardwareConfig = COMMON_ANODE;
Itt mondjuk meg, hogy a katód vagy az anód közös (COMMON_ANODE / COMMON_CATHODE).
byte numDigits = 4;
Hány digitet akarunk kijelezni. Ez a könyvtár 7 szegmenses kijelzőket tud kezelni, plusz a pontot hozzá.
byte digitPins[] = { 10, 11, 12, 13 };
Itt adjuk meg, az arduino melyik lábaira vannak kötve a közös anódok. (A fenti bekötés szerint ez 10, 11, 12 lenne).
byte segmentPins[] = {9, 2, 3, 5, 6, 8, 7, 4};
Az arduino mely lábaira vannak a szegmensek bekötve (A-G -ig és a pont, a fenti rajz szerint ez 7, 9, 3, 5, 6, 8, 2, 4 lenne).
bool resistorsOnSegments = false;
Megadjuk, hogy a szemgensekre vannak kötve az ellenállások, vagy nem (hanem a közös lábakra). Ennek megfelelően vagy digitenként, vagy szegmensenként fog a megjelenítéssel pörögni a program.
A loop() -ban mindösszesen annyit teszek, hogy beolvasom a potméter állását (0-1023 közötti számot kapok), az beletolom egy karakterláncba úgy, hogy 0-val előtöltve mindig 4 számjegy legyen és a végére teszek egy pontot (az utolsó digit után világítani fog a pont is, ahogy az a legelső képen, illetve a lenti videóban látható).
sevseg.setChars(strToLed);
Ezzel állítjuk be, milyen számokat akarunk megjeleníteni.
sevseg.refreshDisplay();
A refreshDisplay segítségével pedig végrehajt egy megjelenítési ciklust.
Érdekességképpen beletettem még a ciklus végére egy 2ms várakozást, játszottam picit vele, hogy mennyit bír az emberi szem, mikortól látom, hogy vibrál a kijelző. 4-5ms 6 digit esetén már észrevehető, sőt egy idő után zavaró tud lenni. Úgyhogy az az arduino board, amelyik sok ilyen led kijelzőt vezérel egyszerre, jobb ha nem csinál semi mást, mert nagyon gyorsan elfogy 2ms :)
Itt egy kis videó is a fent leírtakról. Újdonság nincs benne, ami érdekes lehet, hogy az elején láthatjátok működés közben is:
Jöhetnek az adatok a szimulátortól, és lehet azokat megjeleníteni most már :)
***UPDATE***
Úgy néz ki a szimulátorhoz ez a megoldás nem használható, mivel 8-10 digit fölött már elkezd zavaróan villogni, ha a ciklusban bennmarad a 2ms várakozás. Ennyi idő pedig kell majd a boardnak, hogy lekérje a szimulátortól az adatokat. Más megoldást kell találni. Kaptam egy tippet, miszerint MAX7221 IC-t kellene használnom a ledek vezértléséhez. Remek ötletnek tűnik, jövök majd vele, ahogy van eredmény.