Námět pro takové to hraní s Arduinem.

Je veřejným tajemstvím, že plánuju knihu o elektronice, která bude kombinovat příklady elektronických konstrukcí s Arduinem a výklad principů elektroniky a některých pojmů (třeba „co to je SPI a jak si to připojím ke svému počítači?“) Od blikání s LEDkou půjdeme přes zapojení senzorů a připojení celého bazmeku k internetu až k jednoduchým počítačům. A jaký je předstupeň mezi blikačem a počítačem? No přece kalkulačka!

Dnes existují dva hlavní způsoby stavby kalkulačky…

Nebo jinak: Existují dva způsoby, jak přijít ke kalkulačce. Zaprvé: Buď použijete tu, co máte v počítači, v mobilu, v lednici nebo kdekoli jinde, popřípadě si koupíte některou z 572 modelů, co mají v obchodech, vietnamskými večerkami počínaje, nebo si nějakou postavíte.

Proč si stavět draho něco, co si mohu koupit, nebo co dokonce dostanu jako reklamní dárek, a bude to vypadat líp než to doma postavené? Otázka stará jako poznání samo. A odpověď stejně stará: buď vás baví něco tvořit a přitom se učit nové věci, nebo vás to nebaví. (Některým lidem můžete odseknout: „A proč ty píšeš znovu e-shop, quicksort, bankovní systém…?“)

Takže postavit. Dnes existují dva hlavní způsoby stavby kalkulačky. Jeden je opravdu retro, při něm použijete staré kalkulačkové obvody (MHB7001, MC14007 – viz třeba tahle kalkulajda), druhý je modernistický. Ten způsob mám rád i já. Ve stručnosti: Pokud to můžu poskládat z hotových modulů z eBay za dolar až pět včetně poštovného, tak to poskládám z modulů!

Já si takhle vyhlédl modul pro remake jednodeskáčů. Je tam osm osmisegmentovek a šestnáct tlačítek a připojuje se to přes SPI, tedy tři dráty (+2 na napájení). Objednal jsem, přišel, včetně těch kablíků s dutinkami, a já přemýšlel, jak to připojit. Samozřejmě, nejjednodušší by bylo použít kablíky, kde jsou na jedné straně dutinky (pro ten modul) a na druhé dráty (pro zastrčení do Arduina), ale nakonec jsem se tak na to UNO koukal a oči mi furt kroužily kolem toho pinového konektoru ICSP. Tak jsem se na něj podíval blíž – a co myslíte?

Je tam +5V a zem, jsou tam tři datové vývody (11, 12 a 13) a RESET. Pokud zrovna nehodláte programovat jednočip, tak jsou volné a jsou natvrdo připojené na ty datové výstupy. Takže když to nastrkám tam…

Druhý krok k řešení byl ten obvod TM1638. Mám sice datasheet, který je srozumitelný – inu, jako datasheet k čínskému obvodu, ale raději se podívám, jestli někdo nemá knihovnu. Naštěstí měl: TM1638-library. Dokonce v aktuální verzi (2.2.0) byla i úprava pro ten modul, co mám, protože modul má sedmisegmentovky se společnou anodou.

Všechno jsem tedy propojil, vzal jsem knihovní demo (tm1638qyf), změnil nastavení vývodů, spustil – a děly se věci! Ono to svítilo, blikalo, běhaly po displeji zuřivé nápisy, logiku to nedávalo, až jsem se lekl, že to je rozbité, a ono ne, ono je tak naprogramované to demo!

A tak jsem sedl a udělal svoje vlastní, co zobrazovalo čísla. Fungovalo to skvěle, ale mělo to takový jeden nešvar: Zobrazovalo to čísla buď s úvodními nulami, nebo vlevo. Takže jsem udělal drobnou úpravu knihovny – přidal jsem funkci pro zobrazení čísla se zarovnáním doprava, jak to kalkulačky mívají.

Otestoval jsem i klávesnici. Práce s ní je jednoduchá: modul vrátí šestnáctibitové číslo, kde co bit, to tlačítko. Nejnižší bit odpovídá tlačítku 1, které je „vlevo nahoře“…

Kalkulačka potřebuje 10 tlačítek pro číslice. Zbývalo mi 6. Jedno tlačítko zabere „=“, zbývá jich pět. Takže mám akorát na čtyři základní matematické operace, a to poslední bude „C“ – tedy tlačítko na smazání chyby.

Namapoval jsem je takto:

(„Calcuino? WTF?“ No, taky to mohla být Ardulačka!)

První pokus mi ukázal, že obvod by sice měl odstranit zákmity, ale nějak se mu do toho nechtělo, takže jsem si je ošetřil sám. A pak už to šlo krok za krokem.

Přidal jsem jednoduchou funkci: Když zmáčknu tlačítko s číslicí, objeví se na displeji a přidá se k už napsanému číslu. Je to jednoduchá operace: Z = 10 * Z + n. Jestli nevěříte, zkuste si to: Mám na displeji 123, zmáčknu čtyřku, výsledek by měl být 1234, a to je přeci těch původních 123 * 10 + (zmáčknutá) 4! Do téže funkce přidám omezení počtu míst (na sedm, osmou pozici nechám volnou pro mínus).

Tlačítko C prostě jen vynuluje pracovní registr (a na displeji se objeví 0).

Tohle mi zabralo asi pět minut, a pak jsem zkusil implementovat první operaci, totiž plus.

Není to úplně triviální, jak by to na první pohled mohlo vypadat. Nezapomeňte, že kalkulačky pracují s infixovou notací, to znamená že 2+3 se zadává jako série stisknutí tlačítek 2, +, 3 a =. Algoritmus je tedy takový:

  1. Pokud uživatel stisknul číslici, přidej ji jako nejnižší řád k tomu, co je na displeji.
  2. Pokud uživatel stisknul C, nastav displej na 0
  3. Pokud uživatel stisknul nějakou operaci, poznamenej si ji. Ještě předtím proveď předchozí uloženou operaci, ulož si mezivýsledek do registru X a zobraz ho. Zároveň při dalším stisknutí číslice nejprve vynuluj displej.
  4. Pokud uživatel stisknul „=“, tak proveď poslední uloženou operaci, výsledek si ulož do registru X a zobraz ho.

K tomu jen poznámka: Kalkulačka nezohledňuje (v téhle verzi) prioritu operátorů, to budu řešit až příště (a vy si to můžete dát za domácí úkol).

Kalkulačka tak potřebuje několik pracovních registrů: jednak registr X na uložení mezivýsledku, pak registr „op“ na uložení zvolené operace, a konečně registr Z, kde je obsah displeje.

Takhle z popisu by to mohlo vypadat, že při stisku tlačítka s nějakou operací se vlastně vykonává ta předchozí, a když se nad tím zamyslíte, tak to tak opravdu je. Ta aktuální se ukládá „na příště“ a provádí se ta předchozí. Tlačítko „=“ je v podstatě stejné jako jakákoli jiná operace, jen s tím rozdílem, že „na příště“ se uloží operace „nedělej nic, jen zkopíruj displej do mezivýsledku!“

Tak co, troufnete si to dát sami?

Můj kód je tady:

A tady k tomu máte balíček: kód, modifikovaná knihovna, datasheet a rozložení kláves.

Náměty pro příště: upravit kalkulačku tak, aby zvládala prioritu operátorů, upravit ji tak, aby umožňovala zadat záporná čísla, upravit ji na RPN… Všechny tyhle modifikace mám připravené a postupně je budu přidávat. Ale nechci vás připravit o radost z vlastních experimentů.

Komponenty [sc:ebay item=TM1638+module+keyboard+display] [sc:ebay item=arduino%20UNO%20R3%20atmega328p%20board]