Arduino i czas czyli DS1307
Arduino nie ma wbudowanego zegara. Znaczy to, że pewne operacje związane z czasem da się przeprowadzać (opóźnienia o zadany interwał), ale już kontrolowanie czasu i daty nie jest takie proste.
Aby Arduino mogło wiedzieć dokładnie jaki jest czas potrzebny jest zewnętrzny układ zegara. Takim układem jest Dallas DS1307, dostępny na Nettigo.pl w formie modułu do Arduino. Moduł ten posiada podtrzymywanie bateryjne, więc czas raz ustawiony nie zostaje skasowany po wyłączeniu Arduino.
Montaż
Moduł jest zlutowany, ale kwestia podłączenia do Arduino pozostaje otwarta. Moduł wygląda tak:
W lewym górnym rogu znajduje czteropinowe złącze o rastrze (odstępie między pinami) 2.54 mm. Niestety nie posiadamy na razie w ofercie kabelków do tego złącza. Pozostaje kombinowanie samemu, lub podłączenie się przez gniazdo (do ICSP) i goldpiny. Elementy te są dostępne razem z modułem (jak widać na zdjęciu), ale trzeba je przylutować do modułu (proste nawet dla początkujących).
Korzystając z kabelka możemy moduł podłączyć do dowolnego kontrolera wspierającego protokół I2C.
Gniazdo do podłączenia ICSP (z którego moduł w takim układzie bierze zasilanie) ma dwie pozycje w które można go przylutować. Jedna jest dla Arduino Duemilanove (i klonów zgodnych jeśli chodzi o rozmiary i wyprowadzenie pinów) lub Seeeduino Mega. Moduł przy takim podłączniu (przez ICSP i goldpiny) nie współpracuje z Arduino Mega (wzajemne położenie pinów ICSP i wyjścia magistrali I2C są różne).
Oczywiście zawsze zostaje opcja przylutowania kabelków zamiast goldpina oraz ICSP i wtedy możemy podłączyć się do dowolnego mikrokontrolera wspierającego I2C. Jak wygląda moduł z przylutowanym gniazdem i goldpine oraz założony na Arduino pokazują poniższe zdjęcia:
Co możemy zrobić?
Zbudujemy teraz prosty zegar wyświetlający czas i datę na wyświetlaczu LCD. Podłączenie wyświetlacza jest identyczne jak w opisie LCD Kitu. Podłączamy LCD, zakładamy zlutowany moduł zegara i wygląda to mniej więcej tak:
Co widać na zdjęciu? Oprócz LCD Kitu widać połowę ScrewShielda, czyli rozwiązania na wypadające kabelki. Dzięki niemu podłączenie jest solidne i nie wypada nic nawet gdy lekko zostanie szarpnięte.
Moduł zegara założony w ten sposób zasłania złącza Analog oraz zasilania, co na pierwszy rzut oka utrudnia podłączanie. Faktycznie po założeniu modułu, raczej nie ma mowy o podłączeniu czegoś do wejść analogowych, ale jeżeli wygniemy kabelek korzystając z małych cążków możemy podłączyć się bez problemu przed założeniem modułu a na dodatek, przyciśnie on kable powodując że nie będą one łatwo wypadać. Tak właśnie zasilanie jest doprowadzone do modułu LCD:
Pozostaje tylko oprogramować całość. Oto szkic napędzający całość:
#include <LiquidCrystal.h> #include#include <Wire.h> #include #include //Ustawić zegar w setup czy nie? boolean SETUP=false; LiquidCrystal lcd (12,11,10,9,8,7); void setup() { Serial.begin(9600); lcd.begin(16,2); if (SETUP) { RTC.stop(); RTC.set(DS1307_SEC,1); //set the seconds RTC.set(DS1307_MIN,49); //set the minutes RTC.set(DS1307_HR,19); //set the hours RTC.set(DS1307_DOW,6); //set the day of the week RTC.set(DS1307_DATE,1); //set the date RTC.set(DS1307_MTH,5); //set the month RTC.set(DS1307_YR,10); //set the year RTC.start(); } } char time [20]; char date [20]; void getTime(char *t, char *d) { sprintf(t,"%.2i:%.2i:%.2i", RTC.get(DS1307_HR, true), RTC.get(DS1307_MIN, false), RTC.get(DS1307_SEC, false) ); sprintf(d, "%i/%i/%i", RTC.get(DS1307_DATE, false), RTC.get(DS1307_MTH, false), RTC.get(DS1307_YR, false) ); } void loop() { getTime(time, date); Serial.println(time); lcd.setCursor(0,0); lcd.print(time); lcd.setCursor(0,1); lcd.print(date); delay(1000); }
Biblioteka do obsługi modułu jest do ściągnięcia ze strony produktu, w zakładce Pliki.
Biblioteka dostarczona do modułu zajmuje się komunikacją z DS1307 poprzez I2C. Magistrala I2C na Arduino jest wyprowadzona w wejściach analogowych 4 i 5 – z nich nie będzie można korzystać do odczytywania wartości analogowych.
W szkicu zdefiniowana jest zmienna SETUP
, która ustawiona na true
spowoduje ustawienie zegara na z góry zaprogramowany czas. Zrobione to jest tak aby uprościć ninejszy szkic.
Czyli w treści programu w setup
ustawiamy jakiś czas z nieodległej przyszłości. SETUP
ustawiamy na true
i wgrywamy szkic. Arduino przestawi zegar, ale na razie się nie przejmujemy, że czas jest z przyszłości. Czekamy aż nadejdzie godzina ustawiona w setup
i w tym momencie albo włączamy Arduino ponownie, albo wgrywam szkic jeszcze raz. Funkcja setup
znowu ustawi czas, tym razem będzie dobry.
Teraz trzeba wgrać nowy szkic tym razem z SETUP
ustawionym na false
. Od teraz restart nie będzie ustawiał zegara od nowa.
Gwoli wyjaśnienia ustawienie zegara wykonuje się tak – zatrzymujemy zegar przez RTC.stop()
następnie ustawiamy wszystkie segmenty przez RTC.set()
korzystając z predefiniowanych stałych do określania sekund, minut, godzin, dni, miesięcy, roku oraz dnia tygodnia. Następnie zegar puszczamy, przez RTC.start()
. Jeżeli moduł ma założoną baterię wówczas czas będzie odmierzany non-stop i przy następnym starcie nie trzeba znowu używać RTC.start()
.
Mamy ustawiony czas, pozostaje go odczytać i wyświetlić. Do odczytu zegara wykorzystywana jest funkcja RTC.get(SEGMENT,odczyt_z_bufora)
. SEGMENT
to predefiniowana stała taka sama jak użyta w RTC.set
do ustawienia poszczególnych części czasu (minut, sekund, etc). Wartość odczyt_z_bufora
jest zmienną typu logicznego (boolean) i jeżeli jest ustawiona na true
wówczas biblioteka odpyta układ DS1307 o czas i zachowa jego odczyt w buforze, tak aby następne RTC.get
z ustawionym odczyt_z_bufora
na false miały zagwarantowane, że odczytują ten sam czas (bo można sobie wyobrazić, że kolejne odczyty zostaną dokonane po zmianie czasu np z 23:59:59 na 00:00:00).
W powyższym szkicu odczyt czasu odbywa się w funkcji getTime
biorącej dwa argumenty – bufory znakowe w które zostanie zapisany odpowiednio czas i data, sformatowane dzięki funkcji sprintf
. Pozostaje jeszcze tylko wyświetlić odczytane wartości w dwóch liniach wyświetlacza. Dzieje się to już w pętli loop
.
Szkic do pobrania tutaj.
Pozostaje jeszcze pokazać jak wygląda całość w działaniu:
odradzam klejenie goldpinów, co w przypadku kiedy będziemy chcieli wylutować takie piny?proces odwrotny utrudniony.sa latwiejsze sposoby lutowania i to bez pomocy imadla i kleju.wystarczy jedna reka przytrzymac jednoczesnie i plytke i piny a druga-lutownica zlapac sobie tylko 1 pin.
pozniej juz mamy dwie rece i mozemy swobodnie lutowac.
pozdrawiam
gość
To chyba bardziej uwaga do https://starter-kit.nettigo.pl/2010/05/lutowanie-goldpin-a/ ale nie zmienia to faktu że słuszna. Ja jednak stałem się zwolennikiem trzeciej ręki, bo jest to wygodne.
Jest jeszcze jedna metoda – płytka stykowa – wsadzić goldpiny w płytkę stykową, nałożyć płytkę do przylutowania, czasem trzeba jeszcze coś podłożyć, żeby było równo i można jechać z lutowaniem. Z powodzeniem stosuję tę metodę do lutowania pinów w LCD Kitach (http://nettigo.pl/product/2x16_LCD_kit_kit-lcd-2×16) – sprawdza się
Mam problem z uruchomieniem płytki seeed studio na moim ARDUINO UNO R3. Wszystko podłączone jest prawidłowo, ale szkic podany w linku (https://starter-kit.nettigo.pl/zrodla/rtc/ds1307.pde) nie chce się kompilować. Podejrzewam, że wynika to z braku potrzebnych bibliotek np. Wprogram.h, Wconstants.h stdio.h . Standardowe oprogramowanie nie posiada takich bibliotek, szukając po googlach też nie znalazłem. Skąd to ściągnąć? Proszę o pomoc.
@Kamil
http://forum.nettigo.pl/topic/arduino-uno-r3-ds1307-shield
Na razie trzeba ściągnąć IDE 023 i tam powinno działać, dam znać kiedy będzie dostępna biblioteka działająca z 1.0
Niestety moduł jest niedostępny w ofercie sklepu. Wiadomo kiedy się pojawi ?
Raczej się już nie pojawi. Seeed go wycofał. Zamiast niego będzie inny, nieco mniejszy moduł też oparty o DS1307. Planowana dostępność – koniec kwietnia.
Dobrze wiedzieć. Bo potrzebuję zmontować mały przenośny rejestratorek na nano, więc RTC będzie potrzebne. Podobnie jak adapter mikroSD, którego też nie ma ( będzie ?)