SJKのアイコン画像
SJK 2021年02月27日作成 (2021年02月28日更新)
製作品 製作品 閲覧数 6126
SJK 2021年02月27日作成 (2021年02月28日更新) 製作品 製作品 閲覧数 6126

M5StickC plusとNCIR hatでポータブル非接触体温計を作る

M5StickC plusとNCIR hatでポータブル非接触体温計を作る

概要

コロナ禍で毎日の検温が必須になった昨今、朝の忙しい時間帯に家族全員分迅速に体温を計測するために、半田付けなしですぐに温度測定ができる、NCIRハットとM5StickC-plusで非接触体温計を作ってみました。

使用したモジュール

  • M5StickC plus
    https://www.marutsu.co.jp/pc/i/2190748/
    M5StickC plus

  • 非接触温度センサ Hat(NCIR hat, MLX90614搭載)
    https://www.marutsu.co.jp/pc/i/1632335/
    NCIR hat
    (※現在、m5stack.comでもOut Of Stockとなっております。使用されているセンサーのMLX90614自体が品薄のようです)

  • 接続
    モジュールの接続はM5StickC plus上部ピンソケットにNCIR hatの8ピンを接続するだけです。

開発環境

開発環境は、サンプルスケッチもあるArduino IDEで行いました。サンプルスケッチを書き込んだらすぐに計測できたので、こりゃ簡単だと思ったのですが、計測するたびに値がばらつきすぎる。というわけで、主に計測開始の温度しきい値と積算でその辺をカバーしました。

実装したこと

  • 計測値31℃以下で待機モード(M5StickCの赤色LEDを点灯)
  • 100回温度計測を行いその平均を求める
  • 測定終了時にビープ音を鳴らす
  • 体温の他に、簡易のバッテリー残量表示
  • 複数人が連続使用することを考慮し、ディープスリープと"M5"ボタンでスリープから復帰

スケッチ

体温測定用スケッチ

#include <M5StickCPlus.h> #include <Wire.h> #include <Adafruit_MLX90614.h> Adafruit_MLX90614 mlx = Adafruit_MLX90614(); void setup() { M5.begin(); setCpuFrequencyMhz(10); //電池を持たせるために動作周波数を落とす Wire.begin(0, 26); M5.Beep.setBeep(4000, 500); // ビープ音設定(初期値, 4000Hz, 500msec) mlx.begin(); M5.Axp.ScreenBreath(10); // 画面の輝度を少し下げる M5.Lcd.setRotation(1); // 0縦正方向, 1左に画面, 2縦逆, 3右に画面 M5.Lcd.setTextSize(3); // 文字サイズを3にする M5.Lcd.fillScreen(BLACK); // 背景を黒にする // 温度データ取得 float temperature = mlx.readObjectTempC() + 0.0; float int_temperature = mlx.readAmbientTempC(); int lpcnt = 0 ; while (mlx.readObjectTempC() <= 31.0) //計測値が31℃以下の間は待機 { pinMode(GPIO_NUM_10, OUTPUT); // LED ON(GPIO_NUM_10 or M5_LED) digitalWrite(GPIO_NUM_10, LOW); delay(100); lpcnt += 1 ; if (lpcnt > 50) { ESP.restart(); } } //温度センサーの値を読み取る //センサーの値を100回読み取り平均化する float avetemp = 0; float sum = 0; float rEAD = 0; sum = 0; for (int i = 0; i < 100; i++) { rEAD = mlx.readObjectTempC(); sum = sum + rEAD; //delay(5); } avetemp = (sum / 100 ) + 3.8; //実際の体温との差を取った時、3.8℃ほど低く計測されたのでその補正 // LCD 体温表示 M5.Lcd.setCursor(3, 30, 4); M5.Lcd.print(avetemp,1); M5.Lcd.setTextSize(1); // 文字サイズを1にする M5.Lcd.print("o"); //℃の左肩の丸表記の方法が分からなかったのでoの文字サイズを小さくすることで対応 M5.Lcd.setTextSize(3); // 文字サイズを3にする M5.Lcd.println("C"); // バッテリー電圧 double vbat = M5.Axp.GetVbatData() * 1.1 / 1000; // バッテリー残量 // 簡易的に、線形で4.1Vで100%、3.0Vで0%とする int8_t bat_charge_p = int8_t((vbat - 3.0) / 1.1 * 100); if (bat_charge_p > 100) { bat_charge_p = 100; } else if (bat_charge_p < 0) { bat_charge_p = 0; } // LCDバッテリー残量表示 M5.Lcd.setTextSize(1); // 文字サイズを1にする M5.Lcd.setCursor(3, 100, 4); M5.Lcd.printf("Charge: %3d%%", bat_charge_p); // Beepによる計測完了の通知 //M5.Beep.update(); // tone関数で鳴らした音が指定時間経過していたら止める M5.Beep.tone(4000, 2000); delay(1000); M5.Beep.end(); // beepを止める delay(3 * 1000); M5.Axp.ScreenBreath(0); // 画面の輝度OFF WiFi.mode( WIFI_OFF ); sum = 0; rEAD = 0; avetemp = 0; // GPIO37(M5StickCのHOMEボタン)がLOWになったら起動 pinMode(GPIO_NUM_37, INPUT_PULLUP); esp_sleep_enable_ext0_wakeup(GPIO_NUM_37, LOW); // ディープスリープ esp_deep_sleep_start(); } void loop() { }

実際に使ってみて

しきい値と積算である程度測定値のばらつきは抑えられました。おでこで測るのでやや低めに出ます(そもそもNCIRハットに使われているMLX90614は医療用グレードではないようです)。使い方を覚えれば小学生低学年でも測れるので、朝の検温タイムは著しく短縮できました。
キャプションを入力できます

2
ログインしてコメントを投稿する