Language Switcher Fallback

Binaarkell

Mitmed aastad tagasi, kui ma Arduinoga alles alustasin ja Arduino arendusplaadid olid märgatavalt kallimad kui täna, püüdsin ma ehitada säästuässa binaarkella (inglise keelne artikkel sellest). See oli küll suurepärane ülesanne programmeerimise õppimiseks ja elektroonika vallas nihkeregistritega tutvumiseks, kuid kasutuskõlbliku kellana see tööle ei hakanud. Nimelt Attiny45 sisemine ostsillaator ei ole piisavalt stabiilne, et rahuldava täpsusega ajaarvamist üle paari tunni teha.

Aga nüüd ehitasin sellesama vana vidina ümber. Kirjutasin ka uue koodi, kuna Arduino + DS1302 kellamoodul on täiesti erinev süsteem varasemast Attiny45 + nihkereigistrid. Sain valmis seinakella, mida täiesti kannatab kasutada.

Kuidas neid numbreid lugeda?

Täpsemalt on tegemist binaarselt kodeeritud kümnendsüsteemis numbritega (kahend-kümnendkood https://et.wikipedia.org/wiki/Kahend-k%C3%BCmnendkood). Esimene tulp LEDisid on selleks, et näidata tundide kümnendkohta. Teine tulp tundide ühendkoha jaoks, kolmas minutite kümnendkoha jaoks ja nii edasi. Kui me tahaks näidata kellaaega 15:36:01, siis selles on 6 numbrit kümnendsüsteemis, iga LEDide tulp esindab üht neist.

Iga tulba LEDidest alumine on nn madalaim bit. Arvu, mis paberil oleks kujutatud vasakult paremale nullide ja ühtede jadana, tuleb lugeda tulbas ülevalt alla, kus põlev LED on 1 ja mittepõlev 0.
Põhimõtteliselt iga positsioon on teatud väärtusega. Kõige parempoolsem ("viimane") on 1, sealt vasakule liikudes 2, 4, 8. "1"-ga postsioonidele vastavad väärtused tuleb kokku liita, nulliga positioonide omad vahele jätta. Näiteks arv 3 näeb kahendsüsteemis välja "11". (Paremalt alustades) 1*1+1*2=3. Arv 8 näeb välja "1000" ehk (paremalt alustades) 0*1+0*2+0*4+1*8=8.

Terve kellaaja näide oleks selline:
15:36:01 (punktid tähistavad mittepõlevat LEDi, O-d põlevat LEDi)

  .   .   .
  O . O . .
. . O O . .
O O O . . O

Tööpõhimõte

Tegelikult põlevad korraga vaid ühe tulba LEDid, aga kuna põlevat tulpa vahetatakse 2500 korda sekundis, siis inimsilm ei erista vilkumist. 2500 vahetust 6 tulba vahel teeb "pildilaotuse" sagedusesks 2500/6=417Hz. Selliselt põleva LEDi heledus on umbes 1/6 sellest, mis ta püsivalt põledes oleks.
LEDid on ühendatud maatriksina, kus iga tulba ühist pluss pinget lülitab üks trasistor ja iga rea ühist miinus pinget lülitab samuti transistor.

Ühe tulba näitamiseks kontroller lülitab ridade miinuspoolte transistorid sisse vaid nendel ridadel, kus hetkel näidatavas tulbas peaks "1"-d ehk põlevad LEDid olema. Samal ajal tulpade plusspoolte tranistoridest lülitatakse sisse vaid hetkel aktiivse tulba oma.

Põlema saavad minna vaid need LEDid, mis on parasjagu näidatavast tulbas - sest teistele ei anta plusspinget - ja samas on 1-staatuses olevas reas, sest 0-ridades ei anta ühendust toite miinuspoolega.

DS1302 on kellamoodul, mis oskab täpselt "tiksuda" ja suhelda mikrokontrolleriga kellaaja ja kuupäeva teemadel. Kontroller saab DS1302-le öelda, mis on hetkel õige aeg ja DS1302 võtab selle teatavaks ning hakkab ise aega arvama. Nüüd võib kontroller küsida DS1302 käest, mis tema arvestuse järgi on õige aeg, ning DS1302 vastab. DS1302-l on lisaks kogu seadme 5V toitele küljes ka 3V liitium patarei, millega ta tiskub edasi ka siis, kui ülejäänud seadmel toidet küljes ei ole.

Kellaaja seadmise lahendasin kahe nupuga. Nimetagem ühte neist "Ok" nupuks ja teist "pluss" nupuks. Kui vajutada "Ok" nuppu, siis kell läheb seadmise reziimile. Selle indikeerimiseks lähevad põlema kolm LEDi sekundite kümnendkoha tulbas. Nüüd saab "pluss" nupu vajutamisega muuta tundide väärtust. Vajutades "OK" jäävad tunnid paika, sekundite alal liiguvad kolm põlevat LEDi viimasesse tulpa ja seada saab minutite väärtust. Järgmise "OK" vajutusega kinnitatakse kellaaeg ja minnakse tavalisse tiksumise režiimi.

Kontroller näitab aega umbes 5 minutit järjest oma ostsillaatori võngete järgi arvet pidades, seejärel sünkroniseerib end DS1302 täpsema kellaajaga.

Riistvara

Komponendid:

  • Arduino Pro Mini (sobiks ka Arduino Nano, kui pole käepärast FTDI adapterit)
  • DS1302 kella moodul (millelt ma komponedid maha jootsin ja oma plaadile teisiti paigutasin)
  • 20 LEDi
  • 10 NPN-transistori nt 2N3904
  • 2 surunuppu
  • 14 tk 470 oomi takistit (LEDidega jadamisi olevad takistid võiks olla ka väiksemad, transistoride baasile ühendatud võiks olla suuremad, mul on kõik 470, sest sattusin ammu-ammu selle ehituse alguses võtma eeskujuks selliseid numbreid sisaldanud juhendit)
  • 2tk 10 kilo-oomi takistit (nuppude pull-downid)
  • prototüüpimise plaat
  • juhtmeid
  • patarei CR2032 kellamoodulile
  • 5V toiteadapter (Minu kell võtab voolu 25 +-5 mA. See on päris vähe adapteri jaoks, aga samas lollakalt palju patarei/aku jaoks.)

 

Kood

Koodi saab näha ja alla laadida githubis.
DS1302 jaoks ma ei kasutanud teeki (library-t), vaid ainult koodinäidist http://playground.arduino.cc/Main/DS1302 , millest vajalikud jupid (suurema osa) kopeerisin (failid DS1302.h ja DS1302.ino). DS1302 räägib ise ka kellaaegadest binaarselt kodeeritud kümnendsüsteemis. Arvan, et kood tuli selgem ja robustsem ilma teegita, sest too (http://playground.arduino.cc/Main/DS1302RTC) omakorda kasutab Time teeki ja ei olnud eriti kergesti mõistetav.

Arduino digitalWrite on funktsioon, mille teostamiseks kulub ülemääraselt palju aega. Selle asemel kasutasin ridade ja tulpade lülitamiseks otse pordiregistritesse kirjutamist (https://www.arduino.cc/en/Reference/PortManipulation), mis on hulga kiirem protsess.

DebouncedButtons.h sisaldab klassi, millega mugavamalt nuppude vajutusi lugeda nõnda, et kogemata mitmekordseid vajutusi ei tuleks.

BCDtime.h sisaldab funktsioone, mis teevad kellaaegadega toimetamise loogiliseks ja mugavaks, sealhulgas binaarkodeeritud kümnendsüsteemiga seotu.