• マイページ
  • カート 0
    0 0円
  • お問合せ
M5Stack5でつくる熱中症モニタ

[企画・制作] ZEPエンジニアリング

M5Stack×温湿度センサで作る「熱中症モニタ」(後編)

  前編では、温湿度センサの値から暑さ指数と不快指数を計算し、M5StackのLCD画面に熱中症の危険度をイラスト表示するガジェットを製作しました。M5Stackの大きな特徴のひとつとしてWi-Fiを介してインターネットに接続できる点が挙げられます。
 今回の後編では、温湿度や気圧、暑さ指数、不快指数を既存のクラウドサービス(AmbientData Inc.社の IoTクラウドサービス「Ambient」)にアップロードし、蓄積・可視化を行います。これにより、それぞれのデータの時間的変化をスマートフォンやPCで見ることができるようになります。就寝中の各データの変化や遠くに住む家族の住環境を把握したりと応用性が広がります。 


暑さ指数計とAmbient スマートフォン、PCでデータを可視化 
暑さ指数計とAmbient スマホ、PCでデータを可視化


対象機種はM5Stack Coreシリーズ(BASIC, FIRE等)です。Core2でも同様に動作します。 

M5Stack BASIC
M5Stack Basic V2.6
【M5STACK-K001-V26】
M5Stack FIRE IoT開発キット(PSRAM)V2.6
M5Stack FIRE IoT開発キット(PSRAM)V2.6
【M5STACK-K007-V26】
M5Stack Core2 IoT開発キット
M5Stack Core2 IoT開発キット
【M5STACK-K010】


温湿度気圧センサについては、温湿度気圧センサユニットVer.3(ENV III)を用いました。 

ENV.III
M5Stack用温湿度気圧センサユニット
Ver.3(ENV III)
【M5STACK-U001-C】

IoTクラウドサービス「Ambient」

 Ambientは、IoT機器データから送信されるデータを受信、蓄積、可視化することに特化した、AmbientData Inc.社が提供するフリーミアムサービスです。無料で8チャンネル(8台のIoT機器等)までデータを送信することができます。仕様は以下のとおりです。(AmbientData Inc. Webページより引用)

 ・チャネル数:1ユーザあたり8チャネルまで
 ・データ種類:1チャネルあたり8種類まで
 ・送信間隔:チャネルごとに最小5秒間隔
 ・データ件数:1チャネルあたり1日3,000件(データ8種の場合、約230秒(3分50秒)事に送信可能)
 ・チャート数:1チャネルあたり8個
 ・データ保存期間:1年


 Ambientを利用するためには、次の準備が必要です。それぞれのページに従って準備してください。

 1. ユーザ登録 ⇒ ユーザ登録ページ
 2. チャネルを作る ⇒ ログイン後、チャネル一覧で「チャンネルを作る」をクリックしチャンネルを作成する
 3. ArduinoIDE用ライブラリのインストール ⇒ 本記事の「(1)開発環境を構築」を参照


 ※詳細については、AmbientData Inc.社のページをご参照ください。

熱中症モニタ(暑さ指数計:クラウド送信機能付き)の仕様と制御プログラム

 仕様は、以下のとおりです。

 【前編と同様の仕様】
  ・約1秒毎に温湿度を測定し、暑さ指数と不快指数を表示
  ・暑さ指数から「危険、厳重警戒」などの注意をイラストでも表示
  ・「警戒」レベル(暑さ指数25℃)以上の場合ビープを鳴らす ※前編から一段階下げています。
  ・温湿度気圧センサユニットVer.3(ENV III)は気圧の測定も可能なため併せて表示

 【今回追加した仕様】
  ・現在時刻を表示
  ・温湿度気圧データを5分毎にAmbientサービスに送信

 時刻は、NICT:国立研究開発法人情報通信研究機構の公開NTPサーバから取得しています。NTPについて詳しく知りたい方は、関連記事(ニキシー管風!M5Stackで作る高精度Wi-Fiクロック)も併せてご参照ください。 

(1)開発環境構築

 M5StackのArduino IDE開発環境を用います。その構築方法については、別記事「いろいろなマイコンボードに使えるArduino IDE。環境構築メモ」の「M5StackをArduino IDEで使う」の章を参考にしてください。
 Ambientのサービスを利用するために追加のI/Oライブラリ「Ambient ESP32 ESP8266 lib by Ambient Data」をインストールしてください。またM5Stack CORE2を使用する場合には、「M5Core2 by M5Stack」ライブラリも併せてインストールしてください。

(2)制御プログラム

 プログラム本体とimage.hは、こちらよりダウンロードしてください。 

制御プログラムリスト

  1. //暑さ指数計 クラウド版 Copyright (c) 2022- @logic_star
  2. //#define CORE2 //CORE2を使用する場合は有効化要
  3. #ifdef CORE2
  4.   #include <M5Core2.h>
  5. #else
  6.   #include <M5Stack.h>
  7. #endif
  8. #include "image.h"
  9. #include "UNIT_ENV.h" //ENV IIIライブラリ
  10. SHT3X sht30; //温湿度センサ
  11. QMP6988 qmp6988; //気圧センサ
  12. float tmp = 0.0; //温度
  13. float hum = 0.0; //湿度
  14. float pressure = 0.0; //気圧
  15. float WBGT = 0.0; //暑さ指数
  16. float THI = 0.0; //不快指数
  17. // Wi-Fi関連設定
  18. #include <WiFi.h>
  19. const char* ssid = "SSID"; //Wi-Fi APのSSIDをセットする
  20. const char* password = "PASSWORD"; //Wi-Fi APのパスワードをセットする
  21. // NTP関連設定
  22. #include <time.h>
  23. struct tm timeinfo;
  24. uint8_t secLastReport = 0;
  25. const char* ntpServer = "ntp.nict.jp"; //NTP Server
  26. const long gmtOffset_sec = 9 * 3600;
  27. const int daylightOffset_sec = 0;
  28. const char* week[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  29. int ntp() {
  30. uint16_t wifi_retry_cnt;
  31.   //connect to WiFi
  32.   M5.Lcd.setTextFont(4);
  33.   M5.Lcd.setTextSize(1);
  34.   M5.Lcd.setCursor(0, 0);
  35.   M5.Lcd.printf("Connecting to WiFi AP\n");
  36.   WiFi.begin(ssid, password); //Wi-Fiに接続する
  37.   wifi_retry_cnt = 15;
  38.   while (WiFi.status() != WL_CONNECTED) { //接続待ち 0.5秒×15回でタイムアウト
  39.     delay(500);
  40.     M5.Lcd.printf(".");
  41.     if(--wifi_retry_cnt == 0) {
  42.       WiFi.disconnect(true);
  43.       WiFi.mode(WIFI_OFF);
  44.       M5.Lcd.printf("\nConnection error.");
  45.       return(false);
  46.     }
  47.   }
  48.   M5.Lcd.printf("\nCONNECTED\n"); //接続完了
  49.   configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); //NTPによる時刻取得
  50.   if (!getLocalTime(&timeinfo)) {
  51.     M5.Lcd.printf("\nFailed to obtain time"); //取得失敗した場合のメッセージ
  52.     return (false);
  53.   }
  54.   WiFi.disconnect(true); //時刻取得に成功したらWi-Fi切断
  55.   WiFi.mode(WIFI_OFF);
  56.   return (true);
  57. }
  58. // Ambient関連設定
  59. #include <Ambient.h>
  60. Ambient ambient;
  61. WiFiClient client;
  62. uint16_t channelId = 99999; //チャネルIDを設定
  63. const char* writeKey = "XXXXXXXXXXXXXXXX"; //ライトキーを設定
  64. int SendToCloud() { //Ambientサービスにデータ送信
  65. uint16_t wifi_retry_cnt;
  66.   //connect to WiFi
  67.   Serial.printf("Connecting to %s ", ssid);
  68.   wifi_retry_cnt = 15;
  69.   WiFi.begin(ssid, password); //Wi-Fiに接続する
  70.   while (WiFi.status() != WL_CONNECTED) { //接続待ち 0.5秒×15回でタイムアウト
  71.     delay(500);
  72.     Serial.print(".");
  73.     if(--wifi_retry_cnt == 0) {
  74.       WiFi.disconnect(true);
  75.       WiFi.mode(WIFI_OFF);
  76.       return(false);
  77.     }
  78.   }
  79.   Serial.println("CONNECTED"); //接続完了
  80.   ambient.begin(channelId, writeKey, &client); //Ambientサービスに接続
  81.   ambient.set(1, tmp); //温度データセット
  82.   ambient.set(2, hum); //湿度データセット
  83.   ambient.set(3, WBGT); //暑さ指数データセット
  84.   ambient.set(4, THI); //不快指数データセット
  85.   ambient.set(5, pressure); //気圧データセット
  86.   ambient.send(); //データ一括送信
  87.   delay(500); //送信完了待ちディレイ
  88.   WiFi.disconnect(true); //送信完了したらWi-Fi切断
  89.   WiFi.mode(WIFI_OFF);
  90.   return (true);
  91. }
  92. void setup() {
  93.   M5.begin(true, false, true, true);
  94.   qmp6988.init(); //気圧センサ初期化
  95.   M5.Lcd.fillScreen(TFT_WHITE); //M5Stackの画面初期化
  96.   M5.Lcd.setTextColor(TFT_BLACK, TFT_WHITE);
  97.   M5.Lcd.setTextDatum(TL_DATUM);
  98.   if(ntp() == false) while(1); //Wi?Fi接続、時刻取得に失敗したら処理停止
  99.   M5.Lcd.fillScreen(TFT_WHITE); //M5Stackの画面初期化
  100.   M5.Lcd.drawJpg(image_bg, sizeof image_bg, 0, 30); //背景の表示
  101. }
  102. void loop() {
  103.   getLocalTime(&timeinfo); //現在時刻取得
  104.   if (secLastReport != timeinfo.tm_sec) { //秒が更新されていたら以下処理を実行
  105.     secLastReport = timeinfo.tm_sec;
  106.     M5.Lcd.setCursor(0, 0); //現在時刻表示
  107.     M5.Lcd.printf("%02d/%02d/%02d(%s) %02d:%02d:%02d",
  108.       timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, week[timeinfo.tm_wday],
  109.       timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
  110.     delay(10);
  111.     pressure = qmp6988.calcPressure() / 100; //気圧を測定
  112.     if(sht30.get()==0){ //Obtain the data of shT30. //温湿度を測定
  113.       tmp = sht30.cTemp; //Store the temperature obtained from shT30.
  114.       hum = sht30.humidity; //Store the humidity obtained from the SHT30.
  115.     }
  116.     WBGT = (tmp*0.003289+0.01844)*hum+(0.6868*tmp-2.022); //暑さ指数の計算
  117.     THI = (tmp*0.81+hum*0.01*(tmp*0.99-14.3)+46.3); //不快指数の計算
  118.     if (((timeinfo.tm_min % 5) == 0) && (timeinfo.tm_sec == 0)) SendToCloud(); //5分毎にAmbientへデータ送信
  119.     if (WBGT >= 31) M5.Lcd.drawJpg(image4, sizeof image4, 180, 80); //暑さ指数に応じてイラスト表示
  120.     else if (WBGT >= 28) M5.Lcd.drawJpg(image3, sizeof image3, 180, 80);
  121.     else if (WBGT >= 25) M5.Lcd.drawJpg(image2, sizeof image2, 180, 80);
  122.     else if (WBGT >= 21) M5.Lcd.drawJpg(image1, sizeof image1, 180, 80);
  123.     else M5.Lcd.drawJpg(image0, sizeof image0, 180, 80);
  124.     if (WBGT >= 25){ //暑さ指数25℃以上のときにビープ音を鳴らす。CORE2を除く。
  125. #ifndef CORE2
  126.       M5.Speaker.beep();
  127.       delay(100);
  128.       M5.Speaker.mute();
  129. #endif
  130.     }
  131.     M5.Lcd.setTextFont(6); //暑さ指数の表示
  132.     M5.Lcd.setTextSize(1);
  133.     M5.Lcd.setCursor(128, 44);
  134.     M5.Lcd.printf("%2.1f", WBGT);
  135.     M5.Lcd.setCursor(128, 100); //不快指数の表示
  136.     M5.Lcd.printf("%2.0f", THI);
  137.     M5.Lcd.setTextFont(4); //温度の表示
  138.     M5.Lcd.setTextSize(1);
  139.     M5.Lcd.setCursor(60, 153);
  140.     M5.Lcd.printf("%2.1f 'C", tmp);
  141.     M5.Lcd.setCursor(60, 183); //湿度の表示
  142.     M5.Lcd.printf("%2.1f %%", hum);
  143.     M5.Lcd.setCursor(60, 213); //気圧の表示
  144.     M5.Lcd.printf("%4.1fhPa", pressure);
  145.   }
  146.   delay(100); //100mSウェイト
  147. }
  • 2行目 CORE2を使用する場合は「//」を削除して、CORE2定義を有効化してください。
  • 19~22行目 Wi-Fi関連設定です。各自使用のWi-FiアクセスポイントのSSID, Passwordを設定してください。
  • 24~31行目 NTP関連の設定です。
  • 33~61行目 Wi-Fi接続しNTPにより時刻の取得を行います。Wi-Fi接続または、時刻取得に失敗した場合はfalseでリターンします。
  • 63~68行目 Ambientサービス関連の設定です。Ambientから割り当てられるチャネルID, ライトキーを設定してください。
  • 70~99行目 Wi-Fi接続をしてAmbientサービスへデータの送信を行います。エラーチェックは行っていませんので、何らかの原因でデータ送信に失敗した場合は、データが欠損します。
  • 101~110行目 初期化ルーチンです。M5StackのLCD画面設定とNTPによる時刻取得を行いますが、失敗した場合にはLCD画面にエラーを表示して動作を停止します。Wi-Fi設定に誤りがないか確認をしてください。
  • 112~157行目 メインルーチンです。現在時刻を取得し、秒が更新されていたら、以下処理を実行します。
  • 116~120行目 時刻をLCD画面に表示します。
  • 121~125行目 気圧、温湿度を測定します。
  • 128行目 5分毎にAmbientへデータ送信します。
  • 129~133行目 暑さ指数に応じたイラストを表示します。
  • 134~140行目 暑さ指数が25℃以上の時にビープ音を発生させます。
  • 141~154行目 暑さ指数、不快指数、温湿度、気圧をLCD画面に表示します。

(3)サンプルプログラムの実行例

 サンプルプログラムを実行したときのM5StackのLCD表示をキャプチャしたものを以下に示します。
ほぼ安全 注意 警戒 厳重警戒 危険

 Ambientへ送信したデータは、次の手順でAmbientサービスの設定することにより可視化することができます。

 【作成したチャネルの設定を行う】
  以降、Ambientサービスにログインした状態で作業を行ってください。
 ・チャネル一覧ページにアクセスし、作成したチャネルの「設定変更」をクリックし、
  チャネル名、データ名を設定します。
チャネル設定
 【チャートを作成する】
 ・チャネル一覧ページにアクセスし、作成したチャネル名をクリックします。
 ・画面上部のチャート作成アイコンをクリックしてチャートを追加します。
チャート作成アイコン  ・チャートの設定を行う。温湿度をひとつのチャートに描画する設定例を以下に示します。
チャート設定変更
※上記設定によるチャートの描画例を以下に示します。
チャート描画例
※チャートは、1チャネル当たり8個まで設定できますので、様々な可視化を行うことができます。
複数チャート描画例
※チャート化をしてみると暑さ指数(WBGT)と不快指数(THI)は、ほぼ同意であることがわかります。面白いですね。

まとめ

 M5Stackは、ちょっとした困りごとを解決するツールとして最適です。前編に続いて後編では、データをクラウドへアップロードすることによって、それぞれのデータの時間的変化を可視化することができました。就寝中に熱中症の危険が無いかなどを調べたり、遠方に住む家族の状況を把握したりと応用が広がりそうです。本記事をベースにいろいろな機能追加をされてみてはいかがでしょうか。
 M5Stackをお持ちでない方は、マルツで購入できます。文末のリンクから購入をご検討ください。

関連記事:M5Stack×温湿度センサで作る「熱中症モニタ」(前編)

M5Stack BASIC
M5Stack Basic V2.6
【M5STACK-K001-V26】
M5Stack FIRE IoT開発キット(PSRAM)V2.6
M5Stack FIRE IoT開発キット(PSRAM)V2.6
【M5STACK-K007-V26】
M5Stack Core2 IoT開発キット
M5Stack Core2 IoT開発キット
【M5STACK-K010】
ENV.III
M5Stack用温湿度気圧センサユニット
Ver.3(ENV III)
【M5STACK-U001-C】

c2022ー @logic_star All rights reserved.



Page Top