Zegar czasu rzeczywistego: podłączenie PCF8563 do Arduino

Jeżeli kiedykolwiek postanowicie zbudować zegarek, prędzej czy później będziecie potrzebowali układ  odniesienia czasu. Każdy procesor zlicza czas od swojego uruchomienia. Ale po resecie, zaniku napięcia zasilającego lub przepełnieniu odpowiedniego rejestru – zaczyna od zera. W zupełności wystarcza to dla funkcji opóźnienia i wielu innych, które korzystają z czasu – jak PWM czy watchdog. Słabo nadaje się jednak na zegarek.

Dlatego stosuje się układy odniesienia czasu. Są to dodatkowe czipy,  najczęściej niezależnie zasilane (przez baterię lub kondensator). Ich rolą jest zapamiętywanie godziny i daty – i odliczanie jej nawet, gdy cały komputer jest wyłączony. Zawartość takich czipów może być ustawiona przez użytkownika – albo np. synchronizowana z usługą czasu sieciowego NTP.

Podobnych układów jest na rynku kilka np. DS1307, MCP79400. Tutaj zajmę się zegarem firmy NXP: PCF8563.

Dlaczego akurat PCF8563? Największą zaletą tego układu jest bardzo szeroki zakres jego zasilania. PCF8563 działa od 1v do 5.5v. Dzięki temu bez żadnych dodatkowych sprzęgów można go stosować tak z Arduino, jak i Raspberry. Tego samego nie można powiedzieć np. o DS1307 – który działa jedynie z napięciami 4.5 do 5.5v (np. Raspberry lub micro:bit będą miały z nim kłopoty).

Podłączenie

Piny PCF8563:

Do podłączenia PCF8563 będziecie potrzebowali:

  • kwarc 32kHz,
  • 2x rezystory 10kΩ,
  • kondensator 10..22pF

Schemat podłączenia z dokumentacji producenta:

Vdd to napięcie zasilania a Vss to masa. Napięcie zasilania może zawierać się w granicach 1v (lub 1.8v, jeżeli chcecie czytać z niego dane) do 5.5v. Jako kondensator od kwarcu możecie użyć ceramika o wielkości 10..22pF

Rezystory na SDA i SCL nie są konieczne – większość kontrolerów (w tym Arduino) wyposażono na tych liniach w wewnętrzne rezystory podciągające. Z drugiej strony – nie zaszkodzą, a wewnętrzne pull-up mogą się czasem okazać za słabe.

Używałem rezystorów R = 10kΩ.

I2C

Układ PCF8563 komunikuje się za pomocą szyny i2c. Szyna ta jest stosunkowo prosta w podłączeniu. Wystarczy połączyć ze sobą piny SDA i SCL współpracujących układów. Dodatkowo należy je podciągnąć (poprzez rezystory) do napięcia zasilania.

Może się jednak zdarzyć, że będziecie podłączali układy o różnych poziomach logiki – np. 3v micro:bit i 5v DS1307. Pomimo, że obydwa układy używają szyny i2c – linie danych i zegara będziecie musieli podłączyć przez konwerter poziomów.

Pin SDA to dane – a SCL to zegar.

Dla PCF piny SDA i SCL to odpowiednio 5 i 6.

Dla Arduino UNO, szyna i2c podłączona jest pod piny A4 (SDA) oraz A5 (SCL). Na niektórych klonach wyprowadzono je na szczyt kolumny z pinami cyfrowymi Dx, w kierunku portu USB:

Szynie i2c warto przyjrzeć się dokładniej. Do niej podłącza się czujniki, pamięci i inne.

Oprogramowanie

Każde urządzenie na szynie i2c ma swój adres. Możecie go sprawdzić za pomocą prostej aplikacji. Otwórzcie Arduino IDE. Zacznijcie od dodania biblioteki „Wire” (Szkic->Dodaj bibliotekę). Na blogu Nick Gammond znajdziecie kod ‚scanner’. Wyświetli on  wszystkie urządzenia podłączone do szyny i2c i wypisze ich adresy:

W powyższym kodzie port szeregowy ustawiony jest na szybkość 115200. Domyślnie monitor portu (Ctrl-Shift-M) startuje z szybkością 9600. Musicie to zmienić – inaczej w oknie nic się nie pojawi, albo same „krzaczki”. Do zmiany szybkości transmisji portu szeregowego służy kontrolka w prawym dolnym rogu okna monitora portu:

Dla PCF8563 powinniście otrzymać:

Ustawianie i odczyt czasu

Do obsługi PCF8563 będziecie potrzebowali dodatkowej biblioteki. Możecie ją pobrać z: https://bitbucket.org/orbitalair/arduino_rtc_pcf8563/downloads/. Teraz wystarczy skorzystać z przykładu ‚Plik->Przykłady->orbitalair/arduino_rtc_pcf8563->function_test’. Zawiera on praktycznie wszystko, czego potrzebujecie. Przykład wygląda tak:


Wywołanie metody initClock() zresetuje zegarek. Metoda wysyła „0” do układu zegara. Jeżeli ją wywołacie – stracicie jego zawartość i zaczniecie odliczanie czasu od nowa.

Najważniejsze kroki:

  • Dodajcie bibliotekę ‚Wire’ i ‚orbitalair-arduino-pcf8563’,
  • Stwórzcie obiekt Rtc_Pcf8563:
  • Metoda initClock() słuzy do wyzerowania zegara:
  • rtc.setDate() i rtc.setTime() ustawiają czas. Jeżeli wstawicie je np. w setup() – do pamięci PCF zapiszą nowy czas – nadpisując cokolwiek co było tam wcześniej,
  • Funkcja ‚get*()’ służy do  pobierania daty i czasu,
  • Przydatne:

    i:

Odczyty w stylu „45” czy „85” oznaczają problem z komunikacją. Sprawdźcie połączenia.

Zasilanie awaryjne

Wracając jeszcze raz do schematu z instrukcji do PCF: zwróćcie uwagę na sekcję zasilania:

Zaznaczona część schematu to zasilanie awaryjne układu. W wypadku zaniku Vdd, prąd popłynie z dużego superkondensatora (to ten oznaczony 1F).

Mi bardziej spodobał się projekt z blogu tronixstuff.com, trochę go tylko zmodyfikowałem:

Zauważcie:

  • Napięcie zasilania przechodzi przez diodę zabezpieczającą przed cofaniem się ładunku z kondensatora; UWAGA: jeżeli użyjecie zwykłej diody (na przykład 1n4148), napięcie Vdd zasilające PCF spadnie o ok. 0.6 – 0.7v („zużyje” je dioda); dla mniejszego spadku możecie użyć np. diodę Shottky’ego,
  • Rezystor R1 ogranicza prąd ładujący kondensator. Zgodnie z prawem Ohma:
    I={{(V_{dd}-0.6)}\over {(R_1)}}
    Przykładowo, dla R1=100Ω, zasilania Vdd=5v i diody 1n4148, prąd płynący do/z kondensatora będzie wynosił:
    I={{(5-0.6)}\over {(100)}}=44mA
    To raczej niewiele, ale pamiętajcie, że stabilizator Arduino (czyli Vdd) ma również ograniczoną wydajność.
  • Kondensator musi mieć dopuszczalne maksymalne napięcie o wartości (Vdd-0.6v) – zakładając, że spadek na diodzie to 0.6v; UWAGA: dla Arduino i Vdd = 5v musi to być podwójny superkondensator, np:

    ALE NIE TAKI:

    100F/2.7V supercaps

    …ponieważ podobny „wytrzyma” ładowanie jedynie do 2.7v (no chyba,  że takie właśnie jest Wasze napięcie zasilania Vdd),

  • Im mniejszy R1, tym większy prąd ładowania a kondensator się szybciej naładuje. Ale: większy prąd zostanie pobrany ze źródła Vdd.
  • Dla wspomnianego R1=100Ω i kondensatora 1F, stała czasowa wyniesie:
    \tau = R \cdot C = 100 \cdot 1 = 100s
    Po 100 sekundach kondensator naładuje się do 2/3, w pełni dopiero po ponad 8 minutach. Myślę, że w przypadku zegarka to wartość rozsądna,
  • Kondensator jest bezpośrednio podłączony do chipu. Nie jest to problem, biorąc pod uwagę, że PCF pobiera mikro-ampery (np. 800uA przy włączonym interfejsie) lub jedynie nano-ampery (np. 550nA przy wyłączonym interfejsie) – jest to wartość wystarczająca.

Kondensator zbudowałem na niewielkiej płytce: Teraz mogłem łatwo umieścić całość układu na płytce stykowej:

Test układu podtrzymywania

Układ podtrzymywany przez kondensator pozostawiłem na tydzień co pewien czas notując napięcie kondensatora. Otrzymałem taki wykres:

Zgodnie z charakterystyką rozładowania kondensatora, na początku pracy jego napięcie spadało dość szybko. W miarę czasu napięcie spadało mniej więcej o 90mV/dzień. Oznacza to, że w pełni naładowany kondensator (czyli po kilku minutach) powinien podtrzymać zegar nawet przez miesiąc:)

Podsumowanie

Teraz już wiecie, jak samemu zbudować i podłączyć do Arduino zegar czasu rzeczywistego oparty na PCF. W sprzedaży znajdziecie też gotowe płytki – w komplecie z PCF8563, rezystorami podciągającymi i baterią zasilającą – np. w wersji dla Raspberry Pi:

Źródła

2 komentarze do “Zegar czasu rzeczywistego: podłączenie PCF8563 do Arduino”

  1. Czy możemy coś takiego używać jako zasilanie awaryjne dla Arduino? W sensie Arduino wykrywa brak zasilania głównego, podtrzymanie pracy przez kilka sekund odbywa się przez kondensator a w tym czasie Arduino wykonuje jakieś zadanie, np. zapisanie i zamknięcie pliku

    1. Witam,
      napięcie kondensatora znacznie spada w pierwszym etapie rozładowania. Jeżeli podłączysz kondensator bezpośrednio do pinu 5v, wtedy Arduino szybko się wyłączy. Rozwiązaniem wydaje się zasilanie Arduino przez przetwornicę step-up podłączoną do kondensatora. Ja testuje to z 8F i blink działał przez… 🙂
      Pozdrawiam,
      Arek

Dodaj komentarz

Proszę dodaj swój komentarz. Pamiętaj, żeby nie podawać żadnych danych osobowych.