ヘルスチェックデバイス:脈拍数+酸素飽和度SpO2+体温測定(FreeRTOS+ESP32)

ESP32 Arduino WiFiライブラリ

データパブリッシュ時のみWiFi+MQTT接続するようにWifi接続をON/OFF制御します。

Station Mode起動

WiFi.begin(STA_SSID, STA_PASS);

WiFi停止

WiFi.mode(WIFI_OFF);

noInterrupts()

Arduinoリファレンス
https://www.arduino.cc/reference/en/language/functions/interrupts/nointerrupts/

ESP32 #define noINterrupts()

FreeRTOS vTaskSuspend() タスクの一時停止

測定中、指をセンサから離すなどイレギュラーな動作を検知した際に動作中のタスクや次のタスクを一時停止。

vTaskSuspend()

void vAFunction( void )
 {
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to suspend the created task.
     vTaskSuspend( xHandle );

     // ...

     // The created task will not run during this period, unless
     // another task calls vTaskResume( xHandle ).

     //...

     // Suspend ourselves.
     vTaskSuspend( NULL );

     // We cannot get here unless another task calls vTaskResume
     // with our handle as the parameter.
 }

アップデート

  • LEDをWS2812Bへ変更したことに伴うコード変更・追加
  • FreeRTOSにおけるタスクハンドラーの指定と読取りエラー発生時のタスクサスペンド追加
  • OLEDリフレッシュレート変更・180度反転表示
    など

登録ID設定

1台のデバイスで登録ユーザを10人に設定。IDの切替はスイッチ押下による。
ID毎のデータ出力は以下の通り。

{"id1":{"hr":69,"spo2":100,"temp":35.81}}
{"id2":{"hr":72,"spo2":99,"temp":35.89}}
{"id3":{"hr":74,"spo2":97,"temp":35.85}}
{"id4":{"hr":72,"spo2":99,"temp":35.91}}
{"id5":{"hr":74,"spo2":98,"temp":36.05}}
{"id6":{"hr":0,"spo2":0,"temp":35.75}}
...
...

ホームアシスタントによるモニタ

以下Home Assistantにヘルスチェックデバイスのタブを追加し、ユーザID毎に各データを表示・遠隔モニタ、グラフ表示対応(1台のデバイスでマルチユーザ管理)。

注) メンバーID:1以外のデータは、検証用のダミーデータをパブリッシュ。

追加機能

ESP32 Flash Memory – Store Permanent Data (Write and Read)

ユーザIDの不揮発メモリへの書込み

ESP32 Deep Sleep with Arduino IDE and Wake Up Sources

ディープスリープ

loop()関数について

スケッチ内のループ関数については、FreeRTOSのタスクの一部とみなされ、ある条件を設定することで vTaskDelete(NULL) により動作途中で除外可能。loop()はデフォルトでCPUコア1で動作するため、Semaphore, Mutexの取得に関係なく並列動作する。

アップデート

  • 1台のデバイスを複数のユーザ(10人:最大256人)で共有するためのユーザID設定
  • ボタン押下によるユーザ切換え・WiFi設定(APモード)・ユーザIDリセット機能追加
  • ボタン検知タスクを他のタスクから独立・並列処理
  • スリープ機能(60秒スリープ、ボタン押下で復帰)
  • 表示部にユーザID追加
  • その他デバックにより判明したバグ修正
    など

ID設定・スタート時

脈拍数測定時の動作

酸素飽和度測定時

酸素飽和度+脈拍数測定結果

体温測定結果

補足)パルスオキシメーター: MAX30102 センサの配置について

ユーザにより指の置き方は様々です。指先の接触面とセンサ表面がきちんと接触するよう配慮が必要です。(センサ部分をケース蓋切り欠き部からテーパをつけた状態で突き出す等)

ライブラリアップデートに伴う変更

platformio.ini

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps = 
	adafruit/Adafruit GFX Library@^1.10.10
	adafruit/Adafruit MQTT Library@^2.4.0
	bblanchon/ArduinoJson@^6.18.0
	adafruit/Adafruit MLX90614 Library@^2.1.3
	sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@^1.1.1
	adafruit/Adafruit BusIO@^1.7.5
	adafruit/Adafruit NeoPixel@^1.10.7
	adafruit/Adafruit SSD1306@^2.5.7
	mathertel/OneButton@^2.0.3
	khoih-prog/ESP_WifiManager@^1.12.1
lib_ignore = 
	WiFi101

src/main.cpp(変更箇所のみ)

  // Previous library "https://github.com/lorol/LITTLEFS" merged to the Arduino esp32 core v2
  #include <LittleFS.h>             // https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS
    
  FS* filesystem =      &LittleFS;
  #define FileFS        LittleFS
  #define FS_Name       "LittleFS"

VSCodeのソース管理でプロジェクトフォルダ内で以下Gitの設定を忘れないこと。

$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"