Wio Extension - RTC を MicroPython から使う

この記事は[SORACOM Advent Calendar 2019](https://qiita.com/advent-calendar/2019/soracom)の15日目の記事です。[SORACOM Meetup #0 in 札幌](https://soracom.connpass.com/event/128901/)のLTでの [Wio Extension - RTC ネタ](https://speakerdeck.com/minoruinachi/wio-extension-rtc-wo-micropython-karashi-u)を元に、最新版の MicroPython API ベースに解説します。

# Wio Extention - RTC について

[WioLTE](https://soracom.jp/products/module/wio_lte/)には１つ大きな欠点があって、LTEモデムが電気を食いすぎるため、バッテリーからの電源供給では長期間の測定が行えないことです。

これを回避するため、2019年6月に SORACOM から[Wio Extension – RTC セット
](https://soracom.jp/products/kit/wio_extension_rtc_set/) (以下、WioRTC と略記)が購入できるようになりましたので、さっそく入手して使ってみました。ざっくり言うと電源を自動で ON/OFF してくれるタイマーなようなもので、これで測定していない時間帯には電源を OFF にしておくことによりバッテリーを長持ちさせようとするものです。

@ciniml さんが WioTTE に MicroPython を移植してくれてからというもの、WioLTE では MicroPython ばかり使っているので、WioRTC も MicroPython から利用したいと思いました。ということで、[Aruduino用の公式サンプルスケッチ](https://github.com/Seeed-Studio/Wio_Extension_RTC)などを参考に MicroPython 用スクリプトを作成してみました。

# MicroPython での WioRTC の使い方

MicroPython スクリプトは以下の github に置きました。セットアップ方法は README.md を参照してください。

```
https://github.com/MinoruInachi/wiortc-mpy-sample
```

WioLTE と WioRTC は I2C でやりとりするため、違いの I2C ポートをつなぎます。WioRTCにはI2Cポートが２つありますが、どちらにつないでもかまいません。もう１つのほうは、WioLTE で塞がってしまった I2C ポートの代わりに使えます。

![WioLTEとWioRTCの接続](https://raw.githubusercontent.com/SeeedDocument/Wio_Extension-RTC/master/img/connection.png)

WioRTC で実際にタイマー制御を行っているのは [NXP PCF8523](https://www.nxp.com/products/peripherals-and-logic/signal-chain/real-time-clocks/rtcs-with-ic-bus/100-na-real-time-clock-calendar-with-battery-backup:PCF8523)というチップになります。ドキュメントをながめるといろいろな機能があるのですが、今回扱うのはカウントダウンタイマーだけにしておきます。

以下、簡単に作成した MicroPython API の使い方を説明します。

### WioRTC の初期化

まず、WioRTC インスタンスを作成して始動させます。

```python
from wiortc import WioRTC  # WioRTCクラスをインポート
from machine import I2C  # I2Cクラスをインポート

i2c = I2C('I2C')  # I2Cポートのインスタンスを作成
rtc = WioRTC(i2c)  # I2Cポートを指定して WioRTC インスタンスを作成
rtc.begin()  # WioRTC の始動
```

### カウントダウン時間の設定

カウントダウン時間は以下のように秒数で与えます。

```python
rtc.set_wakeup_period(300)  # カウントダウン時間として300秒(5分)を指定
```

内部的にカウントダウン時間は８ビット符号なし整数(0-255)で与えます。これでは例にありような300秒を指定することはできません。そのため、タイマーにはカウントを1秒単位、1分単位、１時間単位にするモードが用意されています。set_wakeup_period() メソッド内では指定した秒数によって自動的にこの３つのモードが切り替わるようにしています。

### 電源断

カウントダウン時間の設定が終わったら電源を切ります。

```python
rtc.shutdown()  ## WioRTCからの電源供給を止める
```

カウントダウン時間が経過すると、WioRTC が電源供給を再会し、WioLTE のスクリプトが再実行されます。

### API利用法のまとめ

WioRTC の API の利用法をまとめると、以下のようなイメージになります。

```python
# wiortc インポート
from wiortc import WioRTC
from machine import I2C

# WioRTC オブジェクト作成・始動
i2c = I2C('I2C')
rtc = WioRTC(i2c)
rtc.begin()

# この間に何らかの WioLTE の処理

# 何秒後に電源を入れるか設定して電源断
rtc.set_wakeup_period(30)
rtc.shutdown()
```

### EEPROM について

WioRTC には PCF8523 の機能と関係なく、4KBのEEPROM(不揮発性メモリ)が載っています。これがある理由は、おそらく電源遮断中も残しておきたい情報を保存しておくためと思われますが、当然ながら書き込み回数には制限があるはずなので、頻繁に利用するわけにもいかないでしょう。

いちおうこの EEPROM を読み書きする API も用意しています。

EEPROM から値を読み込むには以下のようにします。

```python
val = bytearray(1)  # 長さ１のバイト配列を作成
rtc.eeprom_read(0, val)  # EEPROMのアドレス0の値をvalに格納
```

逆にEEPROM に値を書き込むには以下のようにします。

```
rtc.eeprom_write(0, val)  # EEPROMのアドレス0にバイト配列val内容を書き込む
```

# おわりに

WioRTC を利用するようになってから、数週間レベルの測定は手持ちのモバイルバッテリー(2A供給可能、5000mAh)で出来るようになりました。これで、いつでもどこでもセンサーで測定して SORACOM Harvest にあげるといったことが可能になりました。さらには MicroPython からも利用できるようにすることで、プロトタイピングが実に簡単に出来るようになりました。

この環境を使って心拍数を測定して SORACOM Hervest にデータをあげる例については[SORACOM のAdvent Calendar 2019 ふたつめの方](https://qiita.com/inachi/items/96253f6b4f64933062d1)のほうに書きました。