脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

RasperryPiでリアルタイムクロック(RTC-8564NB)を使ってアラームを設定する

ラズベリーパイで以下のRTCを使う方法です
akizukidenshi.com
f:id:portaltan:20181017131108p:plain

事前準備

RTC-8564NBはラズベリーパイとi2cという通信方式で通信を行います
事前にraspi-configでi2c通信を有効にしておきます

接続&認識

上記の秋月の製品はソケット等もついているのでそのままブレッドボード等でラズベリーパイに接続します
接続したらまずはラズベリーパイがRTCをきちんと認識しているか、されていたらアサインされたアドレスの確認をします

$ 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: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --  

次にRTC用のドライバを適用させます

$ sudo sh -c "echo pcf8563 0x51 > /sys/class/i2c-adapter/i2c-1/new_device"
$ 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: -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --    
  • 8564ではなく8563になっていますが、8563はラズパイにデフォルトで入っていて、かつ8564互換になっています
  • UUは認識しているだけではなく、実際にOSが利用している状態です

時刻あわせ

初期状態のRTCは時刻が正確ではない可能性があるので、まずはシステム側の時間を使って時刻をあわせます

# (念のために)システム側の時刻を最新にupdate(要ネットワーク)
$ sudo ntpdate -v ntp.nict.jp
$ date
Wed 16 Oct 22:08:02 JST 2018

# 次に実際にRTCにシステムの時刻を反映させます
$ sudo hwclock -w

# (逆にRTCの時刻にシステム側を合わせたい場合はsオプションを使います)
$ sudo hwclock -s

# 実際に一致しているかはcオプションで確認します
$ sudo hwclock -c
hw-time      system-time         freq-offset-ppm   tick
1539694800   1539694800.003842
1539694811   1539694811.004140                25      0
1539694822   1539694821.004745                39      0

Alarm機能設定

このRTCは設定した時間で割り込みを行うAlarm機能があります
f:id:portaltan:20181017122320p:plain
端子はオープンドレインなのでAlarmがオンになるとLOWになります
f:id:portaltan:20181017122517p:plain

AF/AIEの設定

割り込みのタイミングとして、決まった時間で割り込みを行うAIE(Alarm Interrupt Enable)と、決まった周期で割り込みを行うTIE(Time Interrupt Enable)という設定があります
そして、割り込みが発生した時点でそれぞれAF(Alarm Flag)、もしくはTF(Timer Flag)がセットされます
これが1になっていると割り込みが発生しないので、都度フラグクリアをしないといけません
f:id:portaltan:20181017130955p:plain

# OSがRTCを掴んでいるので一時的に外します
$ sudo modprobe -r rtc_pcf8563

# AIEをセットし、AFをクリアします(TF/TIEも今回利用しないのでクリアします)
$ sudo i2cset -y 1 0x51 0x01 0x02 b

# 確認
$ sudo i2cget -y 1 0x51 0x01
0x02

今回はAFをクリアして、かつAIEをセットしたいので、上記のレジスタのAddress01(0x01)のbit1だけ1であとは0にします
00000010b(2進数)は16進数で0x02になのでそれをvalueとして送ります

Alarm時刻の設定

次に実際にAlarmの時刻を設定します
レジスタのAddress 09~0Cがそれぞれ以下のように対応しています

  • 0x09: Minute Alarm
  • 0x0A: Hour Alarm
  • 0x0B: Day Alarm
  • 0x0C: Weekday Alarm

例えば毎日10:30にAlarmが発生するように設定します
(RTCにはUTCで時間が入っているのでUTC基準で入力します)

# Minutes Alarm(30分)
sudo i2cset -y 1 0x51 0x09 0x30
# Hour Alarm(10時)
sudo i2cset -y 1 0x51 0x0A 0x10
# Day Alarm(0x80: AE)
sudo i2cset -y 1 0x51 0x0B 0x80
# Weekday Alarm(0x80: AE)
sudo i2cset -y 1 0x51 0x0C 0x80

注意したいのが単純に30分なら16進数に変更して30 -> 0x1Eとすればよいのではなく、レジスタテーブルに記載してある通りに入力する必要があります
f:id:portaltan:20181017133018p:plain
30分の場合は00110000bになり、16進数にすると0x30になります
(このRTCでは仕様上直感的に10進数ライクに数字を入れられるように設計されています)

0x80とはAE(アラーム制御ビット)で、これをセットすると値に関わらずにそのAddressはAlarm状態になります
今回はDayとWeekDayのAEを設定しているので、日にちや週に関わらず毎日毎週10:30になるとAlarmが発生することになります

以上で設定は完了です
設定した時間になると/INTピンがLOWになります