リアルタイムクロックを設定する 【Raspberry Pi & RTC】

Raspberry Pi

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

以下の構成で動作確認をしています。
構成の一例:
・ Raspberry Pi  (bullseye、または、buster)
・ Grove リアルタイムクロックモジュール
・ ブレッドボード・ジャンパーワイヤ オス-メス 15cm ×4本(赤、黒)
・ リアルタイムクロック用の電池(以下参照)

背景 ~ 電源を ON/OFF しても時刻を維持したい!

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

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

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

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

Raspberry Pi で使えるリアルタイムクロックで、普及している製品としては、[A] DS1307 を用いたタイプと、[B] DS3231 を用いたタイプの2種類があります。

[A] DS1307 を使ったデバイス
例: Grove リアルタイムクロック (Grove-RTC)
101020013(SEN12671P) 通販コード M-09276 (購入時価格で \730)
★ 上記の写真の製品です。時刻を記憶しているチップとして DS1307 を使ったタイプです。
[B] DS3231 を使ったデバイス
★ DS3231 を使ったデバイスの写真は、こちらを参照してみてください。
GPIO に刺した赤色の基板が RTC であり、Raspberry Pi をバッテリー駆動とすることでモバイルで使えるようにした構成例です。

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

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

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

設定手順

ハードウェアの確認・設定

① Raspberry Pi にリアルタイムクロック RTC の基板を接続します。
※ RTC には、ラズパイ専用のコネクタがついている製品があります。この場合は電池を入れてコネクタを Raspberry Pi の端子(GPIO)に刺すだけですので簡単です。
※ I2C (= I squared C、Inter-Integrated Circuit、IIC) 通信を使いますので、4本のジャンパーワイヤ(電源用の VCC、グランド GND、通信用の SDA、SCL)を接続する必要があります。デバイス等に書かれている SDA は serial data line、SCL は、serial clock line の略称となっています。
※ Raspberry Pi のピン配列は、ターミナルで pinout + [enter] と入力すると確認できます。
以下の手順で I2C 通信を「有効」にすると、Raspberry Pi の 3番ピンが SDA5番ピンが SCL として機能するようになります。Raspberry Pi 側のピン番号(ピン名称)と RTC の仕様(ピン名称)を確認し、4本のピン名称が対応するように接続します。
Raspberry Pi の VCC としては 2番ピン、GND としては 9番ピン(または、6番ピン)を接続すると動くと思います。
※ なお、私が購入した RTC に添付されていた仕様書では、電源は 3.3V ~ 5.5V と記載されていました。
そこで、Raspberry Pi の 3.3V ピンに RTC の VCC をつないだところ、うまく動きませんでした(下記の手順で “UU” が表示されない)。
そこで、RTC の VCC を Raspberry Pi の 5V ピンに接続しなおしたところ、正常に動作しました。当初、原因がわからず、仕様書の記載と実際のデバイスの動作が整合していないことに気づくのに数日かかりましたので、注記しておくことにします。
② リアルタイムクロックに電池(上記の製品の場合、CR1225)を入れます。
③ Raspberry Pi に、キーボード、モニター、必要があれば LAN ケーブル等を接続し、電源を投入します。

ソフトウェアの設定

④ 上記の RTC デバイスは、I2C 通信を使用します。そこで、以下の手順で 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 としてください。
追記を終えたら、上書き保存します。
★ vi エディタの使い方を忘れている場合は、[↓」キーで末尾まで進み、”o” で編集モードに入って、上記の文字列を書き込み、[esc] で編集モードを抜けます。この状態で書き込みを実行する場合は、”:wq” (write & quit)、書き込みをしない場合は “:q!” (quit、強制終了)で vi エディタから抜けることができます。

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

sudo vi /etc/modules

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

i2c-dev

修正後

i2c-dev
rtc-ds1307

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

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

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

i2cdetect -y 1

→ I2C に接続されている(検出できている)デバイスの一覧が表示されます。
この中で、”68″ と表示されているものがあれば、Raspberry Pi 側で、RTC の認識はできています。
I2C 通信のアドレス 0x68 が RTC デバイスのハードウェアに対応しています。

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

⑨ Raspberry Pi を再起動します(”sudo shutdown -h now” を実行し、再度、電源を投入します)。再起動後、上記の 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 の時刻をシステムに設定するよう追記します。

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

→ [ctrl] + x などで上書き保存し、crontab を終了します。
※ ここで1行目はコメント行です。不要であれば記載しなくてもよいです。追記部分が明確になるようにした記載例です。

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

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

その他

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

関連コマンド

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

sudo hwclock --verbose

→ デバイスから読み取った時刻等がより詳細に表示されます。

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

cat /etc/fake-hwclock.data

→ 2024-03-26 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年?などになっています。
また、リアルタイムクロックは電池切れにはなっていないにもかかわらず、日時を読み出そうとするとエラーとなります。
3年間、起動を繰り返したとすると、RTC への時刻の書き込み(更新)は、1,000 回程度は実行したことになります。

また、日頃、Raspberry Pi を自動起動させていましたが、使用時はネットにつないで、Windows パソコンから、リモートデスクトップからアクセスして使っていました。
この使い方では、リアルタイムクロックの設定がずれていたとしても、Raspberry Pi がネットワークに接続した時点で、システム側でネットを参照し、正確な時刻に自動更新してしまいます(以後、起動時や計測時のログの記録も正常になる)。
このため、RTC の劣化が進んでしまうこと自体に注意がいかず、かつ、RTC の時刻がずれていることにも、しばらく気づきませんでした。

一般に、読み書きが可能な電子デバイスは、読み込みには強く、書き込みには弱いことが通常です。
デバイスの書き込みを頻繁に行うと、デバイスの劣化が進みますし、エラーの要因になります。通常は読み込みのみを行うようにし、書き込みの頻度は下げるようにすれば、書き込みに起因するデバイスの劣化やエラーは最小化できるはずです。

経験上、リアルタイムクロックへの書き込みは、毎日のように実行するのではなく、数か月に1度程度とするか、手動で行う、とするほうがよさそうです。
本来は、許容できる時刻ずれの範囲(要求仕様)を設定したとき、リアルタイムクロックの実際の時刻ずれの量から見積もって、最適な更新期間を決めるべき、ということになります。
リアルタイムクロックの設定についてネット検索をしてみると、この点について指摘されているサイトはほとんどないようです。
そこで、実際に RTC を使っていて経験した内容について、公開しておくことにします。

まとめ

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

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

なお、リアルタイムクロックが動いたら、Raspberry Pi で時報を鳴らしたり、指定時刻に自動でシャットダウンをさせるなど、応用範囲が格段に広がります。もし、興味があるようでしたら、以下の関連リンクも参照してみてください。

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

外部リンク [PR] 
・ リアルタイムクロックの例
[A] DS1307 を用いたタイプ
[B] DS3231 を用いたタイプ
・ 電池: CR1225

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