本ページでは過去、最初はArduino DUEを使い、その後M5StickC Plusを使って万歩計を作成しました。
今回は、その万歩計を拡張して、一段の高みへ導きたいと思います。
まず、復習から始めます。Arduino DUEから始まった万歩計開発の変遷を、ご確認ください。
本HPで最初に作った万歩計の記事は以下をご参照ください。
「#21-8 万歩計を作ろう」
MPU9250の加速度センサを使った、最近のちょっと贅沢な万歩計です。……ずっと昔の万歩計は、重りとばねを使った機械式のセンサでした。
とは言え、さすがにDUEとモバイルバッテリを腰にぶら下げて、外を歩く気には、ならなかったなぁ……(1−o−;)。ちょっと、ガタイが大きかったからね。
なので、完成後の動作確認は、DUEとモバイルバッテリをカラビナで腰にぶら下げて、家の中を歩き回って実施しました。
ちなみに、この時の歩いた歩数は、アクティブブザーのモールス信号を使って表現していました。
我ながら、音(モールス信号)で歩数を表現するという、アイディアは面白かったと思うのですが、やっぱり視覚的な表示が欲しいですよね?実を言うと、万歩計に小さな表示器を付けたくて、OLEDディスプレイを導入したのです。
小さなOLEDディスプレイを組み込んで完成させた万歩計の記事は、以下を参照してください。
「#22-3 万歩計を完成させる」
上図は、前節の写真と同じに見えるかも知れませんが、よく見るとOLEDディスプレイを搭載していて、歩数や消費カロリなどを表示しています。
そうでした。上の記事では、ハードウェア面でOLEDディスプレイを追加しただけではなく、ソフトウェア面でも、消費カロリの計算ができるように拡張したのです。
DUEでの工作により、万歩計の肝となる技術は、
歩行を検知するセンサ | : 加速度センサ |
表示器 | : TFTディスプレイや、OLEDディスプレイなど |
バッテリ駆動 | : モバイルバッテリ |
だと、判りました。その後購入したM5StickC Plusには、上に挙げた機能が全て内蔵されています。「これは、M5StickC Plusを使って万歩計を作らなくては!」そう思ったのが、以下記事となります。
「#24-7 万歩計をスマートに作ろう」
「#24-8 万歩計をスマートに作った」
一気に小さくなりました。ポケットなどに忍ばせて使用可能です、良き(1^−^)d。
M5StickC Plus版の万歩計はArduino開発環境でプログラムしたため、コンパイル時にCPUの動作周波数を選択することができました。そこで、動作周波数とバッテリ持続時間の相関も取って見ました(詳細はこちら)。
計測した歩数データは、1分毎にRAMへ保存する形になっていて、取得したデータをExcelに読み込ませてグラフを作成するなど、応用が広がりました。
自作万歩計の最大の弱点は、バッテリ持続時間と、不意な電源消失(バッテリ切れなど)だと考えています。
バッテリ持続時間はね、仕方ないですよ。長時間持たせようとすると、バッテリの容積や重量は、その分大きく・重たくなるのですから。そこは、バッテリの持続時間(容量)と、容積・重量との取捨選択と、なるのです。
今回取り組むテーマは、不意に電源が消失したとしても、その時点までのデータを失わない事です。
M5StickC Plus初版のデータログは、内蔵RAMへ記憶していました。万歩計を装着してお散歩等から戻ったら、電源を遮断せずにUSBケーブルでPCと接続してRAMからログデータを吸い上げる、と言う事をしていました。
RAM(揮発メモリ)なので、電源が消失すると一発アウトです。電源が消失すると、RAMのデータなんか吹っ飛んで消えてしまうのですから。「キャァアアアア!」なんて悲鳴を上げても、消えたデータは帰って来ません。
長時間ウォーキングして帰って来て、「さぞかし沢山のカロリを消費した事だろう」と、意気揚々にログを吸い上げようと思ったらバッテリ切れで電源が消失していた、なんてことも……。
RAMにログを記憶するなら、電源の安定供給が必須です。
要は、RAMが揮発メモリなのがダメなのです。
「揮発メモリ」がダメならば、つい最近テーマとして取り上げた不揮発メモリ、EEPROMを使ったらどうでしょうか?
ここで力を発揮するのが、以下記事です。
「#34-4 EEPROMをログストレージとして使う」
万歩計データを常にEEPROMへ記録しながら動作していれば、突然の電源消失が起きたとしても、それまでのデータはEEPROMに残ります。それは、EEPROMが不揮発メモリだからです。
電源が消失した、正にその瞬間のデータは一部消えてしまうでしょうけれど、一部だけなら、あきらめもつくというものでしょう。
EEPROMの基本的な特性の理解と、予備実験などは済ませてあるので、今回はそれを実用に移します。
これだけの事ですが、不揮発メモリにデータを残すことで一気に堅牢性が向上し、使用時の安心感が増大します。
完成した改訂版プログラムを以下にリンクします。
完成プログラム:m5cp_pedometer.ino
※コンパイルにはM5cp-PSライブラリが必要となります。リンクを辿ってインストールしておいてください。
コンパイルしてM5StickC Plusに書き込むと、シリアルモニタにて、こちらのコマンドを受け付けています。更に、以下のコマンドを追加しました。
いずれも、時刻を設定したり、ログデータを読み出したり、と言った副次的なコマンドですので、シリアルモニタ無しで万歩計として自立します。
万歩計プログラムで計測した歩数などのデータは、一定時間(ped_MINU_LOG=1分)毎にEEPROMへ書き込んで行きます。
EEPROMに記録するレコード仕様は、こちらで定義した通り、基本的な構造だけが規定してあり、データその物の仕様は任意に決定することができます。
今回の万歩計では、以下の通り決定しました。
万歩計レコード仕様:
前回記事(「#34-4 EEPROMをログストレージとして使う」)にて整備したAPI関数を使って、I2C EEPROMモジュールへ書き込みます。ただし、M5StickC Plus版の万歩計プログラムは、FreeRTOSのマルチタスクを使っているので、共有リソースの管理が必要です。
今回追加で検討が必要なリソースは以下の二点でした。検討結果(結論)まで含めて以下を参照してください。
上検討の通り、ログデータはメインプロセスとサブスレッドの両方がアクセスする共有リソース、I2C通信(Wireクラス)はサブスレッドだけがアクセスする占有リソースと判明しました。
ログデータは共有リソースなので、排他制御が必要ですが、書き込みコマンド変数を用意してメインプロセスからサブスレッドへコマンドを発行する事とします。手順は以下の通りです。
排他制御だからと大げさにセマフォを使わなくとも、この程度のハンドシェイクで排他制御可能でした。手を抜ける所は抜いて済ませましょう。
なお、EEPROMは特性上、記憶容量と書き換え回数に制限があるため、記録する必要のない場合には書き込みを避けるべきです。よって、前回記録したデータを保持しておき、前回値と比べて歩数等のデータに変化が無かった場合には、書き込みを実行しない様にプログラムしておきます。
では実験です。M5StickC PlusとI2C EEPROMモジュールを以下表の様に接続して、万歩計プログラムを書き込んでください。
M5StickC Plus | 接続 | I2C EEPROMモジュール |
3V3 | → | VCC |
GND | ⇔ | GND |
G0(SCL) | ⇔ | SCL |
G26(SDA) | ⇔ | SDA |
以下に、完成した万歩計の外観図を示します。
デュポンケーブルでI2C EEPROMモジュールを接続しており、見た目は「ちょっと……」な感じですが、DIYですので、実用化前の試作段階とでも思っていただければ幸いです。
※ハット🎩と呼ばれる拡張モジュールの様な実装ができたらスマートなのですが……。
なお、I2C EEPROMモジュールはオプションです。今まで通り、I2C EEPROMモジュールを接続しない状態であっても、万歩計としては機能します。I2C EEPROMモジュールを接続する事で計測データが不揮発メモリに記録され、不意な電源消失でもデータを失うことなく、安心して使用できるようになります。
EEPROMに記録したレコードを読み出したい場合は、シリアルモニタを接続して【list】コマンドを使うことができます。
読み出しサンプル:【 】内はシリアルモニタからの送信データ
【listb,2000】
LOG+ 0x2000: 0x1655,'PD',182556400000000500001a40
LOG+ 0x2010: 0x1656,'PD',182556a20000001e00006bda
LOG+ 0x2020: 0x1657,'PD',1825570300000098000157de
LOG+ 0x2030: 0x1658,'PD',18255765000001150002418a
:
: (中略)
:
LOG+ 0x2270: 0x167c,'PD',18256617000009ac00159aaa
LOG+ 0x2280: 0x167d,'PD',182566de000009b00015ad06
LOG+ 0x2290: 0x167e,'PD',18256741000009bb0015ec6c
LOG+ 0x22a0: 0x167f,'PD',18257d1b000009c800162d1c
LOG: found 43 records
OK: listb: eep_radr=0x22b0, eep_ridx=0x1680
歩数データ(PDレコード)はバイナリ値なので、【listb】コマンドで表示した方が、扱い易いと思います。ビッグエンディアンで記録する仕様(※)なので、Excel等に読み込ませた後で、mid()関数で32ビット整数データを切り出し、hex2dec()関数などで整数値に変換して活用できます。
※リトルエンディアンは頂けません。Excelに読み込ませても、もう少し複雑な処理をしないと整数データに変換できませんから。
Excelに貼り付けて処理したグラフを以下図に示します。
近くのスーパマーケットまで買い出しに出かけた往復と、帰宅後、バッテリ切れして自動的に電源が遮断されるまで記録し続けたログです。横軸は経過時間[分]、左縦軸に歩数、右縦軸にバッテリ残量[%]を取っています。
上で考察した通り、移動距離、歩行速さなどから鑑みて正しく歩数がカウントできており、かつ、バッテリ残量低下により自動的に遮断されるまでの間、EEPROMに記録できたことが確認できました。
I2C EEPROMモジュール以外にも、万歩計に、とあるセンサモジュールを組み合わせた応用として、以下の様なアイディアを考えていたのですが、断念しました。断念した理由と共に、1つのアイディアとして、ご紹介だけしておきます。
万歩計を様々なセンサと組み合わせてデータ取得する応用を考えていたところ、結局どれも物にならず、I2C EEPROMのログ記録だけが残った感じです。そう言う事もありますよ……。そうしたアイディアの中から、1つでも物になったら趣味のDIYとしてはGoodでしょう。引き続き見守ってください。