awawa

@awawaInu

脈拍センサを使ってリアルタイムに心拍数を推定する

はじめに

操作しているゲームのキャラクターともっと心を通わせたい、そんな思いを実現するために操作者(私)の心拍数をPCに入力する装置を作りました。 私の心拍数が増えるとキャラクターの息が荒くなるということが現実のものになります。

センサで得た脈拍信号(心電図的なもの)から、PCで心拍数を得るところまでがこの記事の内容で、それをゲームに反映させる部分は別の記事にしたいと思います。 プログラムのこととかはQiitaに投稿してあります。qiita.com

今回は市販の脈拍センサ + マイコン (Arduino) + PC (python) の組み合わせで心拍数を推定しています。

やったこと

最初の手順は簡単です。まず脈拍センサを買いました。 www.amazon.co.jp こんなんです。

f:id:semetemo:20220226233007p:plain
これで心拍数をはかれる
センサの光る部分(写真は電源が入ってないので光ってません)に指を押し当てると、心電図"的な"ものをとることができます。

つづいて配線をして、センサをマイコン(今回はArduino UNO)につなぐと、マイコンがセンサと通信して、リアルタイムに脈波を取得できます。

f:id:semetemo:20220226233240p:plain
1回の波が1回の鼓動

このマイコンをPCとUSBでつなぐと、シリアル通信という方法で、データのやり取りをすることができます。これによりセンサの信号をPCにとりこんで、それを解析して心拍数を推定します。

f:id:semetemo:20220226233347p:plain
毎秒推定結果が表示されます

あとは心拍数を使ってアバターの表情を変えるなり動きを変えるなり好きにできます。 マイコンは今回はArduinoUnoというものを使っていますが、もっと安いProMiniの互換品とかでも動かせると思います。PCを除けば1,500円前後でいけそう。

筐体について

どうやってセンサを固定するか

脈拍センサは指などに光を照射して、光の戻り具合で脈拍を測っています。つまり、目に見えない微妙な明るさの変化をつかって脈拍を測っています。そのため、センサがちょっと動いたりすると値が大きく変動してしまって、正しく脈拍が取れなくなってしまいます。 ということで、いい感じにセンサを固定する必要があります。今回は手元にあったケーブルを束ねるマジックテープを使って指に巻けるようにしました。

f:id:semetemo:20220226233908p:plain
ありものでなんとかなった
ついでに大事な点として、センサの指に触れる部分にセロファンテープを貼っています。回路に直接指が触れるのでそれによりショートして値が飛ぶことがありました。

どこで測るのか

本来は指先か耳たぶで測ることが推奨されています。確かに指先と耳たぶが信号が強くて測りやすいですが、指先につけたらゲームができないし、耳たぶだとヘッドフォンの邪魔になりそうです。

またApple Watchのように腕で測ると、信号が比較的小さく短時間のデータに基づいたリアルタイムな心拍数の推定をしようとするとあまり正確に算出できませんでした。加えて意外に、センサをぴったり腕に固定するのは難しかったため、腕の動きによる値のブレの問題もありました。

首もためしてみましたが、心拍が大きくとれる一方、呼吸や発話の影響が大きく、しゃべらず静かに呼吸する前提でないと心拍数はうまく推定できませんでした。

f:id:semetemo:20220226234720j:plain
センサをベルトに縫い付けて首に巻いてみたけど精度はいまいちだった。
最終的に指先よりは若干信号は弱いものの、親指の第一関節と第二関節の間に固定することにしました。

Arduino側の実装

センサをArduinoに接続する必要があります。センサのVin, GND, SDA, SCL端子をそれぞれArduino UNOの5V, GND, A4, A5端子に接続します。 続いてセンサの値を読みこんでPCに取り込むプログラムを作成し、これをArduinoに書き込みます。 プログラムは、PC側の処理のプログラムも含めてgithubに配置しています。 github.com

PC側の実装

PC側にはArduinoで読み込んだ脈拍の信号が順次送られてきます。しかし生の信号の波形のままではコントローラーとして使いづらいので、ここから心拍数を推定します。

これは簡単そうに見えて一筋縄ではいかなかったです。ひとつに、脈拍の信号には計測したい信号以外のノイズが含まれているため、ノイズにできるだけまどわされずに脈を検出する必要があります。 もう一つに、脈は毎回毎回同じ強さなのではなく、1回1回異なる強度で、またセンサの配置などの条件によっても異なる強度で入ってきます。

このあたりを踏まえつつできるだけ正確に脈拍から心拍数を推定するアルゴリズムを作る必要がありました。アルゴリズムの工夫について詳しくはQiitaの方の記事にそのうち書こうと思います...

作成したプログラムはデフォルトで、1秒ごとに過去5秒のデータを使って心拍数を算出します。この条件で自分の指のデータに対してある程度正しく、リアルタイムに心拍数が推定できていそうでした。

息を止めると止めてすぐに心拍数が下がって、しばらくすると徐々に上がり、呼吸を再開した瞬間に一気に上がるみたいなかなり時間的に素早い変化も取れているようです。

早くこれでVRchatのアバターを操作、いやアバターと一心同体になりたいです。

なお心電図からの心拍推定の研究があってpython用にツールキットとして公開もされているようです。しかし、単にこれを適用するだけでは手元のセンサデータに対してはうまく動作しませんでした。 Welcome to BioSPPy — BioSPPy 0.6.1 documentation