EMC_M5StickC_PulseOximeter
M5Stack Store社(?)のマイコンモジュール「M5StickC」と同オプション「UNIT HEART」を使って血中酸素濃度と心拍数…と思しき数値を表示する簡易パルスオキシメーターもどきArduinoスケッチ例のご紹介です。
能書き(経緯)
時は2020年春。世界は「新型コロナウイルス感染症(COVID-19)」に振り回されております。
未知のウイルスによるバイオハザード。ワクチンも特効薬もなく、また病状や感染経路、予防策などの情報も玉石混交に錯綜する中、病状の急激な悪化の予兆を早期に見出しうる観察手法のひとつとしてにわかに注目を集めているのが「血中酸素濃度」とそれを手軽に計測しうる「パルスオキシメーター」というものだそうです。
「パルスオキシメーター」なんて素人にはあまり聞き馴染みのない測定器で、話を耳にして近所を当たってみたところでは体温計などとは違ってどうやら一般のドラッグストアの類いでは取り扱ってなさそうですが、通販サイトなどではピンからキリまでいろいろ扱いがあるようです。得体の知れぬ安いものは2000円くらいから、高級なものは数万円まで。ボリュームゾーンは5000円くらいですかね…。試しにひとつ買ってみたところ、よくわからないけれどもなんだかそれっぽい数字を表示してくれます。血中酸素濃度だけでなくて、心拍数も測ってくれる。3A級 USB ACアダプター大のクリップ状ユニット(買ったものは単4電池×2本で駆動)に指を突っ込めば、程なく測定結果が表示されます。手軽。体温計より手軽(笑)。
気を良くしてTwitterで自慢したりしてたところ…、タイムラインにM5マイコンのオプション「UNIT HEART」の宣伝記事(共立電子産業デジットさんのツイート)が。「GroveケーブルでM5Coreと接続できる心拍センサユニットです。MAX30100を搭載しており、センサの上に指を置くことで、血中酸素濃度と心拍数を測定できます。M5Stackと心拍センサーモジュールを使用して、簡易パルスオキシメーターなども作れます。」と。…なんだって??
え。そんなUNITあったっけ。そんなのがあるなら、買うべきは出来合いよりもそっちだったでは。いや比較用に出来合いも欲しいけど…、値段も手頃そうだし、とにかくこれは試さない手はないのでは…って、持ってるじゃん既に!?Σ(在庫UNIT確認した。) そうでした…、血中酸素濃度だなんてバラックのセンサーユニットでいかほどまともに測れるものか、測れたところで何に使えようかと気にもとめていなかったものの、心拍数センサーとしては興味があって(LED制御とかとインタラクティブ連動させてみることをイメージしてました)、先行投資的に確保していたのでした…。
試せるじゃん…、すぐに!
早速サンプルスケッチを当たってみたものの…、サンプルはサンプル。出力はもっぱらシリアル通信で、スタンドアロンの簡易パルスオキシメーター的に使うには出力表示は自分で作んなきゃいけないっぽい。そりゃそーだ。
「UNIT HEARTなんて新製品なわけでなし、誰か先駆者がいるだろう」とざっとネット検索してみたのだけれど…、意外と少ないのですね…(実のところ情報探索は苦手)。あってもM5Stackのものが多くて、M5StickCでの実装例で引っかかったのは数えるほど。この程度の用途にM5Stackは大仰なんだよなぁ…(手持ちのものは電源SWの挙動が謎だったりもしてイマイチ気が乗らない)。M5StickCがいい。断固いい(我儘)。
いいやもう…、練習がてら自分で実装しよう…。
と、いうわけで作ってみたのが本稿のスケッチです。実用ではなく、機能お試し&デモ用です。
概要
- 機能
- M5 UNIT HEARTセンサーが検出しMAX30100libライブラリが演算出力する血中酸素濃度(SpO2)と心拍数(HeartRate)を表示。
- 表示出力先はM5StickCのLCDディスプレイ、USBシリアル通信、Bluetoothシリアル通信(無線ロギング対応♪)。
- LCDディスプレイでは心拍検出時にビート表示。
- LCDディスプレイの表示方向変更機能(ボタン操作)。
- (測定値は異常値となることが多く、その緩和になるだろうかと外れ値除外&移動平均機能も試しに実装してみましたが、処理の正攻法を把握していない中、何が本当なのかさっぱり分からなくなるので、コメントアウトで機能を殺しています。)
- 動作環境:M5StickC + M5 UNIT HEART
上記のZIPアーカイブを解凍し、含まれている「EMC_M5StickC_PulseOximeter_????????.ino」をArduino IDEで開いてM5StickCにコンパイル・書き込みしてください。
「MAX30100lib」というライブラリを利用しています(M5StickCライブラリ同梱のサンプルスケッチで使われているのと同じものです)。予めArduino IDEに導入しておいてください。Arduino IDEのライブラリマネージャで「MAX30100」を検索すると複数(執筆時点では2つ)引っかかりますが、ここで使っているのは末尾に「lib」がつくものです。(スケッチで直接読み込んでいるヘッダーファイルはそれに含まれる「MAX30100_PulseOximeter.h」です。)
使い方
- 電源ON/OFF
- M5StickC準拠。電源スイッチでON/OFFしてください(ONは2秒、OFFは6秒の長押し)。
- LCDディスプレイ表示方向変更
- 内蔵ボタンA(HOME)(「M5」と刻印された表のボタン)を押下すると、画面の表示方向が90度ずつ回転します(電源ON/OFFの都度リセットされますが…)。
- LCDディスプレイ表示出力
- 「SpO2(%)」が血中酸素濃度、「HR(bpm)」が心拍数です。
- 心拍検出時、「Beat」欄の「@」が短時間(標準では0.1ms)赤くなります。
- シリアル通信出力
- USBシリアル通信とBluetoothシリアル通信に同じ文字列を出力します。
- レコード(行)区切りはCRLF(たぶん 爆)。データ区切りはタブ文字です。
- 「SpO2(%)」が血中酸素濃度、「HeartRate(bpm)」が心拍数です。
- USBシリアル通信の初期設定はボーレート=115200bps(、パリティ=none、データビット数=8bit、ストップビット数=1bit)です。
- Bluetoothシリアル通信のデバイス名初期設定は「M5StickC」です。
- 調整要素
- setIRLedCurrent()関数への引数の値
- 「MAX30100lib」ライブラリ「PulseOximeter」クラスに「setIRLedCurrent()」という関数があります。センサーデバイスのLED電流を設定するものでしょうか。サンプルスケッチなどでも記載があります。
- 「MAX30100_LED_CURR_0MA」〜「MAX30100_LED_CURR_50MA」の間の定められたステップで指定するようです(数値型ではなくenum列挙型)。
- 「MAX30100lib」付属のサンプルスケッチ「MAX30100_Minimal」ではこの設定行がコメントアウトされていて、デフォルトの50mAとなっているようです(コメントアウトされた設定値は「7_6MA」)。
- 想像に違わず数字が大きいほどUNIT HEARTのLED光が強くなるようで、またこれも想像のとおり数字が小さいと安定した測定値が得られないようです。
- そこで「強い方がいいのかな?」と当初「50MA」で設定していたのですが、試用していて何故か頻々とUNIT HEARTの電源が落ちる(LEDが消灯して反応がなくなる)現象があるのはもしかしてM5StickC的に過負荷なのではなかろうかという気がしてきて、本配布では「24MA」の設定としています。検証は不充分ですが、現象は緩和しています。
- どれくらいの値がいいのか、本稿執筆時点で充分詰めきれていません。必要に応じて各位適宜の試行錯誤をお願いします。
問題点
- UNIT HEARTの不意の電源断
- 前項「調整要素」で述べたとおり、UNIT HEARTの不意の電源断が頻発していました。
- 当初Groveケーブルの接触不良だろうかと考えていたのですが、どうも違うようです。
- 原因は充分究明できていませんが、setIRLedCurrent()関数によるLED電流の設定値が大きすぎてM5StickCの電源が過電流になっているのではないかと推測し、設定値を小さくすることで差し当たって現象を回避しています。
- 今後原因究明する…元気はあまりありません(爆)。皆様のご尽力に期待します。
- 測定値の不安定さ・異常・信憑性
- 実装してみて、なんとなくそれっぽい数字が得られはしますが、、、どうも不安定です。血中酸素濃度も、心拍数も。測れてくれなかったり、小さすぎたり、大きすぎたり(数倍にも)します。
- 心拍数が妥当な値の2倍とかになるのは不整脈なのかもなどと思ったりしていますが、血中酸素濃度が250%とか言われるとちょっとなぁ…、とか(苦笑)。
- 安定もしません。
- 状況の緩和を狙って外れ値除外&移動平均機能も試しに実装してみましたが、処理の正攻法を把握していない中、何が本当なのかさっぱり分からなくなるので、配布版ではコメントアウトで殺しました(コード自体は残してあります)。
- 手持ちの市販パルスオキシメーターでも多少測定値のバタつきは見られますが、本スケッチの不安定さはそれとはかなり次元が違っています。
- 本スケッチは「MAX30100lib」ライブラリの演算出力をそのまま利用していて、自前で難しい処理はしていません(知識がなくて出来ません)。同ライブラリ(のPulseOximeterクラス)の限界でしょうか…。
- 測定値の信ぴょう性にも少し疑義があります。市販パルスオキシメーターでは呼吸を我慢すると血中酸素濃度値の低下が観測出来るのですが、本スケッチではそれが見られません。95%くらいを維持するか、極端に数字が暴れるか。そんな風に見えます。…ま、どちらが本当、ともいい難いところはありますが…。
- ともあれ…、本スケッチ程度の安易なコードでは、残念ながら市販測定器に迫る実用性を得るのは難しいようです。
- 「UNIT HEARTをM5StickCでちょっと試してみたい時用のデモスケッチ」くらいにご理解いただければと。
コード解説
200行ほどのしょぼいソースコードです。コメントもアホほど入れましたので、そちらを見ていただくのが良いかと。
他者製作例
参考までに、一連の取り組みの中で見つけた他の方による製作事例をご紹介しておきます。
M5Stackによるものはいくつもあるようなので割愛して、ここではM5StickC+UNIT HEARTによるものを中心に。
開発履歴(だいたい)
- 2020-05-17 EMC_M5StickC_PulseOximeter_20200517
- 外れ値除外&移動平均機能試験実装(最終的にはコメントアウトで機能削除)。
- 2020-05-15 EMC_M5StickC_PulseOximeter_20200515
- 2020-05-12
更新履歴(だいたい)
このページから抜ける→
いさな工房HP トップ
/
@nifty
サイト管理者:岩橋伴典 as いさな
(E-mail:jo3emc@jarl.com / Twitter:@jo3emc)