公開日:2022/07/16
title.png

21st Season


#21-8 万歩計を作ろう

 今や100均でも売っている万歩計ですが、これをArduinoで作ってみましょう。

 必要な部品は、Arduino本体と、MPU9250等の加速度センサです。
 これ、つい最近も使いましたよね?そう、空中マウス(別解)を作ったのと同じ部品なのです。

  「#21-7 空中マウスの別解

 前回、空中マウスを作った後、そのまま万歩計へ向けて改造して使いました。従って、使用したのはArduino DUEです。

 では、設計を進めて行きましょう。

万歩計とは?

 100均でも売っている万歩計ですが、今時は、時計型のウェアラブル端末やスマートフォンにも、万歩計機能が内蔵されていますよね?使っていらっしゃる方、居られますか?

 100円+消費税で売っているような代物は、ばね等で固定した重りが、歩くことで生ずる衝撃によって上下に動くのをカウントして表示しています。
 一方、時計型ウェアラブル端末やスマホではどうしているか?と言うと、加速度センサを使って、歩いた時に生じる衝撃(加速度)を検出しています。

 Arduinoを使った電子工作では、振動センサなどを使って、歩いた時の衝撃を機械的に検知するなどの方法もあるでしょう。今回はスマホなど最新機器で採用されているのと同じ、加速度センサを使って実現します。→100円では作れないので、ちょっと贅沢な万歩計となります。

「歩行」の検出

 加速度センサを使って、「歩行🚶」を検出する方法について考察してみましょう。

 100均万歩計の様な機械式の装置では、衝撃だけを検知してカウントするので、その場で足踏みしても、「歩行」と見なして歩数をカウントします。
 ですが上でモデリングした通り、歩く度に進行方向への加速度が発生するので、これをちゃんと分離して検出できれば、「歩いた」状態と「足踏みした」状態とを切り分けることができるかも知れません。

 ただ実際には、進行方向に発生する加速度は、常に検出してしまう重力加速度に比べると小さい物なので、これを分離して検出するのは困難ではないか?と考えられます。

 そこで、今回作成するArduino万歩計の目標仕様は以下とします。

 測定した加速度ベクタの成分値を使わずに、ベクタの大きさだけで判定するお陰で、ちょっと良いこともあります。加速度センサMPU9250の設置方向が不問となるので、腰などに固定するだけに留まらず、無造作に鞄の中等に放り込んでおいたとしても、恐らく歩数をカウントできます(原理的には)。

※ただし、当方では未確認です。装置(MPU9250)が鞄の中で自由に動く(飛び跳ねたりする)ことで、加速度の検出状況が変わると、うまく歩数をカウントできない場合があるかもしれないので、用途に合わせてモデリングしなおして見てください。

予備実験(データ収集と解析)

 まずは予備実験として、実際に歩いた時の加速度データがどのような変化を示すのか、測定して見なくては始まりません。

 この後、完成させる装置プログラムを使うと、ここで実施する予備実験を実行できるようになっています。
 装置を腰などにぶら下げて歩き回る必要があるので、電源をPCから供給してもらう訳には行きませんでした。よって、以下図の様なモバイルバッテリから電源を供給して実験しました。

ar66_mbatt.jpg


 完成した装置は下図となります。

a218_expr.jpg

 DUEに加速度センサMPU9250を固定して、Arduino DUEの基板に空いたM3ねじ穴にカラビナを装着しました。この装置を右の腰付近にぶら下げて、歩いてみました。


  予備実験サンプル:

 データはDUEの内蔵RAMに記録してあるので、電源を切ると消えてしまいます。モバイルバッテリから給電したまま電源を切らずに、ハードウェアシリアル端子(D18(TXD1),D19(RXD1),GND)へFTDI(下図)等のUSB⇔UART変換モジュールを接続してシリアルモニタを起動し、データを吸い上げました。

ar41_ftdi.jpg


 通常使うSerialクラスは、DUEのUSB⇔UART変換経由でデータをやり取りするので、今回の様な用途では使えません。これを解決するため、DUEのハードウェアシリアル#1に割り当てられたSerial1クラスを使っています。以下、該当コードの抜粋です。

  #define USE_SERIAL
  #define SerialX Serial1
    :
    : (中略)
    :
  void setup (void)
  {
  #ifdef USE_SERIAL
    // serial
    SerialX.begin (9600);
  #endif // USE_SERIAL
    :
    :(後略)



 Serial1と接続して、【log】コマンドを実行すると、測定したデータが送信されてきます。

  予備実験サンプル:【 】内はシリアルモニタからの送信データ
  【log】
  OK+ 4280 15988 1736
  OK+ 4360 15412 2088
  OK+ 4464 15588 1968
    :
    : (中略)
    :
  OK+ 4596 17428 1276
  OK+ 4524 16444 844
  OK+ 4308 15208 360
  OK: log

 送信されるデータは16ビット符号付整数で、x軸、y軸、z軸方向の加速度データです。上の測定例だと、y軸方向が鉛直方向に一致していたため、y軸方向のデータから、(重力加速度)1G=16,384LSBに近い値が読み出せています。


 測定したデータをExcelに取り込んで、グラフ化したのが以下図となります。

a218_walkacl.png

 これを解析して、「歩行」をモデリングしていきます。

 この測定データは、歩く時に足に掛かる負荷を測定した、と取ることもできます。この時の衝撃は、恐らく、被験者の体重で異なると推定されます。
 体重の異なる対象者に広く適用するには、被験者を変えながら、もう少し色々なデータを取り、より精密に分析・モデル化する必要があるかもしれません。本ページの試作としては、被験者が筆者一人しかいないので、この1データだけを使ってモデリングを実行しました(1^_^)/

ソフトウェアの設計

 前節でモデリングした「歩行」と加速度の関係を前提に、歩数をカウントするアルゴリズムを起こしてみましょう。

 加速度の移動平均値が上昇している場面をped_stat_walk=ped_WK_INCL、下降している場面をped_stat_walk=ped_WK_DECRとします。すると、歩数をカウントするアルゴリズムは以下の様に記述することができます。

 このアルゴリズムで、加速度の変化(山と谷の周期)を検出して、歩数をカウントすることができるはずです。
 パラメータは、山と谷の差分(高さ)であるped_RNGEと、移動平均の区間ped_MAX_MVAです。これらのパラメータは、前節の予備実験によるデータの解析からモデリングしました。

表示が要る

 100均万歩計でさえ、カウントした歩数を表示する表示器を持っています。そうですね、完成品にするためには、表示器が必要ですよね。

 しかし、今回は以下の様な理由から、表示器の接続は断念しました。

 そうは言っても、「歩行」を検出しているかどうかと、カウントした歩数は知りたいですよね。

 そこで、アクティブブザー(音)を使ったU/I(User Interface)を考えてみました。


 以下、数字のモールス符号表です(世界共通)。

数字 モールス符号 備考
0 数字は全て5ストロークの符号。
1 トン(・)の数が、数値と一致。
2
3
4
5
6 ツー(−)の数+5が、数値と一致。
7
8
9

※モールス符号については、「#6-9 モールス符号発信機」に解説があります。

 数字だけなら上表の様に簡単なので、慣れてくれば多分、聞き取れるはずです。

  例題)以下の音は何歩でしょうか?
    
    a218_mrsnum.wav


 いきなり4桁の数値は難しかったですか?答えは、「8,023」歩でした。でも、何となく聞き取れましたでしょう?
 もし、「速すぎて聞き取れないよ〜」と言う場合には、以下の定数で調整できます。遅くしたければ、数値を大きくして見てください。

  const int mrs_msec_SDOT=50;  // mrs: morse short dot time [ms]


 WAVファイルの波形表示(下図)で確認すると、一目瞭然です。

a218_mrswav.png

 上図は、拙作sPeachでWAVファイル(a218_mrsnum.wav)を再生している場面のスクリーンショットです。

 「やっぱり表示(LCD)が欲しいな〜」と、言う方は各自対応お願いいたしますm(1__)m。かさばるとか消費電力とかを何とかすれば、表示装置を接続するのは、そう難しくはないはずです。

出来上がり

 以下に完成したプログラムをリンクしておきます。

  完成プログラム:pedometer.ino


 プログラム先頭付近の「#define USE_SERIAL」を有効にしてコンパイルすると、シリアルモニタから以下のコマンドを受け付けています。

  シリアルモニタコマンド仕様:

 すべて、デバッグおよび予備実験用のコマンドです。普通に万歩計として使う場合は、シリアルモニタ無しで自立できるので、予備実験でDUEから測定データを吸い出す時以外は「#define USE_SERIAL」を無効にしてコンパイルしてください。

歩く実験

 最後に、装置を組み立てて最終実験を済ませてしまいましょう。ほとんどの部分は前回の空中マウスと同じですので、空中マウスの装置が維持されていたら、あと一息です。

 以下に回路図を示します。

a218_schem.png

※上の回路図は「#22-2 OLEDディスプレイを使う」にて、OLEDディスプレイが追加になっています。その点、本ページの記載と異なることに注意してください。

 空中マウスと比べて、D12に接続したアクティブブザーが追加となるだけです(1^−^)。


 以下に、完成した万歩計の外観図を示しておきます。

a218_expr.jpg

 表示器代わりのアクティブブザーがMPU9250と同じブレッドボードに実装されています。腰などにつるすための器具(カラビナなど)は、DUEの基板に空いたM3ねじ穴を活用して取り付けました。
 PCから離れて上の装置だけで自立させるため、電源はモバイルバッテリなどから給電が必要です。


  実験サンプル:


 試作としては意外と簡単でした。完全に汎用にするには、万人に適用可能なモデリングを作るのに、もう少しデータ取りが必要で時間がかかるかな?後は表示器の追加や、全体としてコンパクトに作る事、等ですね。本HPとしては、この時点(試作・試験完了)でテーマを閉じておきます。


btn_arduino.png

btn_prev.png btn_next.png

home