Okos otthon is fókuszban

Arduino kalandok

Arduino kalandok

Mennyi az idő? - RTC

2017. december 19. - denx

Aki programozott már valamilyen PC-n, vagy netán szerveren futó alkalmazást, az hozzá van szokva bizonyos kényelmi szolgáltatásokhoz. Például ahhoz, hogy a program bármikor le tudja kérdezni, hogy mennyi is az idő. Nos, itt egy nagyon limitált eszközhöz van dolgunk, ami ezt mérsékelten képes csak szolgáltatni.

Mit ad nekünk a környezet?

Maga a futtató környezet elég kevés dologra képes, mivel meglehetősen közvetlen a hozzáférésünk a processzor szolgáltatásaihoz. A tipikus Ardu feladatok nagy része megoldható azzal, amit a proci tud, nevezetesen azt tudja megmondani ha kérdezzük, hogy mennyi ideje fut. Ezt milisec pontossággal szokás használni és egy 32 bites változóban kapjuk meg az értéket. Ezt tudja a millis() metódus. Ha egy kicsit utánaszámolunk, akkor a következő jön ki ebből:
- 1 másodperc alatt a számláló 1000-et ugrik..
-> 1 perc alatt 60.000-et.
-> 1 óra alatt 3.600.000-et
-> 1 nap alatt 86.400.000-et.
- 32 biten a legnagyobb ábrázolható szám 4.294.967.295
-> ebből az következik, hogy kb. 49,7 naponta ez a számláló túlcsordul és megint 0-ról kezd számolni.

Ez így elsőre elég tragikusan hangzik, de ha ezt tudjuk előre, akkor tudunk ezzel kalkulálni. Nyilván ez az eszközkészlet teljességgel alkalmatlan arra, hogy meg tudja mondani az eszköz, hogy hány óra hány perc van, arra meg pláne, hogy hanyadik hó hanyadika! 

Mit adnak nekünk a lib-ek?

Nem meglepő módon más is szembesült már a problémakörrel, így született rá rengeteg megoldás. Én ezek közül az egyik "gyári" megoldást favorizálom, a TimeLib.h nevűt. Ez egy olyan könyvtár, amit helyből ismer az összes fordító, így telepítést nem igényel. (A csomag része egy Time.h header fájl is, de mivel ez annyira általános név, hogy ebből több lib gyűjtemény is tartalmaz ugyanilyen nevűt, ráadásul ez nem tartalmaz semmi mást, mint azt, hogy "#include TimeLib.h" sort, így egyszerűbb és megbízhatóbb a TimeLib.h használata.)

Lássuk ez mit is tud! Itt van a hivatalos dokumentációja: https://playground.arduino.cc/Code/Time
A leg lényegesebb funkcióknak elég lényegre törő nevet sikerült találni: hour() minute() second() millis() day() weekday() month() year(). Ezek mind úgy működnek ahogy az ember elsőre gondolja: ha mindent lekérdezek, akkor egy pontos időt tudok kirakni. Ami még jó ebben a lib-ben, hogy minden metódusnak van olyan változata is, aminek be lehet adni a now() hívás kimenetét, ilyenkor nem az aktuális órát, percet, stb adja vissza a hívás, hanem a paraméterként kapott időpillanatból számolja ki, hogy mennyi is az annyi. Vannak még olyan funkciók, amik segítik a 12/24 órás számítást, illetve a hónapok és a hét napjainak a szöveges megjelenítését (angolul) de ezek szerintem egy beágyazott rendszerben nem annyira fontosak. Ami viszont fontos még, hogy ez a lib honnan is fogja tudni, hogy mennyi a pontos idő? Hát onnan, hogy van setTime(t) függvénye, aminek vagy egy átadunk egy time_t típusú változót, vagy a másik overload-olt alakját használjuk: setTime(hr,min,sec,day,month,yr).

Ez mind nagyon kényelmesnek tűnik, 2 apró bökkenő van csupán:
1. Minden indulás vagy RESET után újra be kellene állítani az időt, mivel a háttérben ugyanazt a rendszert használja, amit az első fejezetben taglaltam, ha pedig nincs tápellátás, akkor ugye nincs időmérés sem!
2. Ezek a kis gépecskék a legritkább esetben rendelkeznek olyan felhasználóbarát felülettel, ahova könnyen be lehetne adni az időt...

Mit ad nekünk az RTC?

Ezzel el is jutottunk oda, hogy mire jó az RTC! Az RTC a Real Time Clock nevű alkatrészcsalád angol nevének rövidítéséből ered. Ilyen alkatrész nagyon sok helyen van, például a PC-kben is szokott lenni, de mint külön részegységet nem veszi senki figyelembe, a BIOS-on keresztül lehet hozzáférni általában. Mivel az Arduino dedikáltan és felvállaltan az olcsóságról szól, így ezt sem építik be a gépbe, mivel nagyon sok olyan alkalmazás van, ahol teljesen lényegtelen mennyi is a pontos idő.

RTC-ből sok fajta van, de mind elég hasonlóan működik: egy IC a lelke mindnek (na nem mindnek ugyanaz az egy típus) ami tulajdonképpen arra van kitalálva, hogy folyamatosan számoljon, olyan pontosan ahogy csak tud. Mivel a cuccnak akkor is működnie kell, ha nem kap tápellátást, így szokott lenni egy gombelem is rajtuk. Hogy az alkatrész meg tudja mondani mennyi az idő, ezért egyfajta buszt kell még rajta elhelyezni, amivel tud majd a mi kis gépecskénk kommunikálni vele.

A képeken az egyik legprecízebb típus látható, a DS3231. Amiért ezt szeretjük, az 3 dolog:
- I2C buszon kommunikál. (Erről terveztem egy posztot majd.)
- Tényleg nagyon pontos.
- Olcsó. (1 dodó alatt van az Alin.)

A buszt most nem részletezném elég annyi, hogy egy szabványos kommunikációs protokollt használ, amire egyszerre több más eszközt is fel lehet fűzni. A pontosságának a titka a belső hőmérő. A dolgot úgy kell elképzelni, hogy a képen látható IC-ben benne van egy quartz kristály, amiről a gyártó pontosan tudja, hogy milyen frekvencián rezonál. Szobahőmérsékleten. Ám ha változik a környezet hőmérséklete, akkor változik a kristály rezgésszáma, ami ahhoz vezet, hogy pontatlan lesz az óra! Ha 32 kHz helyett mondjuk 32.001 Hz jön létre a valóságban, akkor ez azt jelenti, hogy minden 32.000-ik másodpercben már egyet csal a számlálás. Vagyis durván perenként 2 ms-ot. ez már óránként 0,12 másodperc! Ez elég sok, mert bár minimális az eltérés, amiből kiindultunk, de egy hónap alatt már ez is durván másfél percet jelenthet! Ennek a pontatlanságnak a kiküszöbölésére építettek egy hőszenzort az IC-be, ami korrigálni tudja ezt a pontatlanságot, vagyis ha sokat volt melegben a szerkezet, akkor időnként levon egyet a saját számlálójából, míg nagy hidegben hozzáadogat. Elég okos kis cucc, nem? Ami nekem hiányzik róla az a gombelem egészségének ellenőrizhetősége: nem tudjuk hogy jó-e még az elem, vagyis hogy mi fog történni, ha elveszíti a tápot az alkatrész. Lehet jól fog tovább számolni, de lehet meghal. Annyit tud még a cucc, hogy meg tudja mondani magáról, hogy pontos-e az idő, amit visszaad: vagyis ha elveszti a tápot majd ismét magához tér, akkor (ha megkérdezzük) meg tudja mondani hogy pontos-e, vagy az elem hibája miatt teljes hülyeséget kapunk vissza.

Végeredmény

Ami az egésznek a végső tanulsága: a felsorolt dolgokat könnyedén egybe tudjuk gyúrni. A TimeLib-nek van egy olyan nagyon okos funkciója, hogy periodikusan képes egy ún. SyncProvider-t kérdezgetni, hogy mennyi az idő. Ez lehet egy RTC, vagy GPS, vagy akárt NTP kliens is. (Ezekről majd később még fogok értekezni.) Esetünkben könnyen összehozható, hogy a rendszer mondjuk percenként (vagy akár óránként ha úgy szeretnénk) megkérdezze az RTC-nket és ehhez állítsa a saját belső "virtuális óráját". (setSyncProvider(getTimeFunction) és setSyncInterval(interval) metódusok kellenek ehhez.)

A szokásos probléma, hogy "nem nagyon van könnyen kezelhető felhasználói felületünk" pedig kiküszöbölhető egyszerűen: építeni kell egy olyan eszközt, amibe ha bedugjuk az RTC-nket, akkor azt internetről beállítja nekünk rajta az isőt. Ezután a már helyesen ketyegő RTC-t át lehet dugni a felhasználás helyére, ahol nem is kell legyen egy árva gomb se. Ezt a beállító-eszközt is be fogom majd mutatni, de ahhoz vagy wifi, vagy Ethernet modul fog kelleni, netán egy olyan Ardu típus, ami már eleve Wifi-vel van szerelve - mondjuk egy NodeMCU.

A bejegyzés trackback címe:

https://ardu.blog.hu/api/trackback/id/tr5513499295

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása