リアルタイムクロックに関するまとめ 【Raspberry Pi】

Raspberry Pi

Raspberry Pi のリアルタイムクロック (RTC) に関する設定手順やコマンド等についてまとめておきます。

今回、以下の環境で確認をしています。
環境の一例: Raspberry Pi 3、Raspbian GNU/Linux 10 (bullseye、または、buster)、Grove リアルタイムクロックモジュール

背景

日ごろ、作業の自動化や、Linux の技術検討用に Raspberry Pi を活用しています。

Raspberry Pi は基板に時刻用のクロック(および時刻用電池)がなく、電源の ON/OFF などの通常使用を行うと、単体では正確な時刻を維持できません。
写真で示したように、リアルタイムクロック(Real Time Clock, RTC)を使うと、設定した時刻を維持できるようになります。

設定手順についてネットで探すと、情報が古いものが多く、今では動かないものもかなり多いようです。
そこで、最近の Raspberry Pi OS (bullseye、buster)をベースに、リアルタイムクロックの設定手順と情報を集約し、まとめておくことにします。

使用している RTC デバイスの事例

[A] DS1307 を使ったデバイス
例: Grove リアルタイムクロック (Grove-RTC)
101020013(SEN12671P) 通販コード M-09276  (購入時価格で \730)
★ 上記の写真の製品です。時刻を記憶しているチップとして DS1307 を使ったタイプです。
[B] DS3231 を使ったデバイス

※ Raspberry Pi で使えるリアルタイムクロックとして、普及している製品としては、DS1307 を用いたタイプと、DS3231 を用いたタイプの2種類があります。
私は、上記のリアルタイムクロック [A] を秋葉原で購入しました。また、DS3231 を使ったデバイス [B] も、Amazon で購入しています。
DS1307、DS3231 の両方のタイプを持っていますが、いずれであっても、チップに対応した文字列を設定ファイルに書き込む程度で、特に問題なく動いています。
販売されているデバイスを Amazon などで確認したい場合は、上記のリンクを確認してみてください。
外形が違っていても、DS1307、DS3231 と明示があれば動くと思います。(ご自分の判断でお願いします。)

電池(CR1225)について
上記の製品の場合、電池は、CR1225 となっています。リアルタイムクロックの電池としては、CR1225 を用いたものが大半だと思います。
ところが、CR1225 はややレアな電池のようであり、秋葉原や家電量販店で探したところ、販売している店舗が見つかりませんでした(扱っている店舗でも品切れとなっており、十分な在庫を仕入れていないようです)。そこで、私の場合、百円均一で購入した CR1220 を入れてみたところ動いています(公称電圧 3V は同じで、厚みが 0.5mm 薄いです。自己判断でお願いします)。
念のため、パナソニックのサイトを確認すると、CR1225 と互換の製品としては、BR1225 (高温環境対応)があるようです。私が探すかぎり、CR1225 は実店舗では見つからない可能性があるため、やや高価となる BR1225 を購入するか、Amazon で CR1225 を購入する、のが確実なようです。

ジャンパーワイヤについて
また、私が購入した上記のデバイスにはコネクタがついていましたが、ラズパイ専用ではありませんでした。そこで、別途、秋葉原で購入したジャンパーワイヤ(ブレッドボード・ジャンパーワイヤ オス-メス 15cm 赤、黒)×計4本をつかって、Raspberry Pi と RTC を接続しています(上記の写真)。
Raspberry Pi を使うにあたり、ジャンパーワイヤのオス-メス、オス-オス、ブレッドボードあたりがあると、便利です。Raspberry Pi の GPIO については、過去いくつか検討をしています。関心があるようでしたら、末尾の関連リンク等を参照してください。

設定手順

ハードウェアの設定

① Raspberry Pi にリアルタイムクロック RTC の基板を接続します。
※ I2C 通信のため、4本(電源用の VCC、グランド GND、通信用の SDA、SCL)の結線が必要です。
RTC には、ラズパイ専用のコネクタがついている製品もあります。この場合はソケットを Raspberry Pi に刺すだけですので簡単です。
※ Raspberry Pi のピン配列は、ターミナルで pinout + [enter] と入力すると確認できます。
以下に記載した手順で I2C 通信を「有効」にすると、Raspberry Pi の 3番ピンが SDA5番ピンが SCL として機能するようになります。Raspberry Pi 側のピン番号(ピン名称)と RTC の仕様(ピン名称)を確認し、4本が対応するように接続します。
Raspberry Pi の VCC としては 2番ピン、GND としては 9番ピン(または、6番ピン)を接続すれば、動くと思います。
※ なお、私が購入したデバイスに添付されていた仕様書では、電源は 3.3V ~ 5.5V と記載されていました。
そこで当初、Raspberry Pi の 3.3V ピンに RTC の VCC をつないだところ、うまく動きませんでした(下記の手順で “UU” が表示されない)。そこで、5V のピンに接続しなおしたところ、正常に動作しました。最初、原因がわからず、仕様書の記載と実機動作に矛盾があることに気づくのに数日程度かかりました。そこで、明文化して公開しておきます。

② リアルタイムクロックに電池(上記の製品の場合、CR1225)を入れます。
③ Raspberry Pi に、キーボード、モニター、必要があれば LAN ケーブル等を接続し、電源を投入します。

ソフトウェアの設定

④ 上記の RTC は I2C 通信(I squared C、Inter-Integrated Circuit 通信)を使用します。
以下の手順で、I2C 通信が有効となるよう設定します。

I2C 通信を有効にする手順
Raspberry Pi の画面で左上の「ラズベリーパイのマーク」をクリック → 「設定」→「Raspberry Pi の設定」をクリック → 「インターフェイス」をクリック → I2C の欄で「有効」を選択する → 「OK」ボタンをクリックする。
(→ この設定で I2C通信が有効となります。)
⑤ 必要により、i2c-tools をインストールします。Raspberry Pi OS として bullseye 以降を使っていれば、すでにインストールされていると思います。もし、古い Raspberry Pi OS を使っている場合は以下を実行し、i2c-tools をインストールします。

sudo apt-get install i2c-tools

⑥ 以下の手順を例に、起動時のデバイス構成の設定 config.txt を修正します。

sudo vi /boot/config.txt

ファイルの末尾に、以下を追記します。

dtoverlay=i2c-rtc,ds1307

★ もし、DS3231 を使っている場合は、ds1307 の部分を ds3231 としてください。
追記を終えたら、上書き保存します。

⑦ 以下を例に、モジュールの設定ファイルに RTC のモジュールを追加します。

sudo vi /etc/modules

ファイルの末尾で、以下となるように追記します。
修正前

i2c-dev

修正後

i2c-dev
rtc-ds1307

★ もし、DS3231 を使っている場合は、rtc-ds1307 の部分を rtc-ds3231 としてください。

記載を終えたら、上書き保存します。

⑧ コンソールで以下を入力し、[enter] キーを押します。

i2cdetect -y 1

→ ”68″ と表示されていれば、Raspberry Pi 側で、RTC の認識はできています。
I2C 通信の 0x68 が RTC デバイスに対応しています。

★ I2C 通信は、Raspberry Pi の上記の4本のピンに、複数の異なるデバイスをつないでいくことで、それぞれのデバイスを同時に動かすことができる仕様になっています。デバイスをつないでいくと、ここで表示される数字が追加されていくようになっています。0x68 といった数値は、通信時に個々のデバイスを識別するために使われると考えると、なぜこのような設定をしているのかがわかると思います。

⑨ Raspberry Pi を再起動します。再起動後、上記の i2cdetect -y 1 を再度、実行します。
“68” と表示されていた部分が “UU” になっていれば、システムが RTC を正常に認識できています。
→ RTC の接続まで完了です。

うまく動かないとき
もし、”68″ は表示されるけれども、”UU” に切り替わらないなどの場合は、以下を確認してみてください。
経験的には、接続がうまくできていないか、単純な間違いが大半だと思います。
・ 5V の電源はつながっているか/正しいピンに接続してあるか
・ GND はつながっているか/正しいピンに接続してあるか
・ 2本の信号線はつながっているか/正しいピンに接続してあるか
・ 電池は正しく接触しているか/斜めになっていないか
・ 設定ファイルにミスタイプはないか
・ 設定後の Raspberry Pi の再起動を忘れていないか

RTC に時刻を書き込む

⑩ つぎに、Raspberry Pi の GUI 画面右上の時刻が表示されている場所にマウスを重ねて、正しい日付と時刻が設定されていることを確認します。ネットに接続できているのであれば、自動で正しい時刻が設定されると思います。
続いて、システムの日付、時刻が正しい状態で、以下のコマンドを実行し、システムの時刻を RTC に書き込みます。

sudo hwclock -w

※ システムの日時が正しい状態で RTC への書き込みを行うようにします。
※ もし、画面で表示されている時刻(システムの時刻)が正しくないときは、ネットワークに接続した状態にして数分待つと、自動で時刻が設定されると思います。あるいは、Raspberry Pi のブラウザなどでネットにアクセスしてみるなど、ネットワークの接続を確認してください。
※ 上記の書き込み(sudo hwclock -w)を実行すると、以下の読み出しや自動設定が正しく機能するようになります。(書き込みを実行しないと、正しく機能しません。)
⑪ 以下のコマンドで、RTC からシステムに時刻を読み出します。

sudo hwclock -r

→ 日付と時刻が正常に表示されたら、RTC の設定と動作確認まで完了です。

参考: リアルタイムクロックの日時を Raspberry Pi/Linux OS に設定する場合 
なお、書き込みとは逆に、リアルタイムクロックが維持している日付と時刻を Raspberry Pi OS に設定する場合は、以下を実行します。つぎの項目で、起動時に、このコマンドを自動で実行するようにします。

sudo hwclock -s

起動時にシステムの時刻合わせを実行するよう設定する

⑫ コンソールで以下を入力し、[enter] キーを押します。このコマンドで起動する編集画面で、自動実行するコマンドを記載しておくと、指定したタイミングで自動で実行するようになります。

crontab -e

⑬ 以下を参考に、Raspberr Pi の起動時に RTC の時刻をシステムに設定するよう追記します。

# 2022/XX/XX
@reboot sudo hwclock -s

→ [ctrl] + x などで上書き保存し、crontab を終了します。
※ ”# 2022/ … ” としている行は、コメント行です。備忘のための記載例です。記載しなくてもよいです。

⑭ Raspberry Pi をスタンドアロンで再起動して、時刻設定が正しくできていることを確認します。
具体的には、LAN ケーブルを外して(または、Wi-Fi などの機器の電源を OFF にして/インターネットに接続できない状態として)、Raspberry Pi の再起動を行います。
→ LAN に接続していない状態で、しばらく経って再起動したとき/何度か起動したとき、RTC の設定が読み込まれて、Raspberry Pi の画面右上の日付・時刻が正しく表示、設定されることを確認します。

→ これで、動作確認まで完了です!

その他

関連するコマンドや、よくあるエラーなどについても、まとめておくことにします。
余裕があるようでしたら、実行して動作確認をしてみてください。

関連コマンド

・ RTC の詳細情報を出力するとき

hwclock --verbose

・ Raspberry Pi が起動時に読み込んでいる時刻データを確認するとき

cat /etc/face-hwclock.data

→ 2021-09-07 09:47:35 などの表示がされると思います。

よくあるエラー表示と対応例

・ hwclock コマンド実行時に、”hwclock: Cannot access the Hardware Clock via any known method.” と表示されたとき
→ ”sudo hwclock -r” などのコマンドで “sudo” を忘れていないか確認します。
また、”sudo hwclock –debug” を実行して、表示を確認します。

・ ”sudo hwclock -r” を実行すると、”The Hardware Clock registers contain values that are eighter invalid (e.g. 50th day of month) or beyond the range we can handle (e.g. Year 2095).” の表示が出るとき
→ リアルタイムクロックに書き込まれている年月日、時刻が合っていないと、この表示となります。
Raspberry Pi のメイン画面の時刻表示の部分をクリックし、設定されている年月日が正しくなっていることを確認し、一度、書き込み “sudo hwclock -w” を実行します。この後、再度、読み出し “sudo hwclock -r” を実行すると、正しい時刻が表示されると思います。
上記の⑨を実行してみて、”UU” が表示されているのであれば、リアルタイムクロックの設定と、Raspberry Pi との通信までは正常に設定できていると考えられます。”UU” が表示されていない場合は、上記の⑨までの設定を再度、行います。

考察:リアルタイムクロックの時刻設定の期間はどの程度にすべきか

・ ネット検索をすると、検索結果の上位に、crontab -e で、指定時刻に毎日リアルタイムクロックに日時を書き込むサンプルが出てきます。
当初、この記載に従って、毎日自動起動させて使っていました(3~4年?ほど放置していました)。
そうしたところ、いつの間にか、リアルタイムクロックの時刻が初期化されてしまっていました。
具体的には、Raspberry Pi をネットワークに接続せずにスダンドアロンで起動してみると、画面の時刻表示が 1970年?などになっています。また、リアルタイムクロックは電池切れにはなっていないにもかかわらず、日時を読み出そうとするとエラーとなります。

日頃、Raspberry Pi を自動起動させており、必要時はリモートデスクトップからアクセスして使っていました。
この使い方では、リアルタイムクロックの設定がずれていたとしても、Raspberry Pi がネットワークに接続できた時点で、システム側でネットを参照し、正確な時刻に自動更新してしまいます(以後、起動時や計測時のログの記録も正常になる)。このため、しばらくの間、RTC の設定がずれていることに気づきませんでした。
リアルタイムクロックへの書き込みは、毎日のように実行するのではなく、手動で行うか、数か月に1度程度とするほうがよさそうです。RTC への書き込みが頻繁すぎると、逆にエラーの元になると思われます。
本来は、許容できる時刻ずれの範囲(要求仕様)を設定したとき、リアルタイムクロックの時刻ずれが実際にどの程度生じるかによって、最適な更新期間が決まることになります。(デバイスへの頻繁すぎる書き込みは避け、許容できる時刻ずれの範囲を超えない程度のタイミングで、時刻の再設定を実行するようにする。)
リアルタイムクロックの設定にあたり、この点について指摘・考察したサイトを見たことがありませんでしたので、注意喚起も含め、公開しておくことにします。冗長ですけれども。。

まとめ

Raspberry Pi のリアルタイムクロックに関し、関連コマンド、設定の流れについてまとめました。

ネット検索をすると、数年以上前の情報が大半で、コマンドが使えなくなっているサイトが出てきます。また、実際にリアルタイムクロックを実用で使っているのか疑問に思うようなサイトも多いようです。
そこで、最近の現に動いている環境のもとで、把握している情報をまとめ、公開しておくことにします。

関連リンク
・ Raspberry Pi を自動で起動、シャットダウンする
・ 初期設定のまとめ 【OpenCV & Raspberry Pi】
・ LED を ON/OFF する 【Raspberry Pi & Python】

タイトルとURLをコピーしました