きっかけ
最近家族の発熱があったりするのと、コロナ軽症者は血中酸素濃度をモニタして症状を判断するとのことなので、2 月くらいに買ってほったらかしにしていたセンサー、MAX30102 をつかってパルスオキシメーターを作ってみた。
ちなみにセンサーは、Aliexpress で 200 円くらいの、これを買った→MAX30102 Heart Rate Pulse Breakout / Blood Oxygen Sensor Module
調査
手元に M5 Stick-C は余っているので、とりあえず Arduino のライブラリがあればそれっぽくなりそうとのことで調べてみると、京セラコミュニケーションシステムズのサイトで、作成例を紹介している記事があった。→M5Stack Basicで通信機能付き心拍・血中酸素モニタを作る
上記の記事は実際には MAX30102 を接続しているようなので、ほぼいけそう。元ネタはMAXIMのサイトかSparkfunのExampleかな。測定原理とかは、このへん →GUIDELINES FOR SPO2 MEASUREMENT USING THE MAXIM® MAX32664 SENSOR HUB
モジュールとは、I2C 通信でいけそうなので、Grove端子からの接続で OK そう。接続は、このケーブルを使おう→ GROVE – 4ピン-ジャンパメスケーブル (5本セット)
モジュールの電源や信号レベルはどうなっているか、このモジュールの回路図はないか見てみると、回路図付きで以下のサイトがひっかかった。
Pulse Oximeter MAX30100/MAX30102 – how to fix wrong board
タイトルからしてどきっとするが、一応電源は M5 系の Grove 5 V で問題なさそう。ただ、I2C の信号線が 1.8 V でプルアップされているようで、記事にもあるように 3.3 V 系 だと不安定だと何とかなるんじゃないかな(事実なんとかなった)、とそのまま接続する事に。それより気になったのは、1.8 V を生成しているはずのレギュレータが、2.8V 品が乗っているものがあるとかいう指摘。テスタで測ったところ問題なく 1.8 V が出力されていたので、これは杞憂に終わった。
接続、コーディング、測定
とりあえず接続はこんな感じで、G32 -> SDA, G33 -> SCL。ソフト的にはI2C周りはデフォルト設定でいけそう。
VSCODE 上 の PlatformIO で、同じようにライブラリを導入。ソースはほぼそのままで、とりあえず適当に画面周りだけ修正。IRと赤色それぞれの測定値を、50個ためるバッファがあって、半分の25個更新しては、ライブラリの関数を呼び出す構造。関数内では、波形のピーク検出に基づいて脈拍の計算と、両センサーの変化率の比から酸素濃度の計算、という感じ。センサーに指を置いて測定すると以下のように表示される。指汚い。
なんか指を押し付ける力で結構ばらつくなぁ、と思ってたんだけど、本家の動画見てもそんなもん?という感じ。
これだと測定中不安になるので、serial plotter用に片方のセンサー値だけ出力するように変更して、リアルタイムにグラフをみながらやろう、という事に。
グラフ見ながらやれば、どうやれば安定できるか、コツがつかめるような気がする。
電源入れて測定開始までは LED 光らないようにしたりして、最終的なものは、以下においた。
https://github.com/Keitark/pulseoxi.git
さいごに
やはり、ここ最近作っている人が多いかんじ。今回はライブラリはそのまま使ってみたが、いろいろ手を加えたり、自分で計算している人もいるようなので、そのうち調べてみる。
参考になるサイト
その後、いろいろなサイトを見てみると、いろいろ情報のまとまっているサイトがあったので、紹介。
脈拍センサーMAX30102を試す(1) Githubのレポジトリの不具合などの情報もあり、2017年なのでもう直っているのかも。
[ESP8266][MAX30102] MAX30102でパルスオキシメーターを作る Datasheetなどにある計算原理などについての確認など、Sparkfunのモジュールの不具合情報みたいなものもあり。