R1.8.6 心拍測定&7セグ表示完成

 心拍センサーと7セグメント表示器の連携ができたようなので、こちらのページに提示することにした。

 組み立てた様子は下記の通り。マイクロビットを含めた3枚の基板をエッジコネクターでつないでいる。

 初期設定。各種変数の宣言。SPIの設定。セグメントコードの設定。10進数で行う。
 電源を入れた時のセンサーの立ち上がりが不安定なので、センサーデータを取りながら2秒ほどの時間を取る。データは捨てる。
 センサーが落ち着いてから、センサーからのデータを200回取り、データの最大値と最小値を決め、脈拍を打ったことを確認するための基準値を決める。普通は、(最大値+最小値)/2なんだろうけれども、それでは具合が悪かったので(最大値+最小値)×0.7とした。

 メインのプログラム。P2端子からのアナログデータから400を減じたものを5倍している。各測定値の差を大きくして扱いやすいようにしている。
 センサーデータが基準値を越えたら、拍動があったということにする。しかし、1回の拍動で基準値を越える場合は何回かあるので、最初の1回だけを採用しその時の時間を記録する。それをセンサーデータ箱という配列の最後に加える。回数を1増やすことによって、1回の拍動で複数回基準値越えをダブルカウントしないようにしている。
 拍動の回数が3回を越えたら1分間の拍動数を計算する関数に移り、そのあと結果表示を実行する。これを繰り返すのがメインループだ。

 開発途中なので、基準となる数値を7セグに表示させることにした。以下がそのプログラム。
 3桁の数字を表示するには以下のようにした。

  1. P16端子に0を送る
  2. 3桁数字を文字列にして配列変数に入れる
  3. 配列変数の0番目の文字が百の位の数字、1番目が10の位、2番目が1の位となる
  4. 百の位〜1の位、それぞれの文字を数値に変換する
  5. 初期設定でセグメントコードの配列を作っているので、それぞれの位の数字番目の値を読み込んでSPI書き出し
  6. P16端子に1を送る

 センサーデータ箱は配列変数。メインループの中で、拍動の時間を配列変数の後ろに後ろに付け加えているので、計算するときは、その最後の2つを取りだして計算する。2回の拍動間の時間で60秒(60000ミリ秒)を割れば、1分間の心拍数が求まるというわけだ。ここは、複数回のデータで平均を取ってもよいと思う。
 脈拍データを計算できたら、見えないのだけれどもマイクロビットのLEDに表示させている。その様子は7セグ基板の隙間から点灯する様子が伺えるので、7セグに表示されるなと分かる。7セグ表示が変わらなければ、脈拍数が同じだったということだ。
 次の関数、表示では、脈拍数が2桁の場合と3桁の場合で扱いが違うので、使えるように下処理をしておく。2桁判断のフラグを立てるだけだけど。

 関数、表示は基準値表示とほぼ同じ手順。ただ、百の位がない場合は、つまり脈拍が2桁の時はフラグが1と立って来ている筈なので、0が入っているセグメントコード配列の10番目を使って3桁目の7セグは点灯しないようにした。

 この装置を持ってジムに通い測定したところ、下のような結果になった。時に20前後の表示があったが、元気でいるから単純に測定ミスだろう。この心拍センサーはかなり扱いが難しい。耳に挟むものも購入したが、信号変換の道具が必要らしい。

 耳に挟むセンサーを使うことがあったら、またアップします。


R1.7.18 心拍測定追記

 母艦PCからプログラムをダウンロードするときは、USBケーブルでつないでおり、電源もPCから供給される。さほど不安定な電源ではないので、使っているプログラムから得られる最大値は630、最低値は0となる。一方、マイクロビットが背負うボタン電池電源は使えば使うほど消耗する電源なので、使うごとに最大値・最小値は変化する。今測定したら、最大値が1935であり最小値は−350だった。これは、指の当て方でも異なる。

 ということは、やはり基準値は固定値では無理があり、測定の都度に事前の計測をして基準値を決めなければならないということだ。


R1.7.19 一応 心拍測定完成?

 最初に、センサーから得られるデータの最大値と最小値を求め、足して2で割ることによって、基準点を出そうと考えた。ところが、これがうまくいかない。最大値も最小値もおかしいし、従って基準値がうまくいかない。そこで、メインルーチン(「ずっと」のところ)では基準値を700と固定して、センサーからのデータが700を越えたら心拍とした。1回の心拍で下のグラフのように4と5で700を複数回越えることがあるので、700を越えたらフラグを立てて1ずつ増加させる。だたし、フラグが1の時(下のグラフで4の時だけ)の稼働時間を配列変数dataの最後に付加させる。そうすることによって、配列変数には心拍1回毎の時間が入ることになる。

 マイクロビット画面のハートマーク点滅が自分の心拍を規則的に再現できるようになっていたら、ボタンBを押して計算に入る。マイクロビットを左手に持てば、ボタンAよりもBの方が押しやすい。

 配列の最後のデータを取りだすブロックがあるので、それを変数t2に入れる。この時、最後のデータは取り除かれるので、今度はt1に配列の最後のデータを取りだす。
 t2には最後の心拍測定値であり、t1にはその前の心拍測定値が入った。と思う。60秒をミリ秒にしたものを、(t2-t1)で割れば、1分間の心拍数が出る。もうちょっと回数を増やして、平均するとより確からしい1分間心拍数が出るだろう。けれど、10回平均だと以前と変わらないので、今回の2回からの求め方で良しとする。

 こんな具合に左手に持って裏にある心拍センサーに人差し指を当てる。LED画面のハート点滅と自分の脈動がシンクロしたら、ボタンB!

 これを持ってトレーニングジムに行ってこよう。


R1.7.18 心拍測定続き

 プログラムの方は試行錯誤中なのだけれど、できたとしてもハードの方がコンパクトでなければ使えないな.....ということで、コンパクトに作ってみた。

 やっぱりバッテリーはボタン電池を使うことにして、以前購入していたものを使う。心拍センサーのケーブルを短くして3mmワッシャーに半田付け。ネジで止める。
 マイクロビットとバッテリーボードは今のところ10mmのスペーサーでつなげているけれど、6mmでもいいようだ。そうなると、大分薄くなる。
 センサーの裏側が凸凹していて安定しないので、グルーで平になるようにしている。センサー固定用のアダプターを3mmほどのプラ板で作り固定する。センサーが飛び出してくるので、指との絶縁を兼ねてカバー用ビニールを両面テープで固定。

 上から、下から見た図。

 今のところ、プログラムは以下のようになっている。

  1. 10秒の間以下の計測を繰り返す。
  2. 信号が700(拡大処理している)よりも大きい値ならフラグを+1する。でなければフラグを0とする。表示消す。
  3. もしフラグが1であったら、心拍回数を+1、スタート時間として記録。ハートマーク表示。※700以上でもフラグが2以上であればカウントしない。1回の拍動で700を複数回越えることがあるため。
  4. 心拍回数を6倍して表示する。
 しかし、この方法ではLED画面を見て自分でカウントすれば脈拍数は分かるし、10秒待つのがまどろっこしい。
 2回の拍動間の秒数で60秒を割れば脈拍数は分かるよね。この方法にしよう。

 問題点は未だ以下の通りある。

  1. 信号の強さが一定ではないので、700としていた基準を変更する必要がある。測定の都度、最高値と最低値を調べ、その中間を基準とするのがいいようだ。
  2. 指をセンサーに当てるのだが、うまく血管の拍動を拾わないことがある。拍動をLEDに表示させて、順調に拾えているようだったら、Aボタンでも押して測定に入るようにしたい。
 そろそろプログラムも完成するかな?


R1.6.21 心拍測定2

 変数ADを加工せずにそのまま棒グラフに渡すと、下のようなグラフとなる。このままでは縦軸数値の変化が小さすぎるので、拡大しているわけですね。


R1.6.20 心拍測定

 運動をしようと思い、適正な負荷をかけるための心拍測定をしようと考えた。折角ならマイクロビットかラズベリーパイを使おうかと。心拍センサーも2つも持っているし。

 コンパクトさを考えれば、単4電池2本やボタン電池でも動作するマイクロビットが有利。アナログ入力もできるし。そこで、早速つないでみた。マイクロビットでの入力は、スイッチサイエンスさんで扱っている「micro:bit用脈波センサ-PULSE05-MICROBIT」という製品の取扱説明書を参考にさせていただいた。というより、その取説のブロックエディタプログラムそのままを使わせていただいた。

 母艦PCでArduino IDEを立ち上げ、プロッタ機能を表示し、センサーに指先を当ててみると下のような結果を得た。おおっ! それなりの結果が出た。

 ブロックエディタプログラムは下の通り。

 ただ、この先が面倒だ。グラフの横軸は計測回数だ。500回分を表示している。ただ、500回が何秒かは不明。プログラムで測定しないといけない。また、心拍回数は、グラフのピーク個数を数えればよいのだが、マイクロビットに数えさせるにはやはりプログラミングしないといけない。力技でプログラムできるが、スマートにやりたい(できるかな?)。グラフの縦軸は測定した値(変数AD)なのだが、500〜800でピークが立ち上がっている。そこで、700に着目し、フラグ変数を定義する。

  1. ADが700よりも小さい値でフラグが0であったら測定を無視する。
  2. ADが700よりも小さい値でフラグが1であったら、心拍回数を+1とする。そして、フラグを0にする。
  3. ADが700以上でフラグが0であれば、フラグを1とする。ただし、すでにフラグが1であれば測定を無視する。
 こんな感じでいいかな? 順序が違うような感じ..... この辺の実際のプログラミングは明日以降にする。試行錯誤でやるしかないな。

 ところが、さきほど再測定したら、いいようにグラフが再現しなかった。途中でプロッタが止まったり。先は長そうだ。

 さらに、スマホで簡単に心拍測定ができるアプリがあった。カメラを指先に当てて測定するもの。ウーン、プログラミングやめようかな?