環境センサーパル AMPIENT SENSE PAL を用い、センサー値の取得を行います。
コイン電池で動作させるための、スリープ機能を利用します。
ここでは、ボード上の4ビットDIP SWのうち3ビットを読み出して子機のIDとして設定しています。0の場合は、ID無しの子機(0xFE
)とします。
LEDの設定を行います。ここでは 10ms おきに ON/OFF の点滅の設定をします(スリープを行い起床時間が短いアプリケーションでは、起床中は点灯するという設定とほぼ同じ意味合いになります)。
このアクトではもっぱら無線パケットを送信しますので、TWENET の設定では動作中に受信回路をオープンにする指定(TWENET::rx_when_idle()
)は含めません。
ボード上のセンサーはI2Cバスを用いますので、バスを利用開始しておきます。
このアクトでは、1ms周期で呼び出させる(アプリケーションループの呼び出しタイミングは不定期な遅延が発生します)TickTimerのイベントを起点としてセンサーの読み出しや送信要求を行います。TickTimer.available()
がtrue
になったときに処理を行います。これによりおよそ1msごとにif節内の処理を行います。
ボード上のセンサーは .sns_LTR308ALS
または .sns_SHTC3
という名前でアクセスでき、このオブジェクトに操作を行います。センサーの完了待ちを行います。まだセンサーの取得が終わっていない場合(.available()
がfalse
)はセンサーに対して時間経過のイベント(.process_ev(E_EVENT_TICK_TIMER)
)を送付します。
上記2つのセンサーがavailableになった時点で、無線送信などの処理を行います。
送信手続きについては他のアクトのサンプルと同様です。ここでは、再送1回、再送遅延を最小にする設定になっています。
パケットにセンサーデータを書き込み際に、センサーデータを取得しています。センサーの値を取得するメソッドはセンサーごとに違います。
照度センサーは.get_luminance() : uint32_t
で得られます。
温湿度センサーは以下のように取得できます。
.get_temp_cent()
: int16_t
: 1℃を100とした温度 (25.6 ℃なら 2560)
.get_temp()
: float
: float値 (25.6 ℃なら 25.6)
.get_humid_dmil()
: int16_t
: 1%を100とした湿度 (56.8%なら 5680)
.get_temp()
: float
: float値 (56.8%なら 56.8)
得られた値のうち温度値は int16_t
ですが、送信パケットのデータ構造は符号なしで格納するため、uint16_t
にキャストしています。
送信が成功すれば b_tansmit
を true
にし、u8txid
に送信パケットの識別IDを格納し、完了待ちします。送信が失敗すれば sleepNow()
によりスリープします。
loop()
中 b_transmit
が true
になっている場合は、送信完了チェックを行い、完了すれば sleepNow()
によりスリープします。
送信完了に確認は the_twelite.tx_status.is_complete(u8txid)
で行っています。u8txid
は送信時に戻り値として戻されたID値です。
ボード上のセンサーの取得を開始します。多くのセンサーは、取得を開始してから完了するまで数msから数十msの時間を必要とします。
5行目で、温湿度センサー SHTC3 のデータ取得を開始します。
6行目で、照度センサー LTR308ALS のデータ取得を開始します。
7行目は、送信完了フラグをクリアします。
スリープに入る手続きをまとめています。
ここでは、起床までの時間を乱数により 1750ms から 2250ms の間に設定しています。これにより他の同じような周期で送信するデバイスのパケットとの連続的な衝突を避けます。
3行目、この例ではシリアルポートからの出力を待ってスリープに入ります。通常は消費エネルギーを最小化したいため、スリープ前のシリアルポートの出力は最小限(または無し)にします。
スリープ前にflushを行うと、出力が不安定になる場合があります。
スリープに入るには the_twelite.sleep()
を呼びます。この呼び出しの中で、ボード上のハードウェアのスリープ前の手続きなどが行われます。たとえばLEDは消灯します。
パラメータとしてスリープ時間をmsで指定しています。
TWELITE PAL では、必ず60秒以内に一度起床し、ウォッチドッグタイマーをリセットしなければなりません。スリープ時間は60000
を超えないように指定してください。
スリープから復帰し起床すると wakeup()
が呼び出されます。そのあとloop()
が都度呼び出されます。wakeup()
の前に、UARTなどの各ペリフェラルやボード上のデバイスのウェイクアップ処理が行われます。例えばLEDの点灯制御を再始動します。
ここではセンサーのデータ取得を開始しています。
より安全な実装として、このアクトでは以下の例外処理を強化します。
センサー取得部分でavailableにならなかった場合の例外処理が記述されてません。
送信完了待ちで送信完了が通知されない場合の例外処理が記述されていません。
上記いずれもタイムアウト処理を行います。現在の時間は millis()
により取得できます。
アクト PAL_AMB-UseNap は、センサーのデータ取得待ちをスリープで行い、より低消費エネルギーで動作できます。