2020年12月7日月曜日

ド素人がM5StickCを用いたマルチ環境計を作ってみた 番外編:心拍・SpO2センサ

 Part1で番外にする~とか書いていた心拍・SpO2センサ編です。
 とはいっても、サンプルコードを探してきてちょっといじった(かどうかも不確か)だけのものです。だから番外にしてるんだけどね。
 
 さて、今回採用したセンサはM5StickC…というかM5Stack公式のセンサキット、UNIT HEARTです。MAX30100センサを採用し、赤外線LEDと光センサを用いて赤血球中の酸素濃度を測定する…らしいです。スイッチサイエンスさんの説明書きまんまです。

UNIT HEART 公式より

 ただ、今回も一筋縄では行かず。なんか調べたコードが生データの表示しかしないやつだったりしたのです。最終的にはなんとかなった(と思う)けど。
 (あと、一枚も写真撮ってなかったからこの記事書きながら撮る羽目になった)

 とりあえず動作中の写真をば。
 HRはHeartRate、つまり心拍数を表し、SpO2は血中酸素濃度を表しています。
 心拍数の正常値は60前後で、SpO2の正常値はなんと97%以上だそうです。もし95%以下なら何かしらの疾患、特に呼吸器系の疾患が疑われるようです。90%を下回るような方は酸素吸入が必要なレベルだそうです。このご時世、ある程度の頻度で測っておくといいかもしれませんね。目安にはなりますから。
動作中(環境計のGroveコネクタを付け替えただけ)

赤色LEDが発光してます
指をのせたところです

 指をのせてから10秒ほど経つと、ある程度正確な値が表示されます。ただし、ご覧の通り医療機関等で使用されているようなパルスオキシメーターとは似ても似つかないため、少しでも指がずれたり、当て方が悪かったりするとおかしな値が帰ってきます。ガチな人は指を固定するためのエンクロージャーを作ったりしているようです。

 今回のコードです…が、ほぼほぼ「M5Stack Basicで通信機能付き心拍・血中酸素モニタを作る(MAX30100) - Qiita」さんのコードまんまです。M5Stack用になっているところをM5StickC用に直したり、一部の表示を削って単純に文字情報のみを表示するようにカスタマイズしただけのものになります。
 一応書いておきますが、Arduino IDEのライブラリの管理からMAX30100_PulseOximeter.hというライブラリをインストールしないと動きません。
 また、UNIT HEARTを接続せずにM5StickCを起動した場合にはFAILEDと表示されるようになってます。
 それ以外はちんぷんかんぷんなコードなので、今回は説明なしです。ついてる説明はもともとあったものです。私はほぼほぼ何をやっているのかわかっていません…

MAX30100_SIMPLE_HRandPulseOximeter
#include <M5StickC.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS     1000

PulseOximeter pox;
uint8_t Heart_rate = 0;
uint8_t Spo2 = 0;
uint32_t tsLastReport = 0;

// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
  printHRandSPO2(true);
}

void setup()
{
  Serial.begin(115200); // to PC via USB

  M5.begin();
  M5.Lcd.setRotation(3);

  // Initialize sensor
  if (!pox.begin()) {
    M5.Lcd.println("FAILED");
    for(;;);
   } else {
    M5.Lcd.println("SUCCESS");
  }

  //LED Configuration
  pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  //Register a callback for the beat detection
  pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop()
{
  M5.update();  //update button state
  pox.update(); //update pulse oximeter

  if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
    Heart_rate = (int)pox.getHeartRate();
    Spo2 = pox.getSpO2();
    printHRandSPO2(false);
    tsLastReport = millis();
  }
}

void printHRandSPO2(bool beat)
{
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0,20,4);
  M5.Lcd.print("HR:   "); M5.Lcd.println(Heart_rate);
  M5.Lcd.print("SpO2: "); M5.Lcd.println(Spo2);  
}
多分これいらないコード消しきれてないかもな…

~巻末の参考資料~

0 件のコメント:

コメントを投稿