A nagy megszámolás
Számos módja van annak, hogy digitális számlálót építsünk
Van egy régóta húzódó hardveres projektem. Haladgat szépen-lassan, már csak a programozás részét kellene befejezni, de ritkán jön meg a kedvem hozzá. Így sajnos fokozottan fogékony vagyok a figyelemelterelésekre.
Szóval láttam egy videóban egy mechanikus számlálót, ami nem sokkal több, mint négy számjegy és egy gomb, amivel lehet növelni a számot. Meg egy tekerő, amivel le lehet nullázni az egészet.
Valamivel később pedig belefutottam egy cuki kis LCD kijelzőbe. Három számot tud megjeleníteni és méreteiből adódóan felettébb próbapanel-kompatibilisnek tűnt.
Talán érezzük már, hogy hova fog kifutni ez az egész. Építeni kellene egy digitális számlálót. Biztos nem túl bonyolult. Csak egy mikrokontroller, egy-két gomb, egy 7 szegmenses kijelző és néhány sor kód. Vagy mégse?
A cél hardver
Szokás szerint nem az egyszerű úton indultam el. Mint oly sokszor, most sem a digitális számláló elkészülése a cél. Az csak egy eszköz, hogy ne a másik projekten kelljen dolgoznom.
Annyira azért nem akartam megnehezíteni a dolgomat, hogy az egészet NAND kapukból rakom össze. Vannak alkatrészek, amik remekül megvalósítanak részfeladatokat a folyamatból. Például IC-k, amik tudnak számlálni vagy éppen értik a 7 szegmenses kijelzők szegmens formátumát.
Kis keresés után ráleltem a CD4026B nevű chip-re, ami 0-tól 9-ig tud számolni és a kimenete a 7 szegmenses kijelző szegmenseinek felel meg (a-tól g-ig).
┌───┬──┬───┐
CLOCK ┤ • └──┘ ├ VDD
CLOCK INHIBIT ┤ ├ RESET
DISPLAY ENABLE IN ┤ ├ UNGATED "C" SEGMENT OUT
DISPLAY ENABLE OUT ┤ ├ c
CARRY OUT ┤ CD4026B ├ b
f ┤ ├ e
g ┤ ├ a
VSS ┤ ├ d
└──────────┘
A kijelző miatt három számjegyet célzok meg. A chip-en található CARRY OUT kimenet akkor lesz 1, ha a számláló 9-ről 0-ra vált, így egymás után lehet fűzni több CD4026B-t, hogy több számjegyünk legyen. Az alacsonyabb helyiértékű chip CARRY OUT-ját az eggyel magasabb helyiértékű chip CLOCK-jába kell kötni.
A gombot ráköthetnénk a legkisebb helyiértékű chip CLOCK bemenetére, de van a gomboknak az a rossz tulajdonsága, amit pergésnek neveznek. Egy gombnyomás során az érintkezők néha többször is egymáshoz érnek, így az elvárt egyszeri növelés helyett random mennyiséggel fog növekedni a számunk. Nem annyira jó működés egy számláló esetében.
Az Internet szerint rengeteg mód van arra, hogy ezt kivédjük, nekem egy Ben Eater videó rémlett fel a 8 bites számítógép építés sorozatából, ahol egy monostabil 555 időzítővel lett ez megoldva.
Ezen a ponton van egy jól működő gombunk és három egymás után kötött chip-ünk, amik együtt el tudnak számolni 0-tól 999-ig. De nem látjuk, hogy éppen hol tartanak.
A fentebb említett LCD kijelzőről kiderült, hogy sajnos nem olyan egyszerű vezérelni, mint mondjuk egy 7 szegmenses LED kijelzőt, meg egyébként sem érkezett meg időben, úgyhogy egy BC56-12-es modellt használtam helyette.
Róla annyit érdemes tudni, hogy mind a három számjegy ugyanazokat a szegmens bemeneteket használja. Van ezen kívül három másik bemenet, amivel azt választhatjuk ki, hogy éppen melyik számjegy aktív. Szóval ha három különböző számjegyet akarunk egyszerre megjeleníteni, akkor nagyon gyorsan kell váltogatnunk a három szám között, hogy a szemünknek úgy tűnjön, mintha a három számjegy egyszerre világítana.
Két fajta változat létezik ebből a fajta kijelzőből: közös anódos és közös katódos, attól függően, hogy a szegmens LED-eknek az anód vagy a katód végük van összekötve. A mi változatunk közös katódos.
A számok közötti gyors váltakozáshoz szükségünk lesz egy órajelre. Legnagyobb szerencsénkre van egy másik Ben Eater videó, amiből megtanulhatunk órajelet generálni egy astabil 555 időzítő segítségével. Ezt az egy órajelet valahogy még három felé kell osztanunk, hogy kiválaszthassuk vele az aktív számjegyet. Én egy másik számlálót, a CD4017B-t használtam erre.
┌───┬──┬───┐
5 ┤ • └──┘ ├ VDD
1 ┤ ├ RESET
0 ┤ ├ CLOCK
2 ┤ ├ CLOCK INHIBIT
6 ┤ CD4017B ├ CARRY OUT
7 ┤ ├ 9
3 ┤ ├ 4
VSS ┤ ├ 8
└──────────┘
Ez a számláló kijelző szegmensek helyett 10 különböző kimeneten jelzi, hogy melyik számnál tart éppen. Az első három számot fogjuk felhasználni arra, hogy legyen három, egymást kölcsönösen kizáró jelünk, a negyedik számot pedig arra, hogy RESET-eljük a chip-et, hogy újra nulláról induljon.
Tehát az egyik oldalon vannak az egymás után fűzött számlálóink a gombbal, a másik oldalon van egy órajelünk három felé osztva, amivel kiválaszthatjuk az aktív számjegyet.
A számlálóinkon van egy ígéretes nevű DISPLAY ENABLE IN bemenet, amiről joggal gondolhatjuk azt, hogy hasznos lehet a kijelző meghajtása során. De nem az.
A DISPLAY ENABLE IN kikapcsolása esetén a kimenetek alacsony állapotba kerülnek. Ha össze vannak kötve más kimenetekkel, amik magas állapotban vannak (mert egy szegmens egy másik számjegyben be van kapcsolva), akkor abból rövidzárlat lesz. Így nem tanácsos összekötni a számlálóink kimeneteit.
Talán néhány (21 darab) dióda meg tudta volna oldani a problémát, de én az erre a célra kitalált 74HC541 chip-et választottam:
┌───┬──┬───┐
OE1' ┤ • └──┘ ├ VDD
A0 ┤ ├ OE2'
A1 ┤ ├ Y0
A2 ┤ ├ Y1
A3 ┤ ├ Y2
A4 ┤ 74HC541 ├ Y3
A5 ┤ ├ Y4
A6 ┤ ├ Y5
A7 ┤ ├ Y6
VSS ┤ ├ Y7
└──────────┘
Az A0-7 pin-eken jön a bemenet, amit megkapunk az Y0-7 pin-eken, ha a kimenetek engedélyezve vannak (OE1' és OE2'). Ha a kimenet nincs engedélyezve, akkor nagy impedanciás módba kerülnek az Y0-7 kimenetek és nem zavarják egymást.
Szóval a három CD4026B számlálónk a-g kimenetét rákötjük egy-egy 74HC541 chip bemenetére (a képen a kék vezetékek), a három 74HC541 kimenetét (a képen a zöld vezetékek) pedig összekötjük és rákötjük a kijelzőre.
Az órajelet három felé osztó CD4017B-ből érkező jeleket szeretnénk arra használni, hogy a megfelelő 74HC541 IC és LED számjegy legyen csak aktív. De mindkét helyen alacsony jelre van szükségünk, a CD4017B pedig magas jelet ad az aktív számjegyre. Szerencsére erre is léteznek integrált áramkörök, mint például a 74HC240, ami a bemenő jelet negálja.
┌───┬──┬───┐
1OE' ┤ • └──┘ ├ VDD
1A1 ┤ ├ 2OE'
2Y4 ┤ ├ 1Y1
1A2 ┤ ├ 2A4
2Y3 ┤ ├ 1Y2
1A3 ┤ 74HC240 ├ 2A3
2Y2 ┤ ├ 1Y3
1A4 ┤ ├ 2A2
2Y1 ┤ ├ 1Y4
VSS ┤ ├ 2A1
└──────────┘
Rákötjük a CD4017B-ből érkező három kimenetünket mondjuk az 1A1, 1A2 és 1A3 bemenetekre és megkapjuk az ellentétét az 1Y1, 1Y2 és 1Y3 kimeneteken.
Ezzel meg is van minden részegység, amire szükségünk van egy működő számlálóhoz. Már csak össze kell drótoznunk mindent és kész is vagyunk.
╔═════════╗
┌───────────┬───────────┬───────────┬───╢ BC56-12 ║
│ │ │ │ ╚═════════╝
│ │ │ │
╔════╧════╗ ╔════╧════╗ ╔════╧════╗ ╔════╧════╗
║ 74HC541 ║ ║ 74HC541 ║ ║ 74HC541 ║ ║ 74HC240 ║
╚════╤══╤═╝ ╚════╤══╤═╝ ╚════╤══╤═╝ ╚═╤══╤════╝
┃ └────────╂──┴────────╂──┴─────┘ │
┃ ┃ ┃ ╔════╧════╗
┃ ┃ ┃ ║ CD4017B ║
┃ ┃ ┃ ╚════╤════╝
┃ ┃ ┃ │
╔══════╗ ╔═════╗ ╔════╧════╗ ╔════╧════╗ ╔════╧════╗ ╔══╧══╗
║ Gomb ╟─╢ 555 ╟─╢ CD4026B ╟─╢ CD4026B ╟─╢ CD4026B ║ ║ 555 ║
╚══════╝ ╚═════╝ ╚═════════╝ ╚═════════╝ ╚═════════╝ ╚═════╝
A képen még látható, hogy be van kötve egy extra gomb a három CD4026B RESET pin-jeire. Induláskor előfordul, hogy random értékekről indulunk, ezért jó ha van kéznél egy nullázó gomb.
Ugyan a végeredmény remekül néz ki, azért elég kényelmetlen lenne kézi számlálóként használni, így tovább nézelődtem alternatív megoldások után.
Segít a memória
A YouTube Algoritmus ezen a ponton már valószínűleg tökéletesen tisztában volt azzal, hogy miben mesterkedem. Volt olyan kedves és felajánlott még egy Ben Eater videót megtekintésre, ami pont egy 7 szegmenses LED kijelző meghajtásáról szól EEPROM segítségével.
Az ott használt alkatrészek ugyan nem teljesen felelnek meg a céljainknak, de az alapötletet fel tudjuk használni: az EEPROM-ban letároljuk előre, hogy adott szám és adott számjegy esetén a 7 szegmens közül melyikeket kell bekapcsolni.
Tehát az EEPROM bemenete az lesz, hogy melyik számjegyet jelenítjük meg éppen (3 pin) és melyik számnál járunk éppen (10 pin, 10 bit, 0 és 1023 közötti számok). A kimenet pedig a hét szegmens állapota (7 pin). Az AT28C64B pont megfelel ezeknek a feltételeknek, 13 bemenete és 8 kimenete van.
┌───┬──┬───┐
┤ • └──┘ ├ VDD
A12 ┤ ├ WE'
A7 ┤ ├
A6 ┤ ├ A8
A5 ┤ ├ A9
A4 ┤ ├ A11
A3 ┤ ├ OE'
A2 ┤ AT28C64B ├ A10
A1 ┤ ├ CE'
A0 ┤ ├ I/O7
I/O0 ┤ ├ I/O6
I/O1 ┤ ├ I/O5
I/O2 ┤ ├ I/O4
VSS ┤ ├ I/O3
└──────────┘
Az áramkör eleje nagyon ismerős lesz, először is egy monostabil 555 időzítő a gombnyomás pergés mentesítéséhez, egy astabil 555 időzítő az órajelhez és egy CD4017B IC, amivel a három számjegyből választjuk ki az egyiket. Számlálónak a CD4040B-t fogjuk használni, ami 12 bitnyi bináris kimenetet produkál (0-tól 4095-ig tud számolni).
┌───┬──┬───┐
Q12 ┤ • └──┘ ├ VDD
Q6 ┤ ├ Q11
Q5 ┤ ├ Q10
Q7 ┤ ├ Q8
Q4 ┤ CD4040B ├ Q9
Q3 ┤ ├ RESET
Q2 ┤ ├ CLOCK
VSS ┤ ├ Q1
└──────────┘
Az AT28C64B-be töltött adat végzi el a konvertálást a bináris számláló és a LED kijelző között. A LED kijelző pedig most egy BA56-12 lesz, hogy ne kelljen invertálni az órajelet (a közös anód miatt a kiválasztott számjegy magas állapotban kell, hogy legyen, a világításra ítélt szegmens pedig alacsonyban).
Először is meg kell töltenünk adattal az EEPROM-ot. Ehhez egy Raspberry Pi Pico-t használtam, szerencsére pont van rajta elég GPIO pin.
Írtam hozzá egy kis programot, de lusta voltam értelmezni az AT28C64B időzítési diagramjait, inkább elég nagy ráhagyásokkal dolgoztam, ami a sleep-eket illeti. Így elég lassú lett, cserébe viszont nem is annyira megbízható. Egymás után többször is le kellett futtatnom, hogy a megfelelő értékeket írja be.
#define A0 10
// ...
#define A12 2
#define IO0 11
// ...
#define IO7 18
#define WE 27
#define OE 20
const uint8_t address[13] = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12 };
const uint8_t io[8] = { IO5, IO7, IO1, IO4, IO3, IO6, IO2, IO0 };
const uint8_t numbers[10][8] = {
{0, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 1, 1, 1, 1, 1},
{0, 0, 1, 0, 0, 1, 0, 1},
{0, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{0, 1, 0, 0, 1, 0, 0, 1},
{0, 1, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 1, 0, 0, 1},
};
Egy kis konfigurációval indítunk. Szükségünk van arra, hogy az AT28C64B pinjei melyik Pico pin-eknek felelnek meg. Aztán definiáljuk a cím- és I/O pin-ek sorrendjét és végül kell egy megfeleltetés, hogy melyik számot melyik szegmensek reprezentálják.
A cím- és I/O pin-ek sorrendje itt attól függ, hogy a végleges helyén hogyan fogjuk összedrótozni az AT28C64B-t a bemeneteivel és a kimenetével. A cím esetén az A0-A9 pinre fog érkezni a szám, ahol a számláló tart. Az A10-A12 pinek pedig a számjegy kiválasztására lesznek használva. Az I/O pin-ek azért vannak össze-vissza, hogy legyen elég hely a vezetékeknek az EEPROM és a kijelző között.
int main()
{
stdio_init_all();
gpio_init(WE);
gpio_set_dir(WE, GPIO_OUT);
gpio_put(WE, true);
gpio_init(OE);
gpio_set_dir(OE, GPIO_OUT);
gpio_put(OE, true);
for (const uint8_t pin : address)
{
gpio_init(pin);
gpio_set_dir(pin, GPIO_OUT);
gpio_put(pin, false);
}
for (const uint8_t pin : io)
{
gpio_init(pin);
gpio_set_dir(pin, GPIO_OUT);
gpio_put(pin, false);
}
// ...
}
Az inicializálás során mindent kimenetre állítunk és mindent kikapcsolunk. A WRITE ENABLE és OUTPUT ENABLE pin-ek esetén ez magas állapotot jelent. Ezek után folytathatjuk a main() függvény tartalmát az adatok beírásával.
printf("write\n");
for (int i = 0; i < 1000; ++i)
{
for (int j = 0; j < 10; ++j)
{
gpio_put(address[j], (i & static_cast<int>(pow(2, j))) > 0);
}
for (int j = 0; j < 3; ++j)
{
gpio_put(address[10], false);
gpio_put(address[11], false);
gpio_put(address[12], false);
gpio_put(address[10 + j], true);
const int digit = i / static_cast<int>(pow(10, j)) % 10;
for (int k = 0; k < 8; ++k)
{
gpio_put(io[k], numbers[digit][k]);
}
sleep_ms(5);
gpio_put(WE, false);
sleep_ms(5);
gpio_put(WE, true);
sleep_ms(5);
}
if (i % 10 == 0)
{
printf(".");
}
}
printf("\ndone.\n");
A cím első 10 bitje a szám, amit meg akarunk jeleníteni. Az utolsó 3 bit az éppen aktív számjegyet jelöli. Az eltárolt érték az adott helyi értéken lévő számjegy 7 szegmenses reprezentációja lesz. Ehhez eggyel/tízzel/százzal osztjuk el az eredeti számot és megnézzük a tízzel osztás során képződő maradékát.
A cím és az I/O pin-ek értékeinek beállítása után be- majd újra kikapcsoljuk az WRITE ENABLE pin-t és megyünk tovább a következő számjegyre majd számra.
Az EEPROM felprogramozása után már csak össze kell kötnünk mindent.
╔═════╗ ╔═════════╗
║ 555 ╟─╢ CD4017B ╟─┐
╚═════╝ ╚═════════╝ │ ╔══════════╗ ╔═════════╗
├─╢ AT28C64B ╟─╢ BA56-12 ║
╔══════╗ ╔═════╗ ╔═════════╗ │ ╚══════════╝ ╚═════════╝
║ Gomb ╟─╢ 555 ╟─╢ CD4040B ╟─┘
╚══════╝ ╚═════╝ ╚═════════╝
Ez a verzió ugyan fele akkora lett, mint az előző, de azért vannak hibái. A használt számláló chip 12 bites, amiből 10 bitet használunk. 10 biten 0-tól 1023-ig tudunk elszámolni, de a kijelzőn csak három számjegy látszik. Úgyhogy a kedves felhasználó azt fogja tapasztalni, hogy 999 után 23-ig fog számolni, aztán újra 999-ig, aztán újra 23-ig és így tovább.
Ezen kívül a CD4017B valószínűleg nem tud elég áramot adni, hogy rendesen meg legyenek hajtva a LED-ek, ezért olyan halovány a kijelző.
Valószínűleg egyik probléma sem megoldhatatlan, de extra komponenseket jelentenek, amik tovább növelik a méretet. Mi a helyzet akkor, ha valami kisebbet szeretnénk?
Szoftveres megoldások
Utolsó ötletem a legelőször elvetett volt: egy mikrokontroller. Ugyan egy Raspberry Pi Pico túlzás lenne egy ilyen kicsi feladathoz, de kereshetünk valamit, ami jobban passzol.
Amire szükségünk van: 7 kimenet a szegmensekhez, 3 kimenet a számjegy választáshoz és két bemenet a gomboknak. Az ATtiny24A pont jónak is tűnik. 12 pin-ből 11-et tudunk használni a saját céljainkra, a tizenkettedik pedig fixen a RESET, ami pont jó, mert arra van szükségünk.
┌───┬──┬───┐
VDD ┤ • └──┘ ├ VSS
PB0 ┤ ├ PA0
PB1 ┤ ├ PA1
RESET' ┤ ATtiny24 ├ PA2
PB2 ┤ ├ PA3
PA7 ┤ ├ PA4
PA6 ┤ ├ PA5
└──────────┘
Az áramkör ennél egyszerűbb talán már nem is lehet, csak az ATtiny24A, két gomb és a LED kijelző (újra egy BA56-12, de ez esetben bármelyiket használhattuk volna, csak a kódon változtat).
Sajnos a kijelzőhöz nem volt megfelelő komponens, úgyhogy csak a helye van ott
Az egyszerűség oka pedig az, hogy mindent szoftverből kell megoldanunk. Ehhez fel kell programoznunk az ATtiny-t. Először egy Raspberry Pi-t próbáltam használni, de valamiért nem működött, úgyhogy végül egy Arduino UNO-val mentem.
Nem a legegyszerűbb dolog programot juttatni az ATtiny-re, de nem mennék bele a részletekbe, itt van rá egy részletes leírás. Ugorjunk inkább a programozásra.
const byte digits[3] PROGMEM = {0, 3, 4};
const byte segments[7] PROGMEM = {1, 5, 7, 9, 10, 2, 6};
const byte numbers[10][7] PROGMEM = {
{0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 1, 1, 1, 1},
{0, 0, 1, 0, 0, 1, 0},
{0, 0, 0, 0, 1, 1, 0},
{1, 0, 0, 1, 1, 0, 0},
{0, 1, 0, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0},
};
const byte buttonPin = 8;
Maga a program ismét egy kis inicializációval indul. Megadjuk a számjegy és szegmens pin-eket, valamint a korábban már használt megfeleltetést a számjegy és a szegmensek között. A nagyobb adatokat program memóriában tároljuk (PROGMEM), hogy futás közben ne foglalják a helyet. Cserébe kicsit nehezebb lesz elérni őket.
void setup() {
for (byte i = 0; i < 3; ++i) {
pinMode(pgm_read_byte(&digits[i]), OUTPUT);
digitalWrite(pgm_read_byte(&digits[i]), LOW);
}
for (byte i = 0; i < 7; ++i) {
pinMode(pgm_read_byte(&segments[i]), OUTPUT);
digitalWrite(pgm_read_byte(&segments[i]), HIGH);
}
pinMode(buttonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), increment, RISING);
}
A számjegy választókat és a szegmenseket lekapcsoljuk, a gomb pin-jére pedig rakunk egy megszakítást. A pgm_read_byte a korábban említett nehezebb elérése a program memóriában tárolt adatoknak.
volatile byte d0 = 0;
volatile byte d1 = 0;
volatile byte d2 = 0;
volatile bool pressed = false;
volatile unsigned long pressTime;
void increment() {
if (!pressed) {
pressed = true;
pressTime = millis();
d2 += 1;
if (d2 > 9) {
d2 = 0;
d1 += 1;
if (d1 > 9) {
d1 = 0;
d0 += 1;
if (d0 > 9) {
d0 = 0;
}
}
}
}
}
A megszakítás eltárolja a megnyomás idejét és megnöveli a számjegyeket, ha még nem volt megnyomva a gomb. Ez lesz a pergés elleni védelmünk alapja.
A számjegyek külön tárolása és egyesével növelése nem nevezhető éppen elegánsnak, de megspórolhatunk vele néhány osztást és maradék számítást a kijelző vezérlése során.
void loop() {
if (pressed) {
noInterrupts();
unsigned long t = pressTime;
interrupts();
if (millis() - t > 150) {
pressed = false;
}
}
for (byte i = 0; i < 7; ++i) {
digitalWrite(pgm_read_byte(&segments[i]), pgm_read_byte(&numbers[d0][i]));
}
digitalWrite(pgm_read_byte(&digits[0]), HIGH);
delay(5);
digitalWrite(pgm_read_byte(&digits[0]), LOW);
for (byte i = 0; i < 7; ++i) {
digitalWrite(pgm_read_byte(&segments[i]), pgm_read_byte(&numbers[d1][i]));
}
digitalWrite(pgm_read_byte(&digits[1]), HIGH);
delay(5);
digitalWrite(pgm_read_byte(&digits[1]), LOW);
for (byte i = 0; i < 7; ++i) {
digitalWrite(pgm_read_byte(&segments[i]), pgm_read_byte(&numbers[d2][i]));
}
digitalWrite(pgm_read_byte(&digits[2]), HIGH);
delay(5);
digitalWrite(pgm_read_byte(&digits[2]), LOW);
}
Programunk fő részében kezeljük a megnyomott gombot: ha elég idő telt el a gomb megnyomása óta (esetünkben 150 mililszekundum), akkor engedjük újra megnyomni a gombot. Nem tökéletes megoldás (mi van mondjuk olyan esetben, ha valaki hosszabb ideig tartja nyomva a gombot és a felengedés okoz pergést?), de itt és most bőven elég.
Ezen kívül itt kezeljük a LED kijelzőt is. Ebben a részben talán nincs semmi meglepő. A numbers tömb megfeleltetése alapján beállítjuk a megfelelő kimenetet a szegmens pin-eken minden egyes számjegyre. A számjegyeket csak kis időre kapcsoljuk be és gyorsan váltakozik az éppen megjelenített számjegy, hogy úgy tűnjön, mintha mindhárom számjegy egyszerre lenne látható.
A delay lehet, hogy egy kicsit magas, azzal érdemes lehet még játszani. Az alábbi képen látszik is, hogy nem egységes fényerejűek a számjegyek, valószínűleg túl alacsony volt még a frissítési gyakoriság.
Sikerült újra megfeleznünk a számláló áramkörünk méretét és azt hiszem ez a legkisebb méret, amit próbapanelen el tudunk érni.
Ugyan a cél nem egy használható méretű digitális kézi számláló volt, de azért nem baj, hogy a végére sikerült valami olyasmit összerakni, ami megfelelően csomagolva egy használható eszköz is lehetne.
Végelszámolás
Három és fél próbapanel, tizenhat IC, méretre vágott vezetékek százai, vagy fél tucat bütyköléssel töltött este, egy (rövidzárlat okozta túlmelegedésből adódó) égési sérülés és a végeredmény: három digitális számláló.
- egy cél-chip-eket használó óriási méretű megoldás, ahol a legnagyobb kihívás a sok vezeték volt
- egy előre programozott EEPROM-os változat a maga különc működésével
- egy mikrokontroller vezérelt, ahol a limitált hardver hajlamos megviccelni az óvatlan programozókat
Bár méretileg csökkentek a megoldások, az első változatban jelen lévő és szemmel is jól látható komplexitás nem veszett el a lépések során, csak átvándorolt a memóriába, majd a program kódba.
Különszám
Bredbord kényes egyensúlyát egy gombnyomás rázta meg. A pergés okozta zaj elérte 555 bemenetét és a monostabil időzítőben cikázó feszültség megnyitotta az utat a feltöltődés felé. A zaj tüskéi továbbra is bele-belemartak, de 555 kitartotta a jelet míg a növekvő feszültség olyan mértékű lett, hogy egy kisülés kíséretében el kellett engednie. Büszkeséggel tekintett utána, ahogy egybeolvadt az ismeretlennel. Lélekben azonban már a következő ostromra készült.
CD4026B az elkerülhetetlenség nyugalmával várta a rendületlenül felé közeledő órajel ketyegését. Reteszeken és kapukon keresztülszáguldva megváltoztatta belső állapotát. A számláló kilencese átfordult nullába. Visszajutott oda, ahonnan indult, egy újabb kezdethez a végtelen körforgásban. A túlcsordulás ugyan a semmibe vezette a jelet, de Bredbord már kibillent egyensúlyából, ezzel CD4026B olyan megállíthatatlan folyamatokat indított el, amik túlmutatnak létezésén.
Hét részre szakadva terjedt tovább a változás a szegmens lábakon BC56-12 LED-jei felé. Néhányuk a vak semmibe zuhanva hosszú álomba merültek. Mások a feszültség izgalmától fénylőn ébredtek új életre. Az általuk kirajzolt minta isteni kinyilatkoztatásként ragyogott fel: átmenetileg ugyan, de ismét helyreállt az egyensúly.