【M5Stick】ENV HAT Ⅲを使って3時間おきの気象データをLINEへ送信

M5Stack

こんにちは! ぜろはちです。

家庭菜園や夏休みの宿題などで毎日の気象データを自動で管理出来たら便利ですよね。

今回、M5Stickと気温、湿度、気圧センサが一体となったENVⅢを使って実現出来たので記事にします。自動管理は、LINE Notifyというサービスを使ってスマホへデータ送信する方法を取りました。

こんな人におすすめ!

  • 家庭菜園や夏休みの宿題などで気象データを管理したい人
  • M5Stack/Stickを活用したい人
  • M5Stickを使ったプログラミングを学習している人

準備したもの

  • M5StickC Plus
  • ENV HAT Ⅲ (気温、湿度、気圧センサー)
  • Wifiルータ
  • LINEがインストールされたスマホ

システム構成

製作方法

製作方法は次の順で解説していきます。まず製作に必要な事前知識です。ENV Ⅲのデータ計測方法、LINE Notifyを使ったデータ送信方法、そしてディープスリープモードによる省電力を説明します。次に全体プログラムの解説になります。

ENV Ⅲの気温・湿度・気圧データ計測方法

ENV Ⅲ概要

今回用いる温度・湿度・気圧センサはENV HAT Ⅲというすべてセンサが1パッケージになっているものを使用します。

2022年3月時点の価格は1430円でした。

温度・湿度センサにはSHT30、気圧センサにはQMP6988というチップが使われています。通信方式はI2Cです。

スペックを載せておきますね。

項目パラメータ
温度測定範囲-40 ~ 120℃
最大測定精度0 ~ 60℃ / ±0.2℃
湿度測定範囲 /誤差10 ~ 90%RH / ±2%
気圧測定範囲 /分解能 /誤差300 ~ 1100 hPa / 0.06 Pa / ±3.9 Pa
通信プロトコルI2C:SHT30(0x44)、QMP6988(0x56)
動作温度範囲0 ~ 40℃

UNIT_ENVライブラリのインストール

M5Stackからライブラリがリリースされているので、今回このライブラリを使用します。

私はArduino IDEではなく、Platform IO IDEを使用していますので、Librariesから「UNIT_ENV」を検索すればライブラリが見つかりますよ。

PlatformIO IDEの使い方については、こちらの記事で紹介していますので参考にして下さい。

温度・湿度・気圧データ計測するためのプログラム

まずはUNIT_ENVライブラリを呼び出します。

#include "UNIT_ENV.h"

次にWireライブラリを初期化し、I2Cバスに接続します。

Wire.begin(0,26);

温度・湿度はSHT30、気圧はQMP6988を使用していますので、まずはSHT30の解説から。

SHT3Xクラスをインスタンス化し、

SHT3X sht30;

get()関数を呼び出すと温度、湿度が計測されます。

sht30.get()

温度はcTemp、湿度はhumidityに格納されています。

float temp = sht30.cTemp;
float hum = sht30.humidity;

続いてQMP6988の解説。同じようにQMP6988クラスをインスタンス化、初期化し、

QMP6988 qmp6988;
qmp6988.init();

calcPressure()関数を呼び出せば戻り値として気圧が返ってきます。

float pressure = qmp6988.calcPressure();

ライブラリを使えば簡単ですね!

LINE Notifyを使ったデータ送信方法

LINE社が提供しているLINE Notifyを使うとWebサービスからの通知をLINEで受信出来るようになります。

3時間おきにLINE Notifyで温度・湿度・気圧データをLINEへ送信します。

LINE Notifyの使い方はこちらの記事で紹介していますので、今回割愛させていただきます。

M5Stickの省電力化

データ計測は屋外を想定していますので、なるべくM5Stickを省電力化し、バッテリーを長持ちさせたいです。ここでは3つの方法で省電力化していきます。ディープスリープモードクロック周波数変更液晶バックライト変更です。

ディープスリープモード

データ計測は頻繁に行わないため、待機中の電力消費はもったいないです。

M5Stickに搭載されているマイコンESP32はディープスリープモードという省電力モードがありますので、これを使用しました。

esp_deep_sleep(10800000000ULL); // 3 * 60 * 60 * 1000000 μs = 3h

引数で指定した時間スリープした後、マイコンがリセットされます。引数はμsec単位で指定します。

ディープスリープモードはM5Stick自体の温度を下げる目的もあります。連続でデータ計測していると計測温度はどんどん上がっていくので、正確な温度測定にはディープスリープモードにして温度を下げる必要があります。

クロック周波数変更

CPUのクロック周波数を下げることも省電力化には有効です。

setCpuFrequencyMhz(80);

引数の単位はMHzです。デフォルトは240MHzで動作しています。今回、80MHzまで下げました。下げすぎると無線通信が安定しなくなるようです。

液晶バックライト変更

液晶を暗くすることも省電力化に繋がりますよね。

M5.Axp.ScreenBreath(0);

引数は明るさで0-12の範囲で指定します。液晶は見ない前提なのでゼロまで下げました。

全体プログラム

プログラム全体を載せます。

#include <M5StickCPlus.h>
#include "UNIT_ENV.h"
#include <WiFiClientSecure.h>

void Line_notify(String msg);

SHT3X sht30;
QMP6988 qmp6988;
WiFiClientSecure client;  

const char* ssid = "*************";
const char* password = "*****************";

const char* host = "notify-api.line.me";
const char* token = "************************";

float tmp = 0.0;
float hum = 0.0;
float pressure = 0.0;
double vbat = 0.0;

void setup() {
  M5.begin();
  setCpuFrequencyMhz(80);
  M5.Axp.ScreenBreath(0);
  M5.Lcd.setRotation(3);
  M5.Lcd.setCursor(0,0,4);
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED){
    M5.Lcd.print('.');
    delay(500);
  }
  M5.Lcd.print("\r\nWiFi connected\r\nIP address: ");
  M5.Lcd.println(WiFi.localIP());

  Wire.begin(0,26);
  qmp6988.init();

  pressure = qmp6988.calcPressure();
  if(sht30.get()==0){ 
    tmp = sht30.cTemp;  
    hum = sht30.humidity; 
  }else{
    tmp=0,hum=0;
  }
  vbat = M5.Axp.GetVbatData() * 1.1 / 1000;
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0,0,4);
  M5.Lcd.printf("Temp: %2.1f  \r\nHumi: %2.0f  \r\nPressure: %2.0fPa\r\nVolt: %.2fV  \r\n", tmp, hum, pressure, vbat);

  char msg[100];
  sprintf(msg, "Temp: %2.1f  \r\nHumi: %2.0f  \r\nPressure: %2.0fPa\r\nVolt: %.2fV  \r\n", tmp, hum, pressure, vbat);

  Line_notify(msg); // LINE Notifyへリクエスト送信
  
  esp_deep_sleep(10800000000ULL); // 3 * 60 * 60 * 1000000 μs = 3h
}

void loop() {
  
}

void Line_notify(String msg) {
  client.setInsecure();
  if (!client.connect(host, 443)) {
    delay(2000);
    M5.Lcd.print("Not Connected");
    return;
  }
  String query = String("message=") + msg;
  String request = String("") +
               "POST /api/notify HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Authorization: Bearer " + token + "\r\n" +
               "Content-Length: " + String(query.length()) +  "\r\n" + 
               "Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
                query + "\r\n";
  client.print(request);
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      break;
    }
  }
  
  delay(2000);
}

気象データを計測してみよう

プログラムを書き込むとさっそくLINEで温度・湿度・気圧データが送られてきます。

ほったらかしにして待っていると、数分の誤差はあるものの3時間毎に温度・湿度・気温データがLINEで送られてきました。

電源電圧の下がり方は3時間で0.1Vほどです。電源電圧4.17Vから始めたのですが12時間はバッテリーが持ちました。

まとめ

M5StickとENVⅢを使って3時間ごとに温度・湿度・気圧データをLINEでスマホへ送信するシステム構築の解説をしました。

家庭菜園や夏休みの宿題などで毎日の気象データを自動で管理出来ますね。

今回はM5StickC PLUSのバッテリー駆動のみで12時間しか持ちませんでした。屋外で使用するとなった場合、電源確保必要ですので、今後の課題にしたいと思います。

興味を持たれた方は是非実践してみて下さい。

最後までお読み頂きありがとうございました。

私はM5StickC PLUSとENV ⅢをAmazon(スイッチサイエンス)で購入しました。みんなのM5Stack入門を読んで勉強してます。