Zegar czasu rzeczywistego RTC DS1307
DS1307 to chyba jeden z najpopularniejszych układów RTC służących do odmierzania czasu w projektach Arduino podczas tworzenia różnego rodzaju zegarków. Układ ten możemy swobodnie kupić już za około 3 zł, dlatego też jest bardzo chętnie wykorzystywany w ogromnej ilości gotowych modułów.
Ma tu wpływ nie tylko jego cena, ale zdolność komunikacji z naszym mikrokontrolerem za pośrednictwem magistrali I2C.
DS1307 posiada możliwość zasilania bateryjnego z zakresu 2V ÷ 3.5V, które ma na zadanie podtrzymanie pracy zegara po zaniku głównego zasilania układu. Napięcie zasilania może mieścić się w zakresie od 4.5V ÷ 5.5V przy poborze prądu na poziomie 1mA. Do poprawnego działania wymagany jest zewnętrzny kwarc 32.768Hz o pojemności obciążenia CL=12.5pF.
Warto tutaj wspomnieć o dodatkowych właściwościach układu, takich jak generator przebiegu prostokątnego, o częstotliwościach 1Hz, 4096Hz, 8192Hz lub 32768Hz. DS1307 oferuje również podtrzymywaną bateryjne pamięć o rozmiarze 56 bajtów. Te dwie cechy są sukcesywnie pomijane przez twórców bibliotek oraz producentów gotowych modułów, poprzez nie umieszczanie wyprowadzenia do odpowiedniego pinu SQW/OUT.
A szkoda - sygnał 1Hz możemy wykorzystać do obsługi przerwania aktualizacji wyświetlania czasu na ekranie LCD lub podłączenia mrugającego dwukropka pomiędzy godziną a minutą, oszczędzając tym samym pin cyfrowy Arduino i miejsce w pamięci na zbędny fragment programu. Ale o tym późnej.
Układ DS1307 dostępny jest w dwóch obudowach SO-8 oraz DIP-8. W obu wariantach, rozkład nóżek jest identyczny:
Dokumentacja techniczna: https://www.jarzebski.pl/datasheets/DS1307.pdf
Schemat połączeń
Połączenie DS1307 jest bardzo proste. Podłączamy zasilanie 5V (nóżka 8), masę GND (nóżka 4) oraz kwarc zegarkowy 32768Hz pomiędzy nóżki 1 i 2 . Jak wspomniałem wcześniej, układ ten komunikuje się z Arduino za pomocą magistrali I2C, a więc SCL (nóżka 6) do pinu A5, a SDA (nóżka 5) do pinu A4. Nie zapomnijmy podciągnąć linii sygnałowych rezystorami o wartości 10kΩ do zasilania 5V.
Należy zwrócić tutaj szczególną uwagę na wyjście SQW/OUT, które również podciągamy rezystorem o wartości 10kΩ do zasilania 5V. Jest to element wymagany ponieważ wyjście SQW/OUT działa w układzie otwartego drenu. Dodatkowo jeśli chcemy podłączyć do niego diodę LED, należy podłączyć tutaj katodę, anodę zaś - do zasilania. Jeśli nie planujemy korzystać z SQW/OUT, możemy pozostawić je "w powietrzu".
Ja zamiast baterii 3V podłączyłem zwykłe zasilanie 3.3V z Arduino. W normalnych warunkach oczywiście skorzystajmy z baterii :)
Prosty przykład
Do obsługi modułów z układami DS1307 przygotowałem bibliotekę dla Arduino, którą można pobrać z repozytorium Git: https://github.com/jarzebski/Arduino-DS1307. Bazuje ona bibliotekach JeeLabs oraz Adafruit, jednak oferuje ona dodatkowe funkcje do sterowania wyjściem SQW/OUT, dostępu do pamięci układu oraz formatowanie daty na wzór date() z PHP.
- #include <Wire.h>
- #include <DS1307.h>
- DS1307 clock;
- RTCDateTime dt;
- void setup()
- {
- Serial.begin(9600);
- // Inicjalizacja DS1307
- Serial.println("Inicjalizacja DS1307");;
- clock.begin();
- // Jeśli nie ustawiono daty, ustawiamy
- if (!clock.isReady())
- {
- // Data i czas z momentu kompilacji
- clock.setDateTime(__DATE__, __TIME__);
- }
- }
- void loop()
- {
- dt = clock.getDateTime();
- Serial.print("Raw data: ");
- Serial.print(dt.year); Serial.print("-");
- Serial.print(dt.month); Serial.print("-");
- Serial.print(dt.day); Serial.print(" ");
- Serial.print(dt.hour); Serial.print(":");
- Serial.print(dt.minute); Serial.print(":");
- Serial.print(dt.second); Serial.println("");
- delay(1000);
- }
Formatowanie daty
Jeśli chcemy wyświetlić czas i datę w odpowiednim dla nas formacie, możemy skorzystać z funkcji dateFormat().
- #include <Wire.h>
- #include <DS1307.h>
- DS1307 clock;
- #include <DS1307.h>
- void setup()
- {
- Serial.begin(9600);
- // Inicjalizacja DS1307
- Serial.println("Inicjalizacja DS1307");;
- clock.begin();
- // Jeśli nie ustawiono daty, ustawiamy
- if (!clock.isReady())
- {
- // Data i czas z momentu kompilacji
- clock.setDateTime(__DATE__, __TIME__);
- // UNIX timestamp
- // clock.setDateTime(1397408400);
- // Recznie (YYYY, MM, DD, HH, II, SS
- // clock.setDateTime(2014, 4, 13, 19, 21, 00);
- }
- }
- void loop()
- {
- dt = clock.getDateTime();
- Serial.print("Long number format: ");
- Serial.println(clock.dateFormat("d-m-Y H:i:s", dt));
- Serial.print("Long format with month name: ");
- Serial.println(clock.dateFormat("d F Y H:i:s", dt));
- Serial.print("Short format witch 12h mode: ");
- Serial.println(clock.dateFormat("jS M y, h:ia", dt));
- Serial.print("Today is: ");
- Serial.print(clock.dateFormat("l, z", dt));
- Serial.println(" days of the year.");
- Serial.print("Actual month has: ");
- Serial.print(clock.dateFormat("t", dt));
- Serial.println(" days.");
- Serial.print("Unixtime: ");
- Serial.println(clock.dateFormat("U", dt));
- delay(1000);
- }
Dostęp do pamięci o rozmiarze 56B
Jak już wiemy, DS1307 oferuje nam pamięć o rozmiarze 56 bajtów, której zawartość jest podtrzymywana bateryjnie. Dostęp do tej pamięci odbywa się poprzez dwie funkcje writeByte() oraz readByte(). W ramach przykładu została ona zapisana wartościami 0xFF - 0xC8, a następnie odczytana.
- #include <Wire.h>
- #include <DS1307.h>
- DS1307 clock;
- char tmp[16];
- void setup()
- {
- Serial.begin(9600);
- // Inicjalizacja DS1307
- Serial.println("Initialize DS1307");
- clock.begin();
- // Wypelniamy pamiec
- Serial.println("Filling memory");
- for (byte i = 0; i < 56; i++)
- {
- clock.writeByte(i, 255-i);
- }
- Serial.println("... Done");
- Serial.println();
- }
- void loop()
- {
- // Odczyt pamieci
- Serial.println("Reading memory");
- Serial.println();
- Serial.print(" ");
- for (byte i = 0; i < 16; i++)
- {
- sprintf(tmp, "0x%.2X ", i, 2);
- Serial.print(tmp);
- }
- Serial.println();
- Serial.println("---------------------------------------------------------------------------------------");
- for (byte j = 0; j < 4; j++)
- {
- sprintf(tmp, " 0x%.2X : ", (j*16), 2);
- Serial.print(tmp);
- for (byte i = 0; i < 16; i++)
- {
- if ((j*16 + i) > 55)
- {
- break;
- }
- sprintf(tmp, "0x%.2X ", clock.readByte(j*16 + i), 2);
- Serial.print(tmp);
- }
- Serial.println();
- }
- delay(5000);
- }
Generator przebiegu prostokątnego SQW
W tym przykładzie możemy zobaczyć jak włączyć generator przebiegu prostokątnego. Należy skonfigurować odpowiedni rejestr wybierając interesującą nas częstotliwość i włączyć SQW. Sygnał ten możemy wykorzystać do obsługi przerwania lub podłączyć diodę LED jako sygnalizator sekund, oszczędzając tym samym cyfrowy pin Arduino. Działanie możecie zobaczyć na filmie znajdujący się na końcu artykułu.
- #include <Wire.h>
- #include <DS1307.h>
- DS1307 clock;
- void setup()
- {
- Serial.begin(9600);
- // Inicjalizacja DS1307
- Serial.println("Initialize DS1307");;
- clock.begin();
- // Ustawiamy date
- if (!clock.isReady())
- {
- // Data i czas z momentu kompilacji
- clock.setDateTime(__DATE__, __TIME__);
- }
- // Wybieramy 1Hz
- clock.setOutput(DS1307_1HZ);
- switch (clock.getOutput())
- {
- case DS1307_LOW: Serial.println("SQW = LOW"); break;
- case DS1307_HIGH: Serial.println("SQW = HIGH"); break;
- case DS1307_1HZ: Serial.println("SQW = 1Hz"); break;
- case DS1307_4096HZ: Serial.println("SQW = 4096Hz"); break;
- case DS1307_8192HZ: Serial.println("SQW = 8192Hz"); break;
- case DS1307_32768HZ: Serial.println("SQW = 32768Hz"); break;
- default: Serial.println("SQW = Unknown"); break; }
- }
- void loop()
- {
- }
Wyjście SQW jako pin cyfrowy
Wyjście SQW możemy również skonfigurować jako dodatkowy pin cyfrowy OUT, który traktujemy tak samo jak pin cyfrowy w Arduino. Działanie możecie zobaczyć na filmie znajdujący się na końcu artykułu.
- #include <Wire.h>
- #include <DS1307.h>
- DS1307 clock;
- boolean state;
- void setup()
- {
- Serial.begin(9600);
- // Inicjalizacja DS1307
- Serial.println("Inicjalizacja DS1307");;
- clock.begin();
- }
- void loop()
- {
- // Ustawiamy wyjscie
- clock.setOutput(state);
- // Zmieniamy stan
- state = !state;
- // Opoznienie
- delay(100);
- }
Za wolno, za szybko. Kwarc to bardzo ważna rzecz
Bardzo ważnym elementem w zegarach czasu rzeczywistego jest odpowiedni dobór i montaż zewnętrznego rezonatora kwarcowego. Najczęściej stosowane są tutaj tak zwane kwarce zegarkowe 32768 Hz o dokładności ±20ppm. Aby zrozumieć dokładniej problem dokładności zegarów RTC musimy zastanowić się, jaki może być błąd czasu dla kwarców tego typu.
PPM to skrót od angielskiego terminu Parts Per Milion. Innymi słowy oznacza, o ile części na jeden milion może pomylić się ów kwarc. Na początek obliczmy sobie procentowy błąd dla typowej wartości 20ppm.
δF = = (20ppm / 1000000) * 100% = 0,002%
Niby nie dużo, ale przeliczając to na dobę, uzyskujemy całkiem pokażną wartość:
(0.002 [%] * 86400 [s]) / 100% = 1.728 [s]
W ciągu doby nasz zegarek może pomylić się w skrajnym przypadku o 1.728 sekundy, a w ciągu miesiąca prawie o 53 sekund, rocznie zaś prawie o 10 minut. Oczywiście wartość ta może być niższa ze względu na to, że kwarc może pomylić się o mniejszą ilość impulsów, zarówno w górę jak i w dół.
Należy zwrócić uwagę, że błąd ten jest silnie zależny od temperatury otoczenia w jakich pracuje kwarc. Typowe kwarce zegarkowe optymalizowane są najczęściej do pracy w temperaturze 25°C, gdzie błąd powinien wynosić 0%. Oczywiście w praktyce nie jest to możliwe. Zależność wielkości ppm od temperatury przedstawia krzywa obok, która jest zawsze podawana w karcie katalogowej danego kwarcu.
Jak widzimy na wykresie, dokładność ±20ppm obowiązuje dla zakresu temperatur 2°C ÷ 48°C. Analogicznie - jeśłi nasz kwarc pracowałby w temperaturze od 10°C ÷ 40°C to dokładność takiego kwarcu powinna mieścić się w granicach ±10ppm.
Jeśli jednak nasz zegar myli się powiedzmy o 5 sekund na dobę, a nie pracuje w ekstremalnej temperaturze -10°C lub 60°C, to jego dokładność jest o wiele mniejsza i wynosi:
5 [s] / 86400 [s] = 0,000057 = 57 ppm
Otrzymane 57 ppm oznacza tyle, że diabeł się nim interesuje :) Ale na poważnie, przyczyn może być kilka:
- Nasz kwarc 32768Hz nie posiada wymaganej pojemności obciążenia CL=12.5pF, dlatego warto sprawdzić co kupiliśmy,
- Nasz kwarc pamięta czasy stanu wojennego. Kwarce podlegają procesowi starzenia, który wynosi około. ±5 ppm/rok. Jeśli kwarc leżakował u sprzedawcy 2 lata to zamiast deklarowanych ±20ppm w danym zakresie temperatur, może być już ±30ppm.
- Na kwarc działają zakłócenia z pobliskich ścieżek, w których występują sygnały szybko zmienne,
- Kwarc jest po prostu wadliwy
A więc, aby zminimalizować błąd zegara musimy posiadać odpowiedni kwarc. Dodatkowo powinien on znajdować się jak najbliżej nóżek DS1307, ale w większej odległości od ścieżek sygnałowych. Zalecaną metodą jest również otoczenie połączenia kwarcu z układem pierścieniem masy (Guard ring). Jeśli mamy możliwość zaprojektowania płytki na dwóch warstwach, możemy otoczyć pole na którym znajduje się kwarc dodatkową masą (Local ground plane) i przylutować do niej metalową obudowę. Odradzane jest również prowadzenie jakichkolwiek ścieżek sygnałowych w tych obszarach.
Jeśli spełnimy wszystkie powyższe warunki... to i tak nasz zegarek nie będzie odmierzał czasu dokładnie (tada!). Nawet jeśli zapewnimy mu przez cały czas jego pracy idealną temperaturę 25°C.
Kwarce z kompensacją temperaturową
Jak już pewnie zdążyliście zauważyć, największym problemem jest tutaj czynnik temperatury. Istnieje kilka metod poprawy dokładności kwarców. Możemy zastosować trymer poprawiając jego stabilność, możemy co jakiś czas synchronizować czas z zewnętrznego wzorca (np.: komputera). Możemy oczywiście skorzystać z innych układów RTC z wbudowaną kompensacją temperatury (DS3231). Jednak jeśli zależy nam na DS1307 warto zainteresować się oscylatorem DS32kHz z kompensacją temperaturową (TCXO).
DS32kHz dostępny jest w obudowach SO oraz EDIP. W naszym przykładzie wykorzystamy ten w obudowie EDIP.
Dokumentacja techniczna: https://www.jarzebski.pl/datasheets/DS32kHz.pdf
Jego dokładność w zakresie temperatury 0°C ÷ 40°C wynosi aż ±2ppm, a w zakresie temperatur przemysłowych -40°C ÷ 85°C aż ±7.5ppm. Dla porównania obliczmy odchyłkę czasu dla 2ppm:
δF = = (2ppm / 1000000) * 100% = 0,0002%
(0.0002 [%] * 86400 [s]) / 100% = 0.1728 [s] na dzień
0.1728 [s] * 355 [dni] = 61 [s] na rok
podczas gdy standardowy kwarc zegarkowy
1.728 [s] * 355 [dni] = 613 [s] na rok
Schemat połączenia DS32kHz i DS1307
Podłączenie DS1307 pozostaje bez zmian. Jedyną różnicą jest podłączenie pod X1 i X2 rezystora o wartości 33kΩ. Wyjście 32KHZ z DS32kHz (nóżka 12) podłączamy natomiast do X1 poprzez szeregowo połączony rezystor 1MΩ i kondensator 100pF. Oczywiście DS32kHz wymaga również zasilania bateryjnego w przypadku zaniku zasilania głównego. Cały układ zasilamy napięciem 5V i podłączamy do masy (wymagane jest również podłączenie wszystkich pinów NC do masy). DS32kHz posiada jeszcze inne warianty zasilania, ale o nich możecie poczytać w dokumencie PDF (strona 7).
Od teraz, wasz zegarek będzie stabilny jak skała.
Jak to działa?
Materiały dodatkowe
Dokumentacja techniczna: https://www.jarzebski.pl/datasheets/DS32kHz.pdf
Dokumentacja techniczna: https://www.jarzebski.pl/datasheets/DS1307.pdf
Biblioteka Arduino: https://github.com/jarzebski/Arduino-DS1307
Reklama
Komentarze
piekny wpis poczyniles ... az milo sie czyta w tak piekny, piedzialkowy ranek
Wielkie dzięki :) miło czyta się komentarze uznania :>
mam problem, skopiowałem pierwszy program z artykułu. Na monitorze pokazuje się "Inicjalizacja DS1307", ale nic dalej. Gdzie może leżeć problem? z góry dzięki.
Witaj, wygląda na to, że nie możesz zapisać aktualnego czasu do DS. Spróbuj skorzystać z clock.setDateTime(2014, 4, 13, 19, 21, 00) zamiast wywołania clock.setDateTime(__DATE__, __TIME__);
Ewentualnie pomiń IF-a i zobacz czy zegar będzie pokazywał cokolwiek od 2000:01:01.
Jeśli nic się nie będzie działo. może oznaczać problem z komunikacją lub wadliwy układ.
Posiadasz Arduino UNO? W nim SDA/SCL są podpięte pod piny analogowe. W innych płytkach mogą to być osobne piny.
Witam,
Przy próbie weryfikacji któregokolwiek przykładu z tych dołączonych do biblioteki, mam następujący błąd:
DS1307_dateformat:15: error: \'RTCDateTime\' does not name a type
DS1307_dateformat.ino: In function \'void setup()\':
DS1307_dateformat:23: error: \'class DS1307\' has no member named \'begin\'
DS1307_dateformat:26: error: \'class DS1307\' has no member named \'isReady\'
DS1307_dateformat:29: error: \'class DS1307\' has no member named \'setDateTime\'
DS1307_dateformat.ino: In function \'void loop()\':
DS1307_dateformat:41: error: \'dt\' was not declared in this scope
DS1307_dateformat:41: error: \'class DS1307\' has no member named \'getDateTime\'
DS1307_dateformat:44: error: \'class DS1307\' has no member named \'dateFormat\'
DS1307_dateformat:47: error: \'class DS1307\' has no member named \'dateFormat\'
DS1307_dateformat:50: error: \'class DS1307\' has no member named \'dateFormat\'
DS1307_dateformat:53: error: \'class DS1307\' has no member named \'dateFormat\'
DS1307_dateformat:57: error: \'class DS1307\' has no member named \'dateFormat\'
DS1307_dateformat:61: error: \'class DS1307\' has no member named \'dateFormat\'
Proszę o pomoc
EN
Zobacz czy przypadkiem nie masz innej biblioteki DS1307 (może masz dwie w libraries/ i sketch ładuje nie tą co trzeba)
Czy jest opcja sprawdzenia ilości dni miesiąca dla wybranego roku i miesiąca? (nie chodzi mi o sprawdzenie danych z fizycznego zegara)
jest operator "t" clock.dateFormat("t", dt) - jako dt podaj interesującą Cię datę
RTCDateTime dt;
Artykuł jest znakomity!
Pytania:
1. >> if (!clock.isReady())
Czy to również sprawdza czy czas jest aktualny w RTC?
Potrzebuję żeby podczas wgrywania programu, sprawdzało czy czas jest aktualny i jeśli nie to żeby go aktualizowało.
2. Today is: Unknown, 95 days of the year.
W jaki sposób to naprawić? Powinno być Monday - poniedziałek. Zapewne jest w kodzie jakiś błąd lub gdzieś indziej - moduł.
Dzięki!
Co do pierwszego, niestety nie jest to wykonywalne, ponieważ __DATE__ i __TIME__ zawierają czas kompilacji, natomiast clock.isReady() zwraca true, jeśli czas był ustawiany. Więc kiedy zresetujesz układ i pozbędziesz się if-a, zawsze będzie Ci wbijał wkompilowany czas kompilacji
Co do dwójki, ktoś mi to już zgłaszał w DS3231, poprawię to na dniach na githubie
Jakiej wersji IDE używasz? Bo wygląda na to, że jakoś odczytał Ci dzień spoza przedziału 1-7 ;D
Szanowny Panie.
Bardzo się ucieszyłem, gdy odnalazłem Pana stronę z opisem sposobu korzystania z zegara SD3231. Niestety po wielu próbach, w moim przypadku, jest to niemożliwe.
Pobrałem plik *.zip, instalowałem w folderze arduino, przesuwałem, ale i tak wyświetlały się błędy:
DS3231_simple.cpp:16:1: error: ‘RTCDateTime’ does not name a type
DS3231_simple.cpp: In function ‘void setup()’:
DS3231_simple.cpp:24:9: error: ‘class DS3231’ has no member named ‘begin’
DS3231_simple.cpp:27:9: error: ‘class DS3231’ has no member named ‘setDateTime’
DS3231_simple.cpp: In function ‘void loop()’:
DS3231_simple.cpp:32:3: error: ‘dt’ was not declared in this scope
DS3231_simple.cpp:32:14: error: ‘class DS3231’ has no member named ‘getDateTime’
Z wcześniejszych komentarzy wynika, że wszystko działa. Dla mnie pewne rzeczy są nie do przeskoczenia. Opanowałem ważne dla mnie fotorezystory, zapis wyników pomiarów na kartę SD, ale w żaden sposób nie mogę uruchomić zegara. Od około trzech dni wertuję strony anglojęzyczne i nic.
Uprzejmie Pana proszę o podpowiedź.
Prawdopdobnie masz jeszcze jedną bibliotekę DS3231 i nie łapie Ci mojej
"Dodatkowo jeśli chcemy podłączyć do niego diodę LED, należy podłączyć tutaj katodę, anodę zaś - do masy."
Czy aby na pewno?
Wyjście pracuje jako otwarty dren , zawsze możesz podłączyć diodę na odwrót :)
Zerknij proszę na schemat.
Masz na nim Led1 przyłaczoną do masy.
Natomiast na zdjęciach i filmie Led1 jest przyłączona do plusa zasilania.
Dioda podłączona jak na schemacie nie ma prawa się zapalić.
(Chyba, że podłączysz do niej napięcie ujemne)
Zakupiłem sobie kiedyś moduł z układem DS1307
http://electropark.pl/rtc-zegary-czasu-rzeczywistego/4789-modul-zegara-czasu-rzeczywistego-rtc-z-ukladem-ds1307.html
i mam dziwne wrażenie, że coś z nim nie jest tak.
Porównując jego wskazania ze wskazaniami modułu
http://electropark.pl/rtc-zegary-czasu-rzeczywistego/4409-modul-rtc-wysokiej-precyzji-z-i2c-ds3231.html
zauważyłem, że spieszy się o jakieś 20 sekund na dobę. To raczej sporo i zastanawiam się, czy po prostu mam wadliwy egzemplarz czy coś z tym można jeszcze zrobić?
Kwarc, kwarc :) albo dodaj DS32kHz
Znaczy kwarc do wymiany, a co masz na myśli pisząc "dodaj DS32kHz"?
Co miałbym dodać?
OK, już załapałem. Chyba za dużo tematów na raz obrabiam. Przeczytałem jeszcze raz ostatni akapit tego wpisu :)
Muszę to sprawdzić w realu zatem.
Witam. Co muszę zrobić, aby korzystając z funkcji dateFormat zamiast anglojęzycznych skrótów miesięcy: "Jan"..."Dec", wyświetlały mi się polskojęzyczne skróty: "Sty"..."Gru"? Z góry dziękuję za pomoc. Pozdrawiam!
Witam, na wstępnie wielki pozytyw za artykuł.
Przy okazji zapytam mam problem z ręcznym ustawieniem czasu gdy podaję komendę
clock.setDateTime(__DATE__, __TIME__);
Zegar działa jak w opisie natomiast problem zaczyna się gdy użyję
clock.setDateTime(2014, 4, 13, 19, 21, 00);
na LCD pojawia się nie wiadomo z kąt godzina 7:56:47
Czy mogę prosić o podpowiedź w jaki sposób najprościej edytować ręcznie zmienne RTC w układzie np. klawiszami ?
Możesz mi wytłumaczyć co dokładnie onacza ta linia w pliku DS1307.h
#define DS1307_ADDRESS (0x68)
Dlaczego DS1307_ADDRESS i (0x68)
Dziękuję bardzo.
Mam taki problem że jak próbuję wyświetlić ta date na lcd to mi krzaczory wyskakują. LCD jest sprawny i inne komunikaty działają normalnie.
Jak wysyłasz wyniki ? :) Może typ zmiennej inny
Doberek.
Zakupiłem u skośnookich braci cały moduł zegara z wbudowanym kwarcem, gniazdem na baterie (akumulator) itd. Za jedną przesyłką wziąłem 3 szt. Po wgraniu programu zegarek odpala się na serialu jak i na LCD bez problemu. Jednak kiedy włożę mu aku lub baterię, UNO się zwiesza. Serial przestaje odpowiadać LCD przygasa bez wyświetlania żadnej linii. Myślałem, że układ jest walnięty, ale na wszystkich 3 szt. to samo.
Jakieś pomysły??
Pozdrawiam Ury
Do modułu włożyłem akumulator 3,2V i wszystko działało przez jakiś czas. Następnie zawiesza się jak opisałeś. Okazało się, że przyczyną może być zbyt wysokie napięcie podawane z baterii. Zmierzyłem 4,4V! Czy ktoś zna rozwiązanie? A może te moduły pracują poprawnie tylko na 3,3 a nie 5V?
WItam, proszę spróbować wymienić naterię CR2032 3,0V na akumulator o tych samych wymiarach np.: LI-ION 2032 o napięciu 3,6V. Zdecydowanie pomoże i nie będzie powodował uszkodzeń baterii.
Hardwarowym rozwiązaniem jest też zmiana rezystora w układzie ładowania akumulatora (wszystkie płytki z zegarem RTC z pojemnikiem na baterię guzikową posiadają układ ładowania, który składa się z wdóch elementów - diody i rezystora (ok 200 Ohm)). Należy wylutować tezystor i wtedy układ nie będzie ładować baterii i tym samym uchroni ją od zniszczenia.
Układ na baterii litowej 3,0V będzie działać długoooo bo pobór prądu z baterii jest na poziomie ok 20-30 nA.Moim zdaniem bateria wystarczy na ok 3-5 lat pracy.
Pozdrawiam
JarekArduino :)
Jeszcze mała poprawka: właśnie przeczytałem w datasheetach, że przy użyciu zwykłaj baterii litowej 3,0 (bez żadnego układu ładowania, czyli samo podłączenie do nóżki RTC o nazwie Vbat) powinno zapewnić prawidłowe działanie baterii przez okres 10 lat!
tu fragment oryginalnego wpisu:
"Backup Supply Input for Any Standard 3V Lithium Cell or Other Energy Source. Battery voltage must be held between the minimum and maximum limits for proper operation.Diodes in series between the battery and the VBAT pin may prevent proper operation. If a
backup supply is not required, VBAT must be grounded. The nominal power-fail trip point VPF) voltage at which access to the RTC and user RAM is denied is set by the internal circuitry as 1.25 x VBAT nominal. A lithium battery with 48mAhr or greater will back up
the DS1307 for more than 10 years in the absence of power at +25°C.
http://pdf1.alldatasheet.com/datasheet-pdf/view/226599/MAXIM/DS1307.html
Pozdrawiam
jarekArduino :)
Świetny wpis. Dziękuję
Witam Pana Panie Korneliuszu:)! Dosłownie kilka dni temu natknąłem się na Pana stronkę i jestem bardzo wdzięczny za:
Przede wszystkim za fajne tematy, które Pan porusza, przedstawia i doskonale wyjaśnia tajniki programowania i konstruowania z "lego" Arduino. Jestem niezmiernie wdzięczny za nareszcie działające skecze ( projekty czy jak kto je tam nazywa...),
Osobiście jestem elektronikiem, ale z epoki powiedzmy "tranzystorów germanowych" ale za namową syna zainteresowały mnie bardzo projekty oparte na platformie Arduino i choć wiele osób przedstawia swoje pomysły i wykorzystanie płytki z różnymi shieldami, nie wiele jest osób tak wspaniale przedstawiających o informatyce jak Pan! Gratuluję i proszę nie przestawać to robić.
Ja wiem, że wiele wpisów jest sprzed kilku lat, ale to nic, odnajdują Pana stronkę wciąż nowe osoby i taka skarbnica wiedzy praktycznej jest (przynajmniej dla mnie) wielkim bogactwem przykładów.
Pozdrawiam i 3mam kciuki
Jarek Kuleszewicz
Zainteresowałem się ostatnio zegarem RTC DS1307, taki egzemplarz zakupiłem z rozmachem na "Alle...", cóż płytka dotarła do mnie bez bateryjki 2032 na którą to jest specjalny koszyczek.
Wpadłem na pomysł aby zrobić zegar z wykorzystaniem wyświetlacza LCD 2x16. W międzyczasie dowiedziałem się że niestety nie może to być bateria litowa, gdyż można ją uszkodzić przy długotrwałym bombardowaniu prądem ok 15-20 mA. Takim prądem jest zasilana bateria na płytce i powinno się używać akumulatorek Litowo-Jonowy (LI-ion) o tym samym symbolu 2030, ale o napięciu nie 3V! tylko 3,6V i wszystko będzie ok.
co do zegarka to chcę zrobić taki zegar RTC z wykorzystaniem wyświetlacza LCD 2x16, sterowanie wyświetlaczem poprzez I2C , jest taki shield o nazwie FC113 o adresie (0x27), zegar RTC DS1307 posiada adres (0x50), a zamieszczona na płytce zegara pamięć (0x68).
Muszę troszkę przerobić Pana projekt "Formatowanie daty" aby sterował wyświetlaczem i2c i dorzucić kilka przycisków, to ustawiania zegarka i być może alarmu budzika.
Po wgraniu projektu na płytkę Arduino Uno, mam problem bo nie kompiluje mi się projekt wyrzucając kilka błędów a mianowicie:
ZegarRTC1_DS1307_formdata:31: error: \'dt\' was not declared in this scope
dt = clock.getDateTime();
Problemem okazuje się mała pomyłka w linii 5
#include powtórzenie tej samej deklaracji biblioteki, nie jet to jednak błąd tylko tu powinna być chyba deklaracja zmiennej \'dt\' czyli: RTCDateTime dt;
po zamianie projekt działa ok!
POzdrawiam :)
jarekArduino
Minęło półtora roku od czasu gdy autor zorientował się, ze ma błąd z diodą LED na schemacie i nadal nie poprawił ani schematu ani opisu. Nadal LED\'a ma anodę na minusie i nadal w opisie jest, że anodę należy dołączyć do plus. A to przecież nie zadziała. Na dodatek - tak jak inny komentator wspomniał, na filmie wyraźnie widać, że anodę dołączono do plusa.
Ogólnie podziękowania za przyjemny i pomocny artykuł.
W komentarzu wyżej z automatu napisałem poprawnie, że anoda do plusa. A w opisie jest do minusa. Prośba o dokonanie korekty opisu i schematu aby wszystko było jak należy.
Pozdrawiam!
Nie mogę sobie poradzić z zamianą UNIX time na minuty a potem na godziny ?:/
tzn? Ustawiasz clock.setDateTime(unixtime) i potem normalnie odczytujesz
Witam. Od razu napiszę że jestem laikiem. Czy wymiana DS1307 wiąże się z tym, że zegar będzie trzeba programować na nowo? Nie mam na myśli ustawiania czasu i daty. Mam zegar lampowy który zaczął czasem pokazywać przypadkowe liczby podczas wyświetlania czasu i daty. Czy wystarczy wymienić element ?
Pozdrawiam
Dzień dobry, na wstępie gratulacje za fachowo zrobiony artykuł o zegarek DS1307. Nie zajmuję się Arduino zawodowo również nie mam skończone studia na ten kierunek, jestem po prostu zwykłym pasjonatem ale to nie oznacza że jestem nowicjuszem programowania Arduino. Chciałbym odnosić o to że mimo wiele prób i czyścienie folder libray od starych bibliotek nie udało mi się prowadzić Pana biblioteka do kompletnego zadziałania. Mi chodzi szczególnie o funkcję do formatowania clock.dateFormat() która oddaje mi zawsze puste pole. Założyłem zegarek DS1307 na Arduino Mega wszystko działa oprócz tej funkcji.
Połączenie elektryczne:
DS1307 nóżka Arduino Mega pin
SDA-------------------> SDA (20)
SCL-------------------> SCL (21)
VCC-------------------> 5V+
GND-------------------> GND
Czekam na Pana sugestie. Dziękuję i pozdrawiam.
Witam,
Czy Pana biblioteka umożliwia ustawienie alarmu o zadanej godzinie, w wybrany dzień tygodnia? Próbuje stworzyć rodzaj harmonogramu.
W jaki sposób to zrealizować?
Pozdrawiam
Najlepsza biblioteka do obsługi DS1307! Inne faktycznie często nie obsługują SQW. Nie rozumiem jak można bez tej funkcjonalności robić jakikolwiek zegarek. Jedyna słuszna droga to SQW+przerwanie na porcie ukontrolera.
Jeszcze raz dzięki :D
Najlepsza bibliotek - niestety - "była"
Nie rozwijana od kilku lat - nie działająca funkcjonalność clock.format - a szkoda - bo początkowo była biblioteką idealną.
Zegar DS1307 nie trzyma czasu. Co może być przyczyną. Po odłączeniu zasilania pamięta czas, ale się zatrzymuje i od tego momentu ponownie zlicza.
Wykorzystywałem bibliotekę od 2016 roku a teraz po długiej przerwie z arduino powróciłem i wyskakuje mi informacja podczas kompilacji, a po wgraniu do ardu - arduino się cyklicznie zawiesza. W chwili obecnej mam następującą konfiguracje:
Arduino IDE na linux mint: 1.8.12
Arduino Uno
Poniżej fragment ostrzeżenia podczas kompilacji:
"
/home/grzegorz/Arduino/libraries/MyDS1307/MyDS1307.cpp: In member function \'char* DS1307::strDayOfWeek(uint8_t)\':
/home/grzegorz/Arduino/libraries/MyDS1307/MyDS1307.cpp:359:19: warning: ISO C++ forbids converting a string constant to \'char*\' [-Wwrite-strings]
case 1: return "Poniedzialek";break;
^~~~~~~~~~~~~~
"
analogiczne uwagi są dla pozostałych wartości tej funkcji (nazwa dnia tygodnia" oraz dla funkcji nazwa dnia miesiąca.
Czy ktoś może mi pomóc w jaki sposób poprawić kod?
Z góry dziękuję.