Jedną z większych wad RPi jest brak wbudowanego układu RTC. Nie jest jednak problemem wyposażenie naszego komputerka w taki układ. Ilość układów RTC przyprawia o zawrót głowy. Ja niestety, w obecnym projekcie nie przemyślałem tego do końca i kupiłem tani i (wtedy) dostępny układ MCP7940M.
Dlaczego niestety? Ponieważ RTC w tej wersji nie posiada wsparcia dla podtrzymania bateryjnego i nie jest oficjalnie wspierany przez kernel linuxa (tak do dzisiaj myślałem).
Całkiem przypadkiem odkryłem, że jednak jest obsługiwany i nie wymaga żadnych przeróbek.

Schemat podłączenia układu jest dość klasyczny. Układ jest podtrzymywany przez baterię. Ważna uwaga, bateria musi mieć wyjściowo niższe napięcie niż szyna zasilania 3.3V. Aby to zapewnić, zastosowałem diodę Schottky’ego (D2), która ma mniejszy spadek napięcia niż zwykła dioda 1N4148 (D1). Tak naprawdę, to ważne jest to tylko jak mamy nową baterię. Stara na pewno będzie miała mniejsze napięcie niż szyna 3.3V i wtedy nie ma problemu.
Jeśli zasilimy układ z szyny 5V też nie będzie z tym problemu. Układ może być zasilany napięciem od 1.8V do 5.5V (Operating voltage range of 1.8V to 5.5V: nota katalogowa).
schemat-mcp9740m
Tak, wiem, na schemacie jest PCF8563P, nie chciało mi sie tworzyć nowego elementu w eagle, więc jest ten 🙂

Ustawienia samego RPi są banalnie proste.
Podłaczamy nasz RTC i sprawdzić czy wszystko z nim ok. Do tego instalujemy narzędzie do obsługi i2c:

 Bash | 
 
 copy code |
?

1
sudo apt-get install i2c-tools

I sprawdzamy czy nasz RTC jest dostępny (dla wersji rev.1 RPi zamieniamy 1 na 0):
 Bash | 
 
 copy code |
?

1
sudo i2cdetect -y 1

Powinniśmy mieć wpis dla adresu 6f:
 Bash | 
 
 copy code |
?

1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
2
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
3
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
5
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
6
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
7
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
8
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 6f
9
70: -- -- -- -- -- -- -- 77

To jest adres układu MCP7940x. Dalej, właczamy moduły dla i2c oraz rtc-ds1307. Edytujemy plik /etc/modules, dodając w nim linie:
 Bash | 
 
 copy code |
?

1
i2c-dev
2
i2c-bcm2708
3
rtc-ds1307

Tak, dobrze napisałem, moduł rtc-ds1307. Potrafi on gadać nie tylko z tytułowym MCP7940, ale też z następującymi układami:

  • ds1307
  • ds1337
  • ds1338
  • ds1339
  • ds1388
  • ds1340
  • ds3231
  • m41t00
  • mcp7940x
  • mcp7941x
  • pt7c4338
  • rx8025

Dodajemy wpis do /etc/rc.local konfigurujący nam nasz układ RTC (dla rev.1 zamieniamy i2c-1 na i2c-0):

 Bash | 
 
 copy code |
?

1
echo mcp7940x 0x6f > /sys/class/i2c-adapter/i2c-1/new_device
2
Pierwszy wyraz po echo definiuje nam typ układu RTC (z powyżesz listy), drugi określa adres wcześniej odczytany.
Teraz wystarczy że zrestartujemy system i nasz RTC powinien być już aktywny:
 Bash | 
 
 copy code |
?

1
ls -l /dev | grep rtc

Powinniśmy dostać coś w stylu:
lrwxrwxrwx 1 root root 4 gru 30 17:09 rtc -> rtc0
crw——- 1 root root 254, 0 gru 30 17:09 rtc0
 Bash | 
 
 copy code |
?

1
lrwxrwxrwx 1 root root           4 gru 30 17:09 rtc -> rtc0
2
crw------- 1 root root    254,   0 gru 30 17:09 rtc0

Jeśli tak nie jest, to coś jest nie tak z naszym układem lub żle skonfigurowaliśmy RPi.

Za operacja na RTC odpowiada komenda hwclock. I tak, oby odczytać czas z RTC:

 Bash | 
 
 copy code |
?

1
sudo hwclock -r

Ustawienie RTC na podstawie aktualnego czasu systemowego:
 Bash | 
 
 copy code |
?

1
sudo hwclock -w

I odwrotnie, systemowy na podstawie RTC:
 Bash | 
 
 copy code |
?

1
sudo hwclock -s

Teraz możemy wyłączyć domyślnie włączony ntp, czyli synchronizacja czasu przez połączenie internetowe:

 Bash | 
 
 copy code |
?

1
2
sudo update-rc.d ntp disable
3
Dzięki temu, nasz system nie będzie się aktualizować za każdym razem przy uruchomieniu tylko korzystać z RTC.
Aby jednak czasem zsynchronizować nasz RTC z resztą świata, warto dopisać do crona wykonywanie polecenia np. raz na tydzień: ntpd -gq ; hwclock -w