M5AtomLiteとENV IIユニットを使って激安で気象観測所を開設する方法


![Screenshot_2020-09-30_17-58-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/f227f338-b1f2-ea54-84af-d5e76e2bfcf5.png)

[ソースコード（スケッチ）の公開](https://gist.github.com/hotstaff/b15f655fac774e1ff4580e02ac21da3d)

M5AtomとM5Stack用環境センサユニット ver.2（ENV II）を使って、Ambientに測定データを送ることであっという間に気象観測ができます。しかも費用は２０００円程度で作れてしまいます。

M5Stackは様々なセンサーのラインナップがあるので簡単にいろいろな計測に応用が可能です。今回はつなぐだけで作れる気温、湿度、気圧を測定するものを作りました。

それでは作り方を紹介します。

# ステップ１　部品を準備する

- M5AtomLite (Switch Scienceにて税抜968円で販売中）
- M5Stack用環境センサユニット ver.2（ENV II） （Switch Scienceにて税抜572円で販売中）

USB-Cケーブルも写っていますが、これは15cmの短いケーブルです。スケッチを書き込むときに便利です。
![DSCF1414.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/ba4c6202-1a03-f04e-2cf8-366390d45ea0.jpeg)

ハードウェアの組み立てはとても簡単です。
箱から出して**Groveケーブルでつなぐだけ**です。

![DSCF1416.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/98fba5bf-e8b3-ab21-b8fa-976a9b462ec3.jpeg)

非常にあっけないものです。これにてある意味**完成**です。不思議な話ですが、センサーユニットよりコンピュータが入ってる
M5AtomLiteのほうが小さいんですよね。この商品すごい完成度です。

あとはこれで気象観測するためにいくつか部品が必要です。

- USB-Cケーブル １００円ショップで購入可能

![DSCF1425.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/a58d42e6-7dcc-393d-55cb-baf0f0a72634.jpeg)

- 適当な大きさのケース　１００円ショップで購入可能

![DSCF1421.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/9de2ed5d-acc9-802c-2023-ef5f5334a57f.jpeg)

- USB給電アダプタ　１００円ショップで購入可能

![DSCF1441.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/0f9c34c8-2e63-9acf-f790-ce7c5f3fbd6b.jpeg)

| 品名 | 価格 |
|:-----------|:------------:|
| M5AtomLite | 968円         |
| M5Stack用環境センサユニット ver.2| 572円       |
| USB-Cケーブル(1m)       | 100円        |
| ケース         | 100円           |
| USB給電アダプタ  | 100円 |
| *消費税(10%)*    |  184円     |
| **合計**      |  2024円   | 


これだけで気温、湿度、気圧を常時測定し無線LANでネットにデータを上げ続ける気象観測所が作れます。
あとは設置する場所によっては

- USB延長ケーブル
- 結束バンド
- 洋灯吊金具

等があれば十分です。

# ステップ２　スケッチの準備

今回のコードはAmbientの中の人の記事だと思われる下記を参考にさせてもらいました。

- [M5StickCで小型環境センサ端末を作る](https://ambidata.io/samples/m5stack/m5sitckc/)

基本的な変更点はM5AtomLiteはディスプレイがないので、シリアルにメッセージを出力するように変えただけです。その他センサーの読み取り方法などをENV.Ⅱユニットに対応させました。

ポイントとしては

- Adafruit_BMP280
- Adafruit_SHT31
 
というライブラリを使っています。これはArduinoIDEから簡単にインストールできます。

書き込むスケッチは以下のようなものです。

```c++:env2-m5atom.ino
#include <M5Atom.h>
#include <Wire.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_SHT31.h>
#include <Ambient.h>

// sensor
#define TIME_TO_SLEEP  7
#define PRESSURE_LOWB 750 //hPa

// WiFi
#define SSID "ssid"
#define PASSWORD "password"
#define RETRY 20

// Ambient
#define CHANNELID number
#define WRITEKEY "writekey"

Adafruit_SHT31 sht3x;
Adafruit_BMP280 bme;

WiFiClient client;
Ambient ambient;

bool connect_wifi() {
    int i = RETRY;
    WiFi.begin(SSID, PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
        if (!i--) {
            // リトライ回数の上限に達したら接続失敗
            Serial.println("Could not connect to WiFi");
            return false;
        }
        delay(500);
        Serial.print(".");
    }
    Serial.print("WiFi connected\r\nIP address: ");
    Serial.println(WiFi.localIP());
    return true;
}

void setup() {
    M5.begin();

    // 26, 32はM5AtomLiteのI2Cのピン番号
    // 本体のラベルを確認
    Wire.begin(26, 32);

    // センサーの初期化
    while (!bme.begin(0x76)) {
        Serial.println("BMP280 init fail");
    }
    while (!sht3x.begin(0x44)) {
        Serial.println("SHT3x init fail");
    }

    // 測定
    float tmp = sht3x.readTemperature();
    float hum = sht3x.readHumidity();

    // 自分の環境では稀にBME280が異常に小さい圧力を返すときがあるため
    // 下限以下だと再取得するようにしました
    float pressure = 0.0;
    do {
        pressure = bme.readPressure();
    }while(pressure < PRESSURE_LOWB * 100);

    Serial.printf("temp: %4.1f'C\r\n", tmp);
    Serial.printf("humid:%4.1f%%\r\n", hum);
    Serial.printf("press:%4.0fhPa\r\n", pressure / 100);
    
    // 無線LANへ接続
    if (connect_wifi()) {
        ambient.begin(CHANNELID, WRITEKEY, &client);

        // 温度、湿度、気圧、バッテリー電圧の値をAmbientに送信する
        ambient.set(1, tmp);
        ambient.set(2, hum);
        ambient.set(3, pressure / 100);

        if (ambient.send()) {
            Serial.println("The data was successfully sent to the ambient");
        }else{
            Serial.println("Failed to send data to ambient");
        }
    }

    // ディープスリープモードに落ちる
    esp_deep_sleep(TIME_TO_SLEEP * 1000000);
}

void loop() {
    // deepsleepでループすると毎回setup()が呼ばれるためloop()は何もなしでOK
}
```

$#define$の部分は設定になっています。環境に合わせて設定してください。

たったこれだけのコードでセンサーのデーターを読み取り、無線LANに接続し、Ambientに送信できます。すべて作るとなると結構面倒なので、これは優秀なライブラリのおかげですね。


## 設定

設定は以下のようなものが必要です。環境に合わせて設定してください。

### センサーの設定
```
// sensor
#define TIME_TO_SLEEP  7
#define PRESSURE_LOWB 750 //hPa
```
`TIME_TO_SLEEP`は何秒ごとに測定するかを表しています。この例だと７秒毎にディープスリープから起き上がって測定します。自分の環境では5分=300秒くらいにするとちょうどいい感じになりました。例では書き込みした後のテストで５分も待たされると大変なので短めにしています。

原因は不明ですが、BME280が稀に700hPa付近の値を出力するので圧力値の下限`PRESSURE_LOWB`を追加しました。これを超える値が出るまで`do{} while()`ループで測定し直します。

下の画像は飛んでる例です。グラフが見えずらくなるので除外します。
![Screenshot_2020-09-30_06-47-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/6899e6c8-58c3-439a-291d-facae36b5f30.png)

再現性があるのかよくわかりませんが、起きないようでしたら、部分はなくてもいいかもしれないです。

### WiFiの設定
```
// WiFi
#define SSID "ssid"
#define PASSWORD "password"
#define RETRY 20
```
これはWiFiの設定です。ssidとpasswordをそれぞれ設定します。

無線LANへの接続が失敗すると無限ループになるのでリトライ回数の上限を設定しました。`RETRY 20`とすると0.5秒を２０回つまり１０秒間だけ接続を待ちます。

### Ambientの設定
```
// Ambient
#define CHANNELID number
#define WRITEKEY "writekey"
```
最後に最も重要な部分です。これはAmbientにユーザー登録した先のHPで得られます。

![Screenshot_2020-09-28_16-24-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/42c996c0-8a0e-18bb-2303-423620bbee50.png)

必要なのはチャンネルIDとライトキーのみです。この２つを控えておいて、#defineの値を書き換えます。文字列の設定部分は両端に""ダブルクォートかシングルクォート''が必要です。チャンネルIDは数値なので囲む必要はありません。

あとは編集したスケッチをArduinoIDEから転送するだけです。

# ステップ３　スケッチの転送

ArduinoIDEにはESP32PicoKitのボードが選択可能だとして説明します。まだインストールできていない場合はボードマネージャーからインストールしてください。

ArduinoIDEからボードをESP32PicoKitを選択し、Upload Speedを115200に設定します。自分の環境ではこの一番遅いもの以外ではたまに書き込みエラーが出ました。

![Screenshot_2020-09-28_16-30-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/6ab38601-92b4-4c71-d968-42cc5fa1fb8c.png)


# ステップ４　動作確認

書き込みが成功していれば設定した時間間隔で起き上がり、無線LANに接続しAmbientに送信していると思います。

正常に計測できていれば、シリアルモニターで見ると、気温、湿度、気圧の値とともに`The data was successfully sent to the ambient`という表示があるはずです。

この時点でAmbientのチャネルのベージではすでに下のようなグラフが確認できているはずです。

![Screenshot_2020-09-28_16-36-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/dae6c456-7f7c-ec1a-501b-61a3e15e8911.png)

画像やプロット名はAmbientのページから設定可能です。

# ステップ５　ケースに入れて設置

無事動作確認できたら、最後にケースにしまって完成です。

![DSCF1440.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/c2d137d9-66c4-7fdf-0032-26d57e83721a.jpeg)

今回はランタンという丁度いい大きさのものが１００円ショップに売っていたのでそれに入れました。吊り下げる部分がついてるので、フックに引っ掛けて簡単に軒下に設置できました。ケーブルは結束バンドで適当にケースに止めてUSB-Cコネクタに力がかかって抜けないようにしています。

あとはこれにUSBアダプタで電源を供給すれば、永久に測定し無線LAN経由でAmbientに送信し続ける観測地点の完成です。

![DSCF1446.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232003/dd828f57-103d-05d0-ad11-d77881c5a7a2.jpeg)

今回作った気象観測所のページは以下になります。

- [今回作ったAmbientのページ](https://ambidata.io/bd/board.html?id=15652)

以前だったら１００００円くらいはかかってたものが、こんなに簡単に作れるとはいい時代になりました。環境センサーだけじゃなくてPM2.5などの測定をやってる方もたくさんいるみたいです。

- [Ambient公開ボード](https://ambidata.io/bd/openBoard.html)

アイディア次第でいろいろ使えそうです。