❤️

M5Stack Unit Heartを使おう

に公開

はじめに

この記事では、M5Stack Unit Heart(血中酸素濃度・心拍センサー)の使い方について解説します。🫀

健康管理やヘルスケアIoTデバイスの開発に興味がある方にとって、手軽に心拍数や血中酸素濃度を測定できるこのユニットは非常に魅力的です。

M5Stack Unit Heartとは?

Unit Heartは、M5Stackシリーズ向けの血中酸素濃度・心拍センサーユニットです。💓

概要

Unit Heartは、MAX30100チップを搭載した完全なパルスオキシメーター(SpO2)および心拍センサーシステムソリューションです。非侵襲型(体を傷つけない)の血中酸素濃度・心拍センサーで、2つの赤外線LEDとフォトディテクター(光検出器)を内蔵しています。

検出原理 🔬

赤外線LEDを使用して指を照射し、酸素を運搬している赤血球と運搬していない赤血球の比率を検出することで、血中酸素濃度を算出します。これは医療機器でも使われている光電式容積脈波記録法(PPG)と同じ原理です。

主な特徴 ✨

項目 内容
🔌 通信プロトコル I2C(アドレス: 0x57)
📏 サイズ 32.0 x 24.0 x 8.0mm
⚖️ 重量 約4.9g
🧱 互換性 LEGO互換ホール x 2
🛠️ 開発プラットフォーム Arduino, UIFlow

機能一覧 📋

  • ✅ プログラマブルなサンプリングレートとLED電流(省電力設計)
  • ✅ 超低シャットダウン電流(typ. 0.7µA)
  • ✅ 高い測定パフォーマンス
  • ✅ 高サンプリングレート
  • ✅ 内蔵温度センサーによるキャリブレーション
  • ✅ 高速データ出力
  • ✅ 血中酸素濃度(SpO2)検出
  • ✅ 心拍数検出

パッケージ内容 📦

  • Unit Heart本体 x 1
  • HY2.0-4P Groveケーブル(20cm)x 1

開発環境のセットアップ 🔧

必要なもの

  • 🖥️ M5Stack Core(Core2, CoreS3 など)
  • ❤️ Unit Heart
  • 🔌 Grove ケーブル(付属品)
  • 💻 Arduino IDE または PlatformIO

Arduino IDE でのセットアップ

1. ボードマネージャーの設定

Arduino IDE のボードマネージャーに M5Stack のボード URL を追加します。

ファイル → 環境設定 → 追加のボードマネージャーURL に以下を追加:

https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json

2. ライブラリのインストール

以下のライブラリをインストールします:

  • M5Stack または M5Unified(使用するCoreに応じて)
  • MAX30100lib(Arduino Library Manager から)
スケッチ → ライブラリをインクルード → ライブラリを管理
→ 「MAX30100」で検索 → インストール

ピンマップと接続 🔗

Unit Heart 側(HY2.0-4P コネクタ)

PIN 機能
GND グラウンド
5V 電源
I2C_SDA I2Cデータ
I2C_SCL I2Cクロック

CoreS3 との接続例 🎯

Unit Heart を M5Stack CoreS3 に Grove ケーブルで接続します。

CoreS3 では PORT.A、PORT.B、PORT.C のいずれにも接続可能 です:

ポート GND 電源 SDA SCL 備考
PORT.A GND 5V G2 G1 標準I2Cポート
PORT.B GND 5V G9 G8 GPIO / UART
PORT.C GND 5V G17 G18 GPIO / UART

他の機種をお使いの場合 📋

Unit Heart は多くの M5Stack デバイスに対応しています:

  • 🔴 Core シリーズ: CoreS3, CoreS3-SE, Core2 v1.1, Tough, Basic v2.7, Fire v2.7, Core2 For AWS
  • 🟢 Atom シリーズ: AtomS3, AtomS3-Lite, AtomS3R, Atom-Lite, Atom-Matrix, Atom Echo など
  • 🔵 その他: M5GO IoT Kit v2.7, Tab5/Tab5 Kit, CoreMP135 など

お使いの機種のピン配置を確認するには:

  1. M5Stack公式ドキュメント にアクセス
  2. ページ下部の 「Compatible」セクション までスクロール
  3. 右側の プルダウンメニュー からお使いの機種を選択
  4. 選択した機種の PORT.A / PORT.B / PORT.C のピン配置が表示されます

ピンマップとコードの関係 🔌💻

Unit Heart を CoreS3 で使用する場合、接続したポートに応じて I2C の初期化でピン番号を指定します:

// CoreS3 のポート別ピン設定
Wire.begin(2, 1);    // PORT.A: SDA=G2,  SCL=G1
Wire.begin(9, 8);    // PORT.B: SDA=G9,  SCL=G8
Wire.begin(17, 18);  // PORT.C: SDA=G17, SCL=G18

M5Unified を使用する場合の例(PORT.A 使用時):

auto cfg = M5.config();
M5.begin(cfg);

// 接続したポートに応じてピン番号を変更
Wire.begin(2, 1);  // PORT.A の場合

使用方法 🖐️

測定方法はとてもシンプルです:

  1. プログラムを実行する
  2. 検出エリア(センサー部分)に指を置く
  3. 数秒待つと心拍数と血中酸素濃度が取得できます

サンプルコード 💻

サンプルコード集 📂

Unit Heart を使った様々なサンプルコードを GitHub で公開しています。段階的に学習できるよう、シンプルなものから応用的なものまで用意しています。
Unit Nekoとの連携も楽しめるサンプルコードになっています。

Unit Nekoに関しては以下を参照してください。

https://qiita.com/tomokusaba/items/a90d4273f8e8d74781d0

🔗 サンプルコード一覧(GitHub)

サンプル 概要
📄 sample1.ino 基本サンプル
📄 sample2.ino 応用サンプル
📄 sample3.ino 機能拡張
📄 sample4.ino 機能拡張
📄 sample5.ino 機能拡張
📄 sample6.ino 機能拡張
📄 sample7.ino 心拍モニタリング
📄 sample8.ino 高度な機能

詳細は GitHub リポジトリの各ファイルをご確認ください。


基本的な心拍・SpO2 測定(CoreS3 対応)

以下のコードは CoreS3 で動作するように最適化されています。ピンマップで説明した G2(SDA)・G1(SCL) の設定が含まれています。

#include <M5Unified.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000

// CoreS3 の PORT.A ピン定義
#define I2C_SDA 2
#define I2C_SCL 1

PulseOximeter pox;
uint32_t tsLastReport = 0;

// コールバック関数:心拍検出時に呼ばれる
void onBeatDetected() {
    Serial.println("Beat!");
}

void setup() {
    M5.begin();
    M5.Display.setTextSize(2);
    M5.Display.println("Initializing...");
    
    Serial.begin(115200);
    
    // CoreS3 用 I2C ピン設定
    Wire.begin(I2C_SDA, I2C_SCL);
    
    // MAX30100の初期化
    if (!pox.begin()) {
        Serial.println("FAILED");
        M5.Display.println("FAILED");
        for(;;);
    } else {
        Serial.println("SUCCESS");
        M5.Display.println("SUCCESS");
    }
    
    // LED電流の設定(省電力 or 高精度)
    pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
    
    // 心拍検出コールバックの登録
    pox.setOnBeatDetectedCallback(onBeatDetected);
    
    M5.Display.clear();
}

void loop() {
    // センサーの更新(頻繁に呼び出す必要あり)
    pox.update();
    
    // 1秒ごとに結果を表示
    if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
        M5.Display.setCursor(0, 0);
        M5.Display.printf("Heart Rate: %.1f bpm\n", pox.getHeartRate());
        M5.Display.printf("SpO2: %.1f %%\n", pox.getSpO2());
        
        Serial.print("Heart rate:");
        Serial.print(pox.getHeartRate());
        Serial.print(" bpm / SpO2:");
        Serial.print(pox.getSpO2());
        Serial.println(" %");
        
        tsLastReport = millis();
    }
}

コードの解説 📖

重要なポイント

  1. pox.update() を頻繁に呼び出す 🔄

    • loop() 内で毎回呼び出す必要があります
    • delay() を使うと測定精度が落ちるので注意!
  2. LED電流の設定 💡

    • setIRLedCurrent() で赤外線LEDの電流を調整
    • 値を大きくすると精度↑、消費電力↑
    • 利用可能な値:
      MAX30100_LED_CURR_0MA      // 0mA(オフ)
      MAX30100_LED_CURR_4_4MA    // 4.4mA
      MAX30100_LED_CURR_7_6MA    // 7.6mA(推奨)
      MAX30100_LED_CURR_11MA     // 11mA
      MAX30100_LED_CURR_14_2MA   // 14.2mA
      MAX30100_LED_CURR_17_4MA   // 17.4mA
      MAX30100_LED_CURR_20_8MA   // 20.8mA
      MAX30100_LED_CURR_24MA     // 24mA
      MAX30100_LED_CURR_27_1MA   // 27.1mA
      MAX30100_LED_CURR_30_6MA   // 30.6mA
      MAX30100_LED_CURR_33_8MA   // 33.8mA
      MAX30100_LED_CURR_37MA     // 37mA
      MAX30100_LED_CURR_40_2MA   // 40.2mA
      MAX30100_LED_CURR_43_6MA   // 43.6mA
      MAX30100_LED_CURR_46_8MA   // 46.8mA
      MAX30100_LED_CURR_50MA     // 50mA(最大)
      
  3. コールバック関数 🎯

    • setOnBeatDetectedCallback() で心拍検出時の処理を登録
    • LEDを光らせたり、音を鳴らしたりできます

トラブルシューティング 🚨

よくある問題と解決策

症状 原因 解決策
🔴 初期化に失敗する 接続不良 or I2Cアドレス PORT.A に接続されているか確認。Wire.begin() の引数を確認(ピンマップと接続参照)
📉 心拍数が0のまま 指の置き方が悪い センサーに指を軽く乗せる。強く押しすぎない
📊 値が不安定 pox.update() の呼び出し頻度 delay() を減らし、頻繁に update() を呼ぶ
🔢 SpO2が常に0 安定するまで時間がかかる 10-15秒ほど待つ。指を動かさない

応用例 🎯

1. ヘルスケアダッシュボード 📱

取得したデータを Wi-Fi 経由でクラウドに送信し、ダッシュボードで可視化:

// Azure IoT Hub や AWS IoT Core への送信例
String payload = "{\"heartRate\":" + String(pox.getHeartRate()) + 
                 ",\"spo2\":" + String(pox.getSpO2()) + "}";
// MQTT で送信...

2. 異常検知アラート 🚑

心拍数が閾値を超えた場合にアラートを出す:

float heartRate = pox.getHeartRate();
if (heartRate > 100 || heartRate < 50) {
    // アラート処理
    M5.Speaker.tone(1000, 500);  // ビープ音
}

3. 運動強度の判定 🏃

心拍数から運動強度を判定:

float heartRate = pox.getHeartRate();
String intensity;

if (heartRate < 100) {
    intensity = "Low (脂肪燃焼ゾーン)";
} else if (heartRate < 140) {
    intensity = "Medium (有酸素ゾーン)";
} else {
    intensity = "High (無酸素ゾーン)";
}

まとめ 🎉

M5Stack Unit Heart を使えば、手軽に心拍数と血中酸素濃度を測定できます。

  • ✅ I2C接続で簡単セットアップ
  • ✅ MAX30100チップによる高精度測定
  • ✅ Arduino / UIFlow 両対応
  • ✅ ヘルスケアIoTプロジェクトに最適

ぜひ皆さんも Unit Heart を使って、健康管理デバイスを作ってみてください!💪❤️

関連リソース 📚

GitHubで編集を提案

Discussion