M5Stick CとHeart Rate UNITでSpO2を測ってみる -3-

https://kinneko.booth.pm/items/1963720

 ----------------------------------------------------------------------------------------

 パルスオキシメーターの品不足の原因

 市場からパルスオキシメーターが消えているのは、TVなんかで報道されていたりするからなのね。知らなかったわ。twitterをさかのぼってみると、3月1日の報道から徐々に盛り上がっていたみたい。そして、最近また別の報道で再燃している感じ。

自宅待機中に急変、どうすれば…突然重症化の恐怖
https://news.tv-asahi.co.jp/news_society/articles/000182476.html

コロナ肺炎悪化を発見する血中酸素濃度測定「パルスオキシメーター」通販や薬局で買える!: J-CAST テレビウオッチ【全文表示】
https://www.j-cast.com/tv/2020/04/24384909.html?p=all

 ここ数日で、ホテル缶詰めの軽症患者用に収容ホテルに採用されていたりする報道もある。自宅待機患者の明暗を分ける決め手としての報道も目立つ。

長女を預けず自宅療養の赤江アナ「預けられるところがあるなら…」と医療関係者:芸能・社会:中日スポーツ(CHUNICHI Web)
https://www.chunichi.co.jp/chuspo/article/entertainment/news/CK2020042602100086.html

 メーカーや販売業者の反応

 メーカーのWebサイトでは、医者の管理のもとに使うもので、素人に使える機械じゃないから、患者が買えるようにしてくれというメッセージが出ている。

パルスオキシメータ | コニカミノルタ
https://www.konicaminolta.jp/healthcare/products/pulseoximeters/index.html

 国産の機器は結構高いのに、皆さん買ったりするのだなぁ。ちょっとびっくり。

【5月連休明けから順次発送】 パルスオキシメーター パルスオキシメータ 酸素濃度計 脈拍 健康 在宅 看護 SpO2 酸素飽和度 血中酸素 カバー ストラップ 電池付 :4580609090016:富士コンテック公式ストア - 通販 - Yahoo!ショッピング
https://store.shopping.yahoo.co.jp/y-fujikomtech/4580609090016.html

 コメント欄でも、よく売れていて品薄であることがわかる。

 こちらのサイトでも同様のようだ。

パルスオキシメーター徹底ガイド|看護師通販NURSERY(ナースリー)
https://www.nursery.co.jp/topics/oximeter/

 SpO2の適切な値

 SpO2値は、一般的には安静時には96-98%(97-100%と書かれているものもある)で、常時90%以上を維持する必要があるそうな。日本呼吸器学会「呼吸器感染症に関するガイドライン2000」によると、90%以下では重症な呼吸不全の状態で、80%あたりでは悪化した肺炎なのだそうだ。とりあえず、M5Stick Cのパルスオキシメータでも、正常時の値は出ている感じだ。

 指で測る場合は、血流のヘモグロビン量を見ているので、指先が冷たくて血流がない場合はうまく測定できないそうだ。M5Stick Cのパルスオキシメータでは、透過での測定はしていないので、マニキュアをしていても関係はなさそうだ。透過光に影響を与えないように、指が汚れていないことも条件になっている。外光が誤差の原因になることもあるそうだ。

 M5Stick Cのパルスオキシメータでは、センサに指を強く押し当ててしまうと、指の血流が阻害されて白くなってしまい、正常に測定ができない。指は乗せるくらいの気持ちで十分だ。

 心拍に同期してLEDを点灯する

 さて、M5Stick Cのパルスオキシメータ、なんか心拍当てにならない気がしたので、心拍センスするとLEDが光るようにしてみた。

 変更はボールドの部分だけ。

 /*

 Arduino-MAX30100 oximetry / heart rate integrated sensor library

 Copyright (C) 2016 OXullo Intersecans x@brainrapers.org

 This program is free software: you can redistribute it and/or modify

 it under the terms of the GNU General Public License as published by

 the Free Software Foundation, either version 3 of the License, or

 (at your option) any later version.

 This program is distributed in the hope that it will be useful,

 but WITHOUT ANY WARRANTY; without even the implied warranty of

 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License

 along with this program. If not, see http://www.gnu.org/licenses/.

 */

#include <M5StickC.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS     1000
// PulseOximeter is the higher level interface to the sensor
// it offers:
//  * beat detection reporting
//  * heart rate calculation
//  * SpO2 (oxidation level) calculation
PulseOximeter pox;

 uint32_t tsLastReport = 0;

// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
Serial.println("Beat!");
digitalWrite(GPIO_NUM_10, LOW);
delay(1);
digitalWrite(GPIO_NUM_10, HIGH);
}
void setup()
{
M5.begin();
pinMode(GPIO_NUM_10, OUTPUT);
digitalWrite(GPIO_NUM_10, HIGH);
M5.Axp.ScreenBreath(8);
M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.print("MAX30100");
M5.Lcd.setCursor(0, 40);
Serial.begin(115200);
Serial.print("Initializing pulse oximeter..");
// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
} else {
Serial.println("SUCCESS");
}
// The default current for the IR LED is 50mA and it could be changed
//   by uncommenting the following line. Check MAX30100_Registers.h for all the
//   available options.
// pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);
}
void loop()
{
// Make sure to call update as fast as possible
pox.update();
// Asynchronously dump heart rate and oxidation levels to the serial
// For both, a value of 0 means "invalid"
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("Heart rate:");
Serial.print(pox.getHeartRate());
Serial.print("bpm / SpO2:");
Serial.print(pox.getSpO2());
Serial.println("%");
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(3, 10, 1);
M5.Lcd.println("SpO2 checker");
M5.Lcd.print(" SpO2: ");
M5.Lcd.print(pox.getSpO2());
M5.Lcd.println(" %");
M5.Lcd.println(" Heart rate:");
M5.Lcd.print("   ");
M5.Lcd.print(pox.getHeartRate());
M5.Lcd.println(" bpm");
tsLastReport = millis();
}
}

 LEDのピンのLOW/HIGHの切り替えは、delayをしないと光らない。あまり長く処理をブロックしても、センサの動きに問題が出るかもしれないのと、点灯時間が長いとLEDが眩しいので、delayは最低限の1/1000秒にした。LOWで点灯するのがキモだ。

 指で脈を取りながら比べてみると、タイミングは0.1sec遅れくらいで正しく取れている気がする。心拍の値が大きいような気がするのは、間隔から分単位の値を推測する関数のせいかな? この関数は、1つ前からの経過時間だけ見て推測しているような気がする。


オリジナル投稿:
M5Stick CとHeart Rate UNITでSpO2を測ってみる -3-|kinneko|pixivFANBOX
https://kinneko.fanbox.cc/posts/994755