M5StackとBME280センサーで取得した環境データをクラウドで可視化する

#はじめに
 M5StackとBME280を利用し、取得したデータをクラウドで可視化する。
  
 
#やりたいこと

 M5StackというESP32基板のマイコンボードを使う。

 環境センサーは、Bosch製のBME280を利用する。数年前、ヘリウム環境で使うセンサーを探したことがあって、市販のセンサーを全部試したことがあった。すべてのメーカのセンサーにヘリウムガス漏れが発生してしまいドリフトが発生したが、このBME280だけは全然ガス漏れしなかった。
 IoTプロジェクトにおいて、環境センサーの選定の時は、まずBME280を選択すれば失敗することは絶対ないと思う。モジュールは、[Adafruit BME280](https://www.adafruit.com/product/2652)がおすすめである。Adafruit社の製品の場合、Arduino向けのライブラリーが充実しており、プログラミングが楽である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/57e3df05-e5f5-9fc4-3e15-4ce23c42d737.png)
**Bosch BME280**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/78427729-fbda-8f5e-f5ed-9a782f0e77b0.png)
**Adafruit BME280 Board: I2C, SPIインタフェース支援**

　そして、BME280より温度、湿度、圧力の情報を取得し、Ambientというクラウドサービスを利用し、可視化する。

![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/8e039cc7-ee6a-de34-5029-2c6ed1b0d525.jpeg)
**M5Stack + BME280**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/702e841f-c549-a4bf-8f59-6bf34579e265.png)
[出典:　Ambient Data Inc.](https://ambidata.io/)

　Ambientの利用には、ユーザー登録([無料](https://ambidata.io/usr/signup.html))が必要である。ユーザー登録し、ログイン後のページで「チャネルを作る」ボタンをクリックするとチャネルが生成され、「チャネルId」と「ライトキー」が設定される。Ambientにデーターを送信する時は、この「チャネルId」と「ライトキー」を利用する。

#実行画面

　比較的簡単に可視化サイトの構築ができた。下記のリンクを押すと、公開ページへ移動する。
[**リンク：M5Stack +　BME280 可視化画面**](https://ambidata.io/ch/channel.html?id=21534)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/031575a0-785c-8016-1ff7-aee07b05754d.png)

#プログラムコード

注意する部分：全体コードの中にAmbientのチャンネルidとライトキーを入力する部分がある。 * と"**"表記された部分で、これはAmbientのチャンネル登録の際に付与されるので、それを記入すればいい。

```c++

#Ambientのチャンネルidとライトキー
unsigned int channelID = *****; 
const char* writeKey = "********************";
```

全体コード

```c++:M5Stack_BME280_Ambient.ino

#include <M5Stack.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Ambient.h>

#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
unsigned long delayTime;

#Wifi SSID + PASSWORDを入力
const char* ssid ="*************";
const char* password ="*************";

WiFiClient client;
Ambient ambient;

#Ambientのチャンネルidとライトキー
unsigned int channelID = *****; 
const char* writeKey = "********************";


void setup() {
  M5.begin();
  M5.Lcd.setTextSize(2);
  WiFi.begin(ssid, password);
  
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    M5.Lcd.print('.');
  }

  M5.Lcd.print("\r\nWiFi Connected\r\nIP address: ");
  M5.Lcd.println(WiFi.localIP());

  //Ambient IO
  ambient.begin(channelID, writeKey, &client);
  
  //BME280 Initialization
    Serial.begin(115200);
    while(!Serial);    // time to get serial running
    M5.Lcd.println("BME280 test");

    unsigned status;
    
    // default settings
    status = bme.begin();  
    // You can also pass in a Wire library object like &Wire2
    // status = bme.begin(0x76, &Wire2)
    if (!status) {
        M5.Lcd.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        M5.Lcd.print("SensorID was: 0x"); 
        M5.Lcd.println(bme.sensorID(),16);
        M5.Lcd.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        M5.Lcd.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        M5.Lcd.print("        ID of 0x60 represents a BME 280.\n");
        M5.Lcd.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }
    
    M5.Lcd.println("-- Default Test --");
    delayTime = 1000;

    M5.Lcd.println();
 
}

void loop() {
    float temp = bme.readTemperature();
    float pres = bme.readPressure()/1000.0F; //[kPa]
    float humid = bme.readHumidity();
    M5.Lcd.printf("Temp: %.2f, Press: %.2f, Humid: %.2f \r\n", temp,pres,humid);

    ambient.set(1,temp);
    ambient.set(2,humid);
    ambient.set(3,pres);
    ambient.send();

    delay(60*1000);
}

void M5printValues() {
    
    float temp = bme.readTemperature();
    float pres = bme.readPressure()/1000.0F; //[kPa]
    float humid = bme.readHumidity();

    M5.Lcd.setCursor(20,40);
    M5.Lcd.print("Temp: ");
    M5.Lcd.print(temp,1);
    M5.Lcd.print("degC");
    
    M5.Lcd.setCursor(20,100);
    M5.Lcd.print("Pressure: ");
    M5.Lcd.print(pres,1);
    M5.Lcd.print("kPa");

    M5.Lcd.setCursor(20,160);
    M5.Lcd.print("Humidity: ");
    M5.Lcd.print(humid,1);
    M5.Lcd.print("%RH");
    
}
```
#まとめ

1.M5Stack+BME280のセンサーデータを、クラウドで可視化することができた。

#参考資料
1.[M5StackとBME280センサーで、環境データを取得する]
(https://qiita.com/kotai2003/items/80fe919b20640a86bace)

2.[みんなのM5Stack入門](https://www.amazon.co.jp/%E3%81%BF%E3%82%93%E3%81%AA%E3%81%AEM5Stack%E5%85%A5%E9%96%80-%E4%B8%8B%E5%B3%B6%E5%81%A5%E5%BD%A6-ebook/dp/B082DVY3J1/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=M5Stack&qid=1591166876&s=books&sr=1-2)

IoT可視化サービスAmbinet社の下村さんが書いた本を参考にした。
M5Stack,ESP32全般に関する情報をわかりやすく整理したので、M5Stackユーザーにはおすすめする。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/36396e04-8fcc-b3dd-9b96-04dec9cccd79.png)