• conect+

M5Stackからconect+ Studioに温度・湿度・気圧センサー情報を送信しよう

最終更新: 1月24日

  1. 概要

  2. M5Stackをセットアップする

  3. 環境センサユニットⅡ(温度・湿度・気圧センサー)からセンサー情報を取得する

  4. conect+stduioの設定方法

  5. conect+studioにM5Stackからセンサーデータを送信する

  6. ダッシュボードにグラフを表示して可視化する

1.概要


 M5Stackは、5インチサイズの小型でありながらもカラーディスプレイ、microSDカードスロット、スピーカーなどを備えたコンパクトで便利な開発モジュールです。ESP32マイコンを搭載しているため、Wi-FやBluetooth通信扱うことができ、ArduinoIDEやビジュアルプログラミングの環境により、IoT機器の試作においても有用な端末です。


この記事では、M5Stackの標準モデルM5Stack Basicに環境センサーユニットⅡ(SHT30とBMP12を内蔵したセンサーモジュール)をつなぐことで、温度・湿度・気圧といった情報をconect+ Studioに送信し、センサー情報の可視化を行う例をご紹介します。


※ダッシュボードの表示例(温度、湿度、気圧)


2.M5Stackをセットアップする

まずはM5StackをArduinoIDEでプログラミングできるように設定します。

ArduinoIDEはArduino ( https://www.arduino.cc/ )からダウンロードすることができます。

今回はWindows10を例に開発する例をご説明します。「Software」の「Download」から"Windows app"を選択し、ArduinoIDE を入手します。(今回の記事ではWindows10を対象として開発環境構築を進めます)

ArduinoIDEをインストール後、M5Stackの開発環境を構築します。

M5Stackの公式ページにWindows/Mac/Linuxでのインストール方法が解説されていますので、こちらでは概要のみご説明します。

M5Stack Docs - The reference docs for M5Stack products.


・PC接続用のCP2104 ドライバーをインストール

・ArduinoIDEの「環境設定」より追加のボードマネージャに以下のURLを追加します。

https://dl.espressif.com/dl/package_esp32_index.json

・ツールのボードマネージャよりesp32を検索し、インストールします。

・「スケッチ」-「ライブラリのインクルード」-「ライブラリマネージャ」よりM5Stackをインストールします。

これでArduinoIDE側にM5Stackを扱う上で必要なライブラリ準備は完了です。

「ファイル」-「スケッチ例」-「サンプルスケッチ」から「Display」などのデフォルトで入っているサンプルプログラムを選択し、ボードマネージャから「M5Stack-Core-ESP32」を選択します。M5StackをUSBで接続してビルドと書き込みが成功したら開発環境の構築は成功です。

※このセットアップ情報はArduino1.8.13(2020/11/22)時点の情報となります。

最新の設定方法についてはArduinoやM5Stackの公式情報を参照ください。




3.環境センサユニットⅡ(温度・湿度・気圧センサー)からセンサー情報を取得する


M5Stackに環境センサーユニットⅡを接続し、温度・湿度・気圧を取得してみましょう。

環境センサーユニットⅡはArduinoやM5Stackなどに接続がしやすいSeeed社のGroveインタフェース規格で作られた複合環境センサーです。内部にはSHT30とBMP280の2つのセンサーを搭載しています。


・M5StackのGroveコネクタにセンサーを接続します。


環境センサの中に入っている2種類に必要となるライブラリをインストールします。


①MBP280はライブラリマネージャより「Adafruit BMP280 Library」をインストールします。


② M5StackのGitHubに公開されているサンプルコードをまとめてダウンロードします。

GitHub - m5stack/M5-ProductExampleCodes

③ 前の手順でダウンロードしたフォルダより「M5-ProductExampleCodes-master\Unit\ENVII\Arduino\ENVII」内にある「Adafruit_Sensor.h」「SHT3X.cpp」「SHT3X.h」をコピーし、「C:\Users\<user_name>\Documents\Arduino\libraries\Adafruit_BMP280_Library」にコピーします。これにより2つのセンサのライブラリを両方とも呼び出せるようにします。


④以下の公式サンプルプログラムの「ENVII.ino」の内容を元に、ビルドし書き込みます。

#include <M5Stack.h>
#include <Wire.h>
#include "Adafruit_Sensor.h"
#include <Adafruit_BMP280.h>
#include "SHT3X.h"
SHT3X sht30;
Adafruit_BMP280 bme;

float tmp = 0.0;
float hum = 0.0;
float pressure = 0.0;

void setup() {
  M5.begin();
  Wire.begin();
  M5.Lcd.setBrightness(10);
  M5.Lcd.setTextSize(3);
  Serial.println(F("ENV Unit(SHT30 and BMP280) test..."));

  while (!bme.begin(0x76)){  
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    M5.Lcd.println("Could not find a valid BMP280 sensor, check wiring!");
  }
  M5.Lcd.clear(BLACK);
  M5.Lcd.println("ENV Unit test...");
}

void loop() {
  pressure = bme.readPressure();
  if(sht30.get()==0){
    tmp = sht30.cTemp;
    hum = sht30.humidity;
  }
  Serial.printf("Temperatura: %2.2f*C  Humedad: %0.2f%%  Pressure: %0.2fPa\r\n", tmp, hum, pressure);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.setTextColor(WHITE, BLACK);
  
  M5.Lcd.printf("Temp: %2.1f  \r\nHumi: %2.0f%%  \r\nPressure:%2.0fPa\r\n", tmp, hum, pressure);

  delay(100);

}

以下のようにセンサーデータがM5Stackのディスプレイに出力されればセンサー情報の取得は成功です。息を吹きかけたり、手で温めたりしてセンサ値が変化することを確認してみてください。


4.conect+ Studioの設定方法について

 前章ではM5Stackでセンサデータを取得できることまでを確認できました。これからそのデータをconect+Studioにデータを送信するための準備を始めます。まず、conect+Stduioの「データアダプター」画面から「データアダプターを追加」を選択します。

WebAPIを選択します。


データアダプター名を入力してください。こちらの項目は今後様々なデータを管理する上で、わかりやすい名前にしておくことをお勧めます。ここでは「M5Stack-Adapter」としました。

新たに生成されたデータアダプターの右に並ぶアイコンから「デバイス」を選択します。


「デバイス」管理画面に遷移しますので「デバイスを追加」を押下し、センサーを追加していきます。

今回つなぐのは温度、湿度、気圧なので3つのセンサーを追加します。

まず管理番号となるデバイスIDを指定します。「センサーを追加する」で3つのセンサーを追加し、それぞれの名前は後からわかるように「温度」「湿度」「気圧」を指定し、IDは英数字で「temp01」「humid01」「press01」を指定します。(ここは管理しやすく、任意の文字列を指定いただければ問題ありません。ただし、IDとセンサーIDについてはプログラム上でも使うため英数字にする必要があります。)


これで今回データを送信するためのアダプターが作られました。今回つくったアダプターが正しく動か確認してみましょう。新規作成したデータアダプターから「?」アイコンの「リファレンス」を開きます。

リファレンスから「POST」を選択し、「Try it out」を押下してください。ここでデータをconect+に送るpost処理を仮想的にテストすることができます。

先程指定したデバイス名、センサーID(今回はM5Stack)を入力します。

下にスクロールし「Execute」を押すと、RequestBodyに仮に定義されているデータで仮想的にPOSTが実行されます。結果が「Success」となれば仮想的なデータPOSTの実行が成功です。


「データ」を選択し、データアダプター、デバイス、センサーを指定して「検索」を押下すると実際にconect+に保存されたデータを確認することができます。こちらのデータを確認できれば、conect+側の設定は完了です。



5.conect+ studioにM5Stackからセンサーデータを送信する

 この章では、いよいよM5Stackからconect+にセンサーデータを送信します。以下にM5Stack側のプログラムを示します。M5Stackが起動したら指定したWifiに自動的に接続し、センサの値を10秒程度ごとに更新取得、conect+にデータ温度、湿度、気圧を順番に送信する内容となっています。



#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include "Adafruit_Sensor.h"
#include <Adafruit_BMP280.h>
#include "SHT3X.h"
#include <M5Stack.h>
SHT3X sht30;
Adafruit_BMP280 bme;

// C+ Studioに送るhostURLを定義
const char *hostTemp = "https://api.studio.conect.plus/sensingData/xxxxxx/temp01";
const char *hostHumid = "https://api.studio.conect.plus/sensingData/xxxxxx/humid01";
const char *hostPress = "https://api.studio.conect.plus/sensingData/xxxxxx/press01";

WiFiClient client;
//接続するWifiのSSID/Passを定義
const char *ssid = "XXXXX";
const char *password = "XXXXX";

void setup()
{
  M5.begin();
  Serial.begin(115200);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextColor(WHITE, BLACK);
  M5.Lcd.fillScreen(BLACK);
  //センサの接続チェック
  while (!bme.begin(0x76))
  {  
    Serial.println("Could not find a valid BMP280 sensor");
    M5.Lcd.println("Could not find a valid BMP280 sensor");
  }
  // Wifi接続
  M5.Lcd.println("Wifi connecting");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
     delay(100);
     M5.Lcd.print(".");
  }
  M5.Lcd.println("Wifi conected");
  // NTPサーバーと時刻情報の同期
  configTime(9 * 3600, 0, "ntp.nict.jp"); 
}

void loop()
{
  struct tm timeInfo;
  char   timeString[30];
  char   timeStringDisplay[20];
  double sensorValTemp=25;
  double sensorValHumid=50;
  double sensorValPress=1000;

  // センサ情報取得とセンサ情報送信のループ
  while(1)
  {
    //センサ情報の更新
    sensorValPress = bme.readPressure();
    if(sht30.get()==0)
    {
      sensorValTemp = sht30.cTemp;
      sensorValHumid = sht30.humidity;
    }
    Serial.printf("Temp:%2.2f*C Humid:%0.2f%%  Press:%0.2fPa\r\n", 
                   sensorValTemp, sensorValHumid, sensorValPress);
    M5.Lcd.setCursor(0, 50);
    M5.Lcd.printf("Temp:%2.1f \r\nHumid:%2.1f%% \r\nPress:%2.1fPa\r\n", 
                   sensorValTemp, sensorValHumid, sensorValPress);

    // 現在の時刻を取得
    getLocalTime(&timeInfo);
    // C+Stduioに送信するための時刻文字列を作成
    sprintf(timeString,"%04d-%02d-%02dT%02d:%02d:%02d.000+09:00" 
                ,timeInfo.tm_year + 1900
                ,timeInfo.tm_mon + 1
                ,timeInfo.tm_mday
                ,timeInfo.tm_hour
                ,timeInfo.tm_min
                ,timeInfo.tm_sec
                );
    // M5Stackに表示するための時刻文字列を作成
    sprintf(timeStringDisplay,"%04d-%02d-%02dT%02d:%02d:%02d" 
                ,timeInfo.tm_year + 1900
                ,timeInfo.tm_mon + 1
                ,timeInfo.tm_mday
                ,timeInfo.tm_hour
                ,timeInfo.tm_min
                ,timeInfo.tm_sec
                );

    // センサデータを文字列に変換
    String sensorValTempStr = String(sensorValTemp,2);
    String sensorValHumidStr = String(sensorValHumid,2);
    String sensorValPressStr = String(sensorValPress,2);
    
    // C+送信用のJSONを作成
    String dc = "\""; // ダブルクオーテーション文字列を定義
    String timeStingDc = dc + timeString + dc;
    String jsonStringTemp   = 
     "{" + dc + "sensingAt" + dc + ":" + timeStingDc + ","
       + dc + "value01" + dc  + ":" + sensorValTempStr + "}";
    String jsonStringHumid  = 
      "{" + dc + "sensingAt" + dc + ":" + timeStingDc + ","
       + dc + "value01" + dc  + ":" + sensorValHumidStr + "}";
    String jsonStringPress  =
       "{" + dc + "sensingAt" + dc + ":" + timeStingDc + ","
       + dc + "value01" + dc  + ":" + sensorValPressStr + "}";
    Serial.println(jsonStringTemp);
    Serial.println(jsonStringHumid);
    Serial.println(jsonStringPress);

    // HTTP POSTのためのhttpインスタンス作成
    HTTPClient http;
    // 温度送信
    http.begin(hostTemp);
    http.addHeader("Content-Type", "application/json");
    int status_code = http.POST(jsonStringTemp);
    if( status_code == 200 )
    {
        Serial.println("Send Temp , Successful operation");
    }
    http.end();
    // 湿度送信
    http.begin(hostHumid);
    http.addHeader("Content-Type", "application/json");  
    status_code = http.POST(jsonStringHumid);
    if( status_code == 200 )
    {
        Serial.println("Send Humid , Successful operation");
    }
    http.end();
    // 気圧送信
    http.begin(hostPress);
    http.addHeader("Content-Type", "application/json");
    status_code = http.POST(jsonStringPress);
    if( status_code == 200 )
    {
        Serial.println("Send Press , Successful operation");
        // 送信成功時にupdate時刻をM5Stackに表示
        M5.Lcd.setCursor(0, 120);
        M5.Lcd.println("update:\r\n" + String(timeStringDisplay));
    }
    http.end();
    // 10秒程度の待ち時間
    delay(10000);
 }
}

以下に上記サンプルプログラムのポイントを解説します。



① conect+に送るホストURLを定義します

以下定義で、今回作成したデータアダプターに対してデータを送信するURLを定義します。

// C+ Studioに送るhostURLを定義
const char *hostTemp = "https://api.studio.conect.plus/sensingData/xxxxxx/temp01";
const char *hostHumid = "https://api.studio.conect.plus/sensingData/xxxxxx/humid01";
const char *hostPress = "https://api.studio.conect.plus/sensingData/xxxxxx/press01";

こちらのURLはご自身が先程作成したデータアダプターのリファレンスから指定します。それぞれワークスペースID、WebAPIキー、デバイスID、センサーIDとなります。温度、湿度、気圧ごとのURLを定義してください。

https://api.studio.conect.plus/sensingData/{ワークスペースID}/{WebAPIキー}/{デバイスID}/{センサーID}

参考:WebAPIの使い方


② 接続先となるWifiとSSIDのパスワードを定義します。

//接続するWifiのSSID/Passを定義
const char *ssid = "XXXXX";
const char *password = "XXXXX";


③時刻情報からC+に送信する時刻データ文字列を生成します。

conect+には時刻を"2019-12-05T13:26:53.124+09:00"のフォーマットで送信する必要があります。getLocalTimeで時刻を取得した後、sprintfを用いて時刻データを指定文字列に変更します。

// 現在の時刻を取得
getLocalTime(&timeInfo);
// C+Stduioに送信するための時刻文字列を作成
sprintf(timeString,"%04d-%02d-%02dT%02d:%02d:%02d.000+09:00" 
             ,timeInfo.tm_year + 1900
             ,timeInfo.tm_mon + 1
             ,timeInfo.tm_mday
             ,timeInfo.tm_hour
             ,timeInfo.tm_min
             ,timeInfo.tm_sec
             );

④ HTTPで作成したデータをpostする

HTTPClientからインスタンスのhttpを作成し、http.begin("hostURL")によりhttpの処理を開始します。postメソッドでURLを指定してデータをポストします。

戻り値のstatus_codeが200なら成功なので、成功表示処理を入れています。必要に応じてエラー処理を導入してください。

   // HTTP POSTのためのhttpインスタンス作成
    HTTPClient http;
    // 温度送信
    http.begin(hostTemp);
    http.addHeader("Content-Type", "application/json");
    int status_code = http.POST(jsonStringTemp);
    if( status_code == 200 )
    {
        Serial.println("Send Temp , Successful operation");
    }

本プログラムをM5Stackに書き込み、以下のように「Wifi接続状況」「センサ値」「update時刻」表示がされていればconect+へのデータ送信は成功です。


5.ダッシュボードにグラフを作成して可視化する

 前章を通して、M5Stackからconec+にデータを送信するところまで完了しました。最後にダッシュボードにデータを並べて可視化しましょう。「ダッシュボード」を選択し「新しいページを追加」します。

自由にページ名を指定し、今回はグリッドレイアウトを選択し、保存を押下します。


ダッシュボードの編集画面から「ウィジェット追加」で折れ線グラフを追加します。


「センサーを追加」からセンサーをグラフに表示するセンサーを設定します。それぞれ「アダプタ」「デバイス」「センサ名」を選択肢から指定するだけで自動的に反映されます。


先程の同様の手順で他のセンサーも追加し、温度、湿度、気圧をすべて追加しましょう。「保存する」を押下したらM5Stackの各種センサー情報の可視化は完了です。設定によりこの画面の公開URLを作成することも可能です。


635回の閲覧0件のコメント