Raspberry PiにRTC(DS1307)を接続

はじめに

2016年11月、Raspberry Pi2にRTCモジュールを接続しました。

RaspberryPi2 ボード

RaspberryPi2 ボード

Raspberry Piには、RTC(Real Time Clock)というハードウェア・クロックが搭載されていません。そのため、ブート直後は前回シャットダウン時の日時になります。インターネットに接続状態の場合は、NTPサーバーと同期して日時を補正してくれます。しかし、インターネットに接続できない場合やNTPサーバーにアクセスできない場合は正確な日時が設定されません。

そこで、バッテリーバックアップ付きのRTCモジュールを接続することにより、インターネットに接続していない状態でブートした場合でも日時を保持できるようにしました。

「Raspberry Pi RTC 拡張モジュール DS1307」を購入して接続しました。この拡張モジュールは、MAXIM社の「DS1307」チップを使用しています。サイズは23mm×26mmの小型のボードで、10ピンのコネクタで接続します。時計はCR1220電池でバッテリーバックアップされています。

Raspberry Pi2のRaspbian jessie OSで動作確認しました。

pi@pi2note:~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 8.0 (jessie)
Release:        8.0
Codename:       jessie

 

リアルタイムクロック RTC DS1307 とは

maxim社のホームページに DS1307  の説明がありました。

DS1307は、I2Cインターフェースでマイクロプロセッサと接続するRTCデバイスです。

[説明]
シリアルリアルタイムクロック(RTC)のDS1307は低電力、56バイトNV SRAM内蔵の完全なバイナリコードの10進(BCD)クロック・カレンダです。アドレスおよびデータはI2C、双方向バスによりシリアル転送されます。

クロック・カレンダは、秒、分、時間、曜日、日、月、年の各情報を提供します。月の最後の日付は、うるう年の修正を含めて、31日より少ない月について自動的に調整されます。クロックは、24時間形式もしくはAM/PM表示付き12時間形式のいずれかで動作します。DS1307は、電源障害を検出して自動的にバックアップ電源に切り換える電源検出回路を内蔵しています。デバイスがバックアップ電源によって動作する際にもタイムキーピング動作は維持されます。

[主な特長]

  • 全計時機能を完全に管理
  • リアルタイムクロックは秒、分、時間、日、月、曜日、および年をカウント(2100年までうるう年を補正)
  • 56バイト、バッテリーバックアップ、汎用RAMは書き込み回数が無制限
  • 簡素なシリアルポートによってほとんどのマイクロコントローラと接続可能 (I2Cシリアルインターフェース)

 

データシートにアドレスマップの記述がありました。7バイトの領域に「年/月/日/曜日/時/分/秒」の情報をBCD形式で記録しており、リアルタイムにクロックを刻んでいます。

DS1307アドレスマップ

DS1307アドレスマップ

 

DS1307レジスタ説明

DS1307レジスタ説明

 

I2Cとは

I2C(Inter-Integrated Circuit)とは、周辺デバイスとのシリアル通信の方式です。1台のマスターに複数のスレーブデバイスを接続することが可能で、スレーブデバイスはアドレスで区別します。マスターとスレーブは、シリアルデータ (SDA) とシリアルクロック (SCL) の2本の信号線で接続します。

I2C接続

I2C接続

 

Raspberry Pi2のGPIOポートコネクタ(40ピン)にI2Cの信号線が接続されています。

 

ピン GPIO 用途
1 3.3V
2 5V
3 GPIO 02 I2C SDA
4 5V
5 GPIO 03 I2C SCL
6 GND
7 GPIO 04
8 GPIO 14 UART TXD
9 GND
10 GPIO 15 UART RXD

 

RTCボードはRaspberryPiのGPIOポートの1番~10番ピンの10本のコネクタで接続するようになっています。

 

Raspberry PiとRTC DS1307の間は、SDA(3番ピン)とSCL(5番ピン)の信号線と電源系(Vcc / GND)を接続します。そして、RTCボードの上部から5本の信号線のピンが出ていて、UARTの信号線を接続できるようになっています。

RTC for RPI

RTC for RPI

 

Linuxシステムの時計について

Linuxシステムには主要な時計が2つ存在します。

  •  ハードウェア・クロック :  CPUから独立している時計で、システムが停止している間も動作している時計です
  •  システム・クロック :  Linuxカーネルの内部に存在している時計で、すべての基準となる時計です

ハードウェア・クロックはRTCと呼ばれ、バッテリーバックアップすることでマシンの電源がOFFの場合にも動作しています。

 

Linuxの時計

Linuxの時計

 

インターネット接続している場合は、NTPプロトコルでネットワーク上の時刻サーバーに問い合わせてシステム・クロックを時間同期させることができます。

システム・クロック

dateコマンドでシステム・クロックにアクセスします。

コマンド 説明
date システム・クロックを標準出力に表示します
date -s ‘日時’ システム・クロックに指定した日時を設定します

ハードウェア・クロック

hwclockコマンドでハードウェア・クロックにアクセスします。

コマンド 説明
hwclock -r ハードウェア・クロックを読んで標準出力に表示します
hwclock -w ハードウェア・クロックにシステム・クロックを書き込みます
hwclock -s ハードウェア・クロックをシステム・クロックに設定します

 

RTC DS1307デバイスを接続

I2C有効化とソフトの設定

最初に、Raspberry PiのI2Cを有効化します。

sudo raspi-config

「7 Advanced Options」→「A7 I2C」→「はい」→「了解」で、I2Cを有効化して <Finish>  で終了します。

次に、ユーティリティをインストールします。

sudo apt-get install i2c-tools

 

 

モジュールをロードするために、/etc/modulesに「i2c-dev」と「rtc-ds1307」を追加します。

pi@pi2note:~ $ sudo cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

i2c-dev
rtc-ds1307

RTCデバイスの登録

最初に、「i2cdetect」コマンドでI2Cデバイスのアドレスを調べます。

pi@pi2note:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

DS1307は、アドレス0x68に接続されていました。

RTCデバイスを登録します。「sudo su」で管理者モードで操作します。デバイス名とアドレス「ds1307 0x68」をI2Cデバイスに書き込みます。
もう一度、「i2cdetect」コマンドでI2Cデバイスのアドレスを調べると、68→UUに変化してシステム管理下になったことがわかります。

pi@pi2note:~ $ sudo su
root@pi2note:/home/pi# modprobe rtc-ds1307
root@pi2note:/home/pi# echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
root@pi2note:/home/pi# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

 

  • 「date」コマンドでシステム・クロックを参照します
  • 「hwclock -w」コマンドで、システム・クロックをハードウェア・クロックに書き込みます
  • 「hwclock -r」コマンドで、ハードウェア・クロックを読み込んで正しく設定されたことを確認します
root@pi2note:/home/pi# date
2016年 11月 8日 火曜日 10:58:59 JST
root@pi2note:/home/pi# hwclock -w
root@pi2note:/home/pi# hwclock -r
2016年11月08日 10時59分11秒 -0.518151 seconds
root@pi2note:/home/pi#

RTC DS1307のテスト

シャットダウンして電源OFFにします。しばらく時間を空けて、ネットワーク切断状態で電源を入れます。
「date」コマンドで、日時を確認するとシャットダウンした日時となっています。「i2cdump」コマンドで、DS1307内の日時を確認します。

pi@pi2note:~ $ date
2016年 11月 8日 火曜日 11:07:53 JST

pi@pi2note:~ $ sudo i2cdump -y 1 0x68 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 44 28 02 03 08 11 16 93 f7 9f 9b a5 d3 ff ff 9f

Address 0 : 44 秒
Address 1 : 28 分
Address 2 : 02 時 (02+09=11時)
Address 3 : 03 曜日 (火曜日)
Address 4 : 08 日
Address 5 : 11 月
Address 6 : 16 年 (2016)

Linux内部のシステム・クロックは停止していましたが、RTCのハードウェア・クロックは現在の時刻となっていますので、正常に動作しています。

ブート時にRTC時刻を設定する

ブート時に、RTCのハードウェア・クロックをシステム・クロックに設定すれば、ネットワークに接続していなくてもブート時に正しく時刻が設定されることになります。

/etc/default/hwclock の最後の行 HCTOSYS_DEVICE のコメントアウトを外します。

pi@pi2note:~ $ sudo cat /etc/default/hwclock|grep HCTOSYS_DEVICE
# probably match the CONFIG_RTC_HCTOSYS_DEVICE kernel config option.
HCTOSYS_DEVICE=rtc0

起動スクリプト /etc/rc.local の exitの手前でハードウェア・クロックをシステム・クロックに設定します。/etc/rc.local は、管理者モードで実行しますので、sudoは入れる必要はありません。

echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
sleep 1
hwclock -s

 


さて、テストしてみます。ネットワーク切断状態で電源を入れます。ブート時に正しく時刻が設定されるはずです。

「date」コマンドでシステム・クロックを確認すると、現在の時刻ではありませんでした。
「hwclock -r」コマンドでハードウェア・クロックを参照すると、システム・クロックと同じです。

pi@pi2note:~ $ date
2016年 11月  8日 火曜日 12:33:34 JST
pi@pi2note:~ $ sudo hwclock -r
2016年11月08日 12時34分15秒  -0.276407 seconds

 

ブート時に正しく時刻が設定されていません。何かミスしているようです。

ネットワークに接続して、NTPサービスを再起動します。そして、「date」コマンドでシステム・クロックを確認すると、当然ながら現在の時刻が表示されます。
「hwclock -r」コマンドでハードウェア・クロックを参照すると、システム・クロックと同じになっています。NTPサービスにより、ハードウェア・クロックが再設定されてしまったようです。

pi@pi2note:~ $ sudo /etc/init.d/ntp restart
[ ok ] Restarting ntp (via systemctl): ntp.service.
pi@pi2note:~ $ date
2016年 11月  8日 火曜日 13:28:49 JST
pi@pi2note:~ $ sudo hwclock -r
2016年11月08日 13時28分52秒  -0.252129 seconds

このことから、ネットワーク切断状態でブートした場合は、NTPサーバーからの時刻取得に失敗していますが、ハードウェア・クロックを再設定していると想像できます

これでは、RTCを接続した意味がありません!

 


続きは、「Raspberry PiにRTC(DS1307)を接続 【解決編】」を参照して下さい。無事解決しました。