Raspberry Pi 2 で RTC を使いスタンドアロンで時刻を保持

[投稿日] 2015年9月3日
[最終更新] 2016年11月16日

Raspberry Pi(以下RPi)はバッテリーがない為、起動時は前回シャットダウン時の時刻になります。インターネットに繋がっていれば、ネット上のNTPサーバーと同期して時刻を補正してくれますが、スタンドアロンの場合そうもいきません。RPiは名刺サイズというその大きさと電子工作との相性の良さから、PCを置けないような場所に置いてスタンドアロンで使用したいケースも多いと思いますので、これは困ったことです。

スポンサーリンク

2015/09/10: エラーに関する追記
2015/11/27: I2Cについて追記

RTCモジュールの導入

スタンドアロンで電源を落としても時刻を更新するには、RTCモジュールを導入します。今回使用したのはDS1307を搭載した「リアルタイムクロック・モジュール – スイッチサイエンス」です。Amazonからも購入できます。2,000円ほどしますが、DS1307搭載のものなら同じようにできるかと。

実際の導入については、Adafruitの「Set RTC Time | Adding a Real Time Clock to Raspberry Pi | Adafruit Learning System」が非常に参考になります。この通りになぞればOKです。他に「Using an I2C Real Time Clock (RTC) with a Raspberry Pi – nicegear blog」も、同じことをしていますが完全にコピペでいけるのでこちらのほうが楽かもしれません。これらのページを参考に、まとめたものを以下にメモします。

I2Cの有効化

2015/11/27追記:I2Cの準備手順についてまとめました→「Raspberry Pi で I2C を使用する準備 : 或る阿呆の記

まずI2Cを有効化します。I2Cの有効化については、カーネル3.18以降ならば raspi-config のAdvanced Option から有効化するのが簡単です。それより前のカーネルでやる必要がある場合や、設定ファイルの編集で行いたい場合は「Raspberry Pi の I2C を有効化する方法 (旧版) – 意識低い開発者のBlog」が参考になります。なお、カーネルのバージョンは uname -r コマンドで調べられます。たまには rpi-update しましょう。

接続と確認

RPiのピン配置を「RPi Low-level peripherals – eLinux.org」で確認し、SDA、SCL、5V、GNDを繋ぎます。繋いだら、i2cdetect コマンドで、0x68 が表示されることを確認します。

$ i2cdetect -y 1

なお、-y 1は1chの意で、昔の基板…具体的にはRevision 1の頃のRPiだとここが0になります。

RTCモジュールの取り込み

以下のコマンドを実行します。

$ sudo modprobe rtc-ds1307
$ echo ds1307 0x68 | sudo tee /sys/class/i2c-adapter/i2c-1/new_device
$ sudo hwclock

これで時刻が表示されればOKです。echoのところでひょっとするとエラーが出るかもしれませんが、繰り返せば成功するはずです。その場合は、後述する「エラーが発生する場合」を参照してください。なお、古い基板ではi2c-1のところがi2c-0になります。

初期状態では2000年になってしまっているので、ハードウェアクロックをシステムクロックに合わせます。システムクロックは、NTPサーバーで正確な時刻にしておきます。

$ sudo hwclock -w
$ sudo hwclock

現在の時刻が表示されればOKです。

起動スクリプトの修正

次に、/etc/rc.localに以下を追記して、起動時に自動的にシステムクロックをハードウェアクロックに同期するようにします。なお、/etc/rc.localは、起動時に実行するシェルスクリプトです。

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

古い基板ではi2c-1がi2c-0に(略)。コマンドラインで追記したい場合は以下のようにすると、コピペで完了できます。

$ sudo sed -i 's#^exit 0$#echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device#' /etc/rc.local
$ echo 'sudo hwclock -s' | sudo tee -a /etc/rc.local
$ echo exit 0 | sudo tee -a /etc/rc.local

以上でOK。

hwclockでエラーが発生する場合

ひょっとすると、hwclockを実行したとき、以下の様なエラーが出るかもしれません。

  • hwclock: ioctl(RTC_RD_TIME) to /dev/rtc0 to read the time failed: Invalid argument
  • hwclock: ioctl(RTC_RD_TIME) to /dev/rtc0 to read the time failed: Input/output error

必ず出るわけではなく、hwclockを繰り返せばいつかは必ず成功するのですが、頻繁に上記のエラーが起きる、という症状が私の場合ありました。RPiの起動時に失敗されては嫌ですね。割と有名な問題らしく、調べてみるとどうもntpの問題のようで、ntpとfake-hwclockなるものをアンインストールすれば正常に動くようになる、という報告もみました(「ODROID Forum • View topic – RTC does not keep time over ON/OFF cycles」)。実際、ntpを切ってみると成功率100%で動いたりしたのですが、ntpがなくなっては困ります。…なのですが、chkconfigでntpをoffにしたりなんだりと色々いじっていると、症状がでなくなってしまいました。再現性がなくなってしまい謎なのですが、こういうこともあったということのみメモします。

2015/09/10、追記。下記のようにしてfake-hwclockパッケージの削除することで、本エラーは回避できるかもしれません。まだ未検証ですので、時間を見つけて試してみたいところです…まずはエラーの再現からなのですが。参考…「h’s IT Notes: Raspberry Piにリアルタイムクロックをインストールする

$ sudo apt-get remove fake-hwclock
$ sudo dpkg --purge fake-hwclock

Interface 2015年10月号の付録、ラズベリー・パイ便利帳2015に載っていました。apt-getで関連するパッケージを削除して、dpkg –purgeで設定ファイルを消去していますね。

スポンサーリンク

“Raspberry Pi 2 で RTC を使いスタンドアロンで時刻を保持” への 2 件のフィードバック

  1. はじめまして,私も同様のhwclockのエラーに悩まされています.
    私の場合は,さらに具合が悪いようで,rc.localを読み込んだ際に,一度エラーとなると,次回起動時に狂ったRPiの時計をRTCに合わせてしまうという,なんとも不思議な挙動を示すことがあります.
    しかし,あなたと同様にこの挙動も再現性がありません.
    このような挙動はあなたもございましたか?
    もし,なにか原因に心当たりがあればご教授いただけると助かります.
    追伸
    当方は,ntpを停止することで,確かに,エラーが出てこなくなったようにも見えました.

  2. >yさん
    はじめまして。私が出会ったエラーは、記事のとおりで、あくまで同期に失敗するだけでした。yさんの症状は、勝手にハードウェアクロックが上書きされてしまっている感じでしょうか?それはかなり不思議ですね。
    私は、再現性がないままに調子がよくなってしまい、またその後検証する機会もないままですので、結局本当のところはわからずじまいです。お役に立てず残念ですが…。

コメントを残す

メールアドレスが公開されることはありません。