Raspberry Piとは、シングルボードコンピューターです。キーボード、マウス、ディスプレイを繋げば超小型のPCとして使用できます。
何を今更、という話ですが、上記のような認識だと罠にハマってしまう可能性があります。普通のPCにあって、Raspberry Piには無いものがあるのです。
それが何かというと、RTC(Real Time Clock)です。ハードウェアクロックとも呼ばれます。いわゆる時計のことです。
普通のPCはいちど時計を設定すれば、電源をOFFにしている間も時を刻み続け、次にONにした時も何事もなく正しい日時が設定されます。しかし、時計の回路がないRaspberry Piは違います。電源をOFFにすると時計が止まり、次にONにしたときには前回OFFにした時刻から時計が再開します。
Raspberry Piは標準でインターネットに接続されていると自動で時刻合わせが行われるため、RTCが無いことを把握していない方も案外多いような気がします。今回、インターネット接続がないオフラインで使用しても時計が狂わないようにしなければいけなくなったので、いろいろ試してみました。ググってみると色々な情報が見つかりますが、古いRaspberry Pi向けの情報だったり設定が複雑だったりしました。
この記事は、2019年8月時点での最もシンプルな設定で実現する方法ということで、記録として残します。
実現方法
普通のPCには時計の回路がマザーボードに実装されています。ようは、それと同じものをRaspberry Piに外付けすれば良いわけです。私達はモジュール自作する予定ですが、まずは実現可能性を探るために既製品を使用します。
次の2つの製品を試しに購入しました。
1.HiLetgo 3個セット DS3231 AT24C32 時計モジュール リアル時間時計モジュール IICモジュール RTCモジュール Arduinoに対応 [並行輸入品]
2.高精度ラズベリーパイRTC時計モジュール リアル時間時計モジュール DS3231 Pi 2/ 3 B/B+ Zero適用 (DS3231)
まずは1の方を試します。
何も接続せずに・・・
ターミナルで”timedatectl status”を実行すると、次のように表示されます。
pi@raspberrypi:~ $ timedatectl status Local time: 日 2019-08-11 21:07:45 JST Universal time: 日 2019-08-11 12:07:45 UTC RTC time: n/a Time zone: Asia/Tokyo (JST, +0900) Network time on: yes NTP synchronized: yes RTC in local TZ: no
RTC timeのところがn/aと表示されています。時計の機能がないことを示しています。
今回、I2Cのインターフェースを使って時計を外付けするので、I2Cを有効にする必要があります。方法はRaspberry PiのI2Cを使って電圧を測定する(2019年3月版)の記事をご参照ください。
ターミナルで”i2cdetect -y 1″と入力し、接続前の状態を見ておきます。
pi@raspberrypi:~ $ 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
なにも検出されません。
RTCモジュールを接続
これを接続します。
このモジュールの良いところは、充電回路があるためバッテリーに二次電池が使えます。Raspberry Piの電源を入れれば充電されるので、電池の交換が困難な場所に設置する場合に最適です。
このモジュールの悪いところは、充電できる電池ではなく普通のボタン電池を使いたい場合は改造が必要なところです。あと、モジュールのI2Cにプルアップ抵抗が実装されており、Arduino等で使用する場合は都合が良いようですが、本体側にプルアップ抵抗が実装されているRaspberry Piで使用するには、モジュールのプルアップ抵抗を外す必要があります。
このモジュールの何とも言えないところは、EEPROM(24C32)が乗っているところです。データを保存できるようですが、今回はRTCがあれば良かったので私としては不要でしたし、RTCとEEPROMを同居させるメリットも良く分かりません(Arduinoでの使用を想定していそうなので、Arduino的にはEEPROMがあった方が都合が良いということかも知れません)。
外す対象は次の写真で白い丸で示した抵抗です。
二次電池じゃない普通のボタン電池を使用する場合は、赤い丸の抵抗かダイオードを外すそうです(未検証)。
接続して認識されたか確認します。
pi@raspberrypi:~ $ 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- 5f 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
大丈夫そうです。68がRTCです。57はEEPROMで、5fは不明です。
OSの設定
設定方法は、ネットで探すと色々な方法が見つかるのですが、あまり複雑なものを参考にすると、後で色々と苦労しそうです。あと、OSの標準のふるまいから外れてしまうと、時刻合わせや時刻の問い合わせで辻褄が合わないことになりそうな予感もします。よって、出来るだけシンプルな設定を目指します。
主に↓を参考にしました。
RTC DS3231 setup on stretch – Raspberry Pi Forums
“fake-hwclock”を削除
pi@raspberrypi:~ $ sudo apt-get purge fake-hwclock
“/boot/config.txt”を編集
pi@raspberrypi:~ $ sudo vi /boot/config.txt # 最後に次を追加 dtoverlay=i2c-rtc,ds3231
“/etc/udev/rules.d/85-hwclock.rules”を新規作成
pi@raspberrypi:~ $ sudo vi /etc/udev/rules.d/85-hwclock.rules KERNEL=="rtc0", RUN+="/sbin/hwclock --rtc=$root/$name --hctosys"
これで準備は整いました。
動作確認
動作確認のために、現在の時刻設定を確認します。
pi@raspberrypi:~ $ sudo hwclock -r 2000-01-01 10:00:04.049898+0900 pi@raspberrypi:~ $ date 2019年 8月 11日 日曜日 22:50:22 JST
ズレています。
自動で時刻合わせしてもらうためにWi-FiをONにして、Raspberry Piを再起動します。
時刻の確認の前にi2cdetectを確認します。
pi@raspberrypi:~ $ 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- 5f 60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
68の位置がUUに変わっています。UUの意味は “Probing was skipped, because this address is currently in use by a driver. This strongly suggests that there is a chip at this address.” だそうです。
次に時刻を確認。
pi@raspberrypi:~ $ date 2019年 8月 11日 日曜日 23:41:47 JST pi@raspberrypi:~ $ sudo hwclock -r 2019-08-11 23:42:10.145266+0900
大丈夫そうです(30秒ほどズレているのは私がもたついたためです)。
自動の時刻合わせがなくても大丈夫か確認するため、Wi-FiをOFFにして電源をOFFし、しばらく放置して起動してみます。
pi@raspberrypi:~ $ date 2019年 8月 12日 月曜日 00:27:35 JST pi@raspberrypi:~ $ sudo hwclock -r 2019-08-12 00:27:42.678945+0900
おっけー!
もう一つのRTCモジュールも確認
次に、こちらのモジュールも試してみます。
こちらのモジュールは充電できない普通のボタン電池を使用します。
このモジュールの良い点は、写真のようにRaspberry Piに直接挿せるので利用が簡単でコンパクトなところです。Raspberry Piにとって余計なプルアップ抵抗もありません。
悪い点は、(良い点の裏返しですが)貴重なGPIOの端子がこのモジュールに専有されてしまうことです。直接挿さなければ良いだけですが、そうするとコネクタが余計です。あと、充電電池が使用できないことです。
当たり前ですがいちおう書くと、EEPROMのような余計なチップはありません。
設定は先程のモジュールで行った内容と同じでいい(使っているチップが同じなため)ので終わっています。なので差し替えればいいだけです。
差し替えて再起動します。
まずはi2cdetectを確認。
pi@raspberrypi:~ $ 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: -- -- -- -- -- -- -- --
こっちのモジュールは68のアドレスだけです。
正しく動作しているか確認します。今回はtimedatectlで確認します。
pi@raspberrypi:~ $ timedatectl status Local time: 月 2019-08-12 02:05:05 JST Universal time: 日 2019-08-11 17:05:05 UTC RTC time: 日 2019-08-11 17:05:05 Time zone: Asia/Tokyo (JST, +0900) Network time on: yes NTP synchronized: yes RTC in local TZ: no
RTC timeが表示されているので大丈夫でしょう。
おまけ
ラズパイを使用する際、すでに持っているUSB電源を使う場合は次のケーブルを使うと手元で電源をON/OFF出来て便利です。