1. menmenshod

    No comment

    menmenshod
Changes in body
Source | HTML | Preview

はじめに

祝!2019年初投稿!:flag_jp:
今回は、去年頃から話題になりつつあるM5Stackマイコンについて書こうと思います。M5Stack始めてみたいけど、ネット上で情報が少なすぎてどうしたらいいか分からないっていう方必見です。M5Stackに触れて5日ほどしか経ってませんので、以下記事でおかしい点ありましたらご指摘よろしくお願いします。

  • プロフィール

    • 学生webエンジニア(Ruby on Rails)
    • 趣味でマイコンをちょくちょく弄ってた経験あり
  • 対象読者

    • M5stackでセンサリングしたい
    • M5stackで何か表示したい
    • センサリングしたデータをネット上で確認したい
    • M5stackからwebhookしてLINEやslackに通知したい

M5Stackとは

ESP32がベースとなった、ディスプレイ・バッテリー・ボタン・スピーカー・WiFiアンテナ・SDカードスロットなどひっくるめて一つになったマイコン。Arduino IDE での開発ができ、M5Cloudというpythonで描けるクラウド型開発環境もあるらしい

使うもの

開発環境

macOS High Sierra
本記事ではmacを使用することを前提にしますが、windowsでもさほど手順は変わらないはずです。
以下の記事を参考にしてArduino IDEの導入をしました。
https://qiita.com/hmmrjn/items/2b2da09eecffcbdbad85

作るもの

具体的な目標物を決めます。
今回は、日々の犬の散歩ルートの時系列位置情報を取得し、ambientを用いてGooglemap上に記された地図データを保存し、そのURLをLINEで通知するというものを作る。

作成手順

作成手順は順を追って三つに分けます

  1. M5stackがGPS信号を受信出来ているかチェックする。
  2. M5stackがambientにGPSデータを送信する。
  3. M5stackからLINEに通知を送る。

1. M5stackがGPS信号を受信出来ているかチェックする

まず以下の写真のようにM5StackとGPSモジュールが積まれてアンテナが伸びているか確認する IMG_0104.JPG
Arduino IDEを開いて、以下のスケッチ例を開いて書き込む。
これだけ!
スクリーンショット 2019-01-03 1.43.45.png
シリアルモニタを開いて
スクリーンショット 2019-01-03 1.46.45.png
GPSの生データが取得出来ていればOK
信号が来なかったり、,,,,,,,99,99,99 こんな感じだったら取得できていませんorz
マイコンの接続、アンテナを再確認してください。

2. M5stackからambientにGPSデータを送信する

webでの設定

ambient(https://ambidata.io/)
でユーザー登録してログインしておく
「チャネルを作る」から作成されたチャネルの、チャネルID・リードキー・ライトキーを控えておく。チャネルに入り、チャートを追加して地図グラフを作っておく。ここのチャートの項目についてはまだ詳しくないのですが、一つのチャネルで他8つのデータが管理できるようです。公開チャネルにするか非公開チャネルにするかは自由で。LINEで共有する場合は公開にしましょう。
スクリーンショット 2019-01-03 1.59.48.png

Arduino IDE

プログラムは以下のサイトを参考にして一部改変しています。
https://ambidata.io/samples/m5stack/m5stack_pulse_gps/
リンク先でも記されているように、GPS生データを緯度・経度の扱いやすいデータに変換するために、TinyGPS++ライブラリを使うことを推奨します。リンク先のzipファイルをダウンロードして下写真のようにzip形式のライブラリをインクルードしときましょう。
スクリーンショット 2019-01-03 12.43.16.png
以下にプログラムを記します。コメントで説明書きしています。(間違ってるかも!?ご指摘ください)


#include <M5Stack.h>  //M5stack使うよ
#include <TinyGPS++.h>  //GPS生データをうまいこと処理してくれるライブラリ使うよ
#include "Ambient.h"  //Ambient使うよ

HardwareSerial GPS_s(2);  //GPSの信号端子

TinyGPSPlus gps;  //GPSデータのインスタンス的な
WiFiClient client;  //WiFi接続に関するインスタンス的な
Ambient ambient;  //Ambientのインスタンス的な

const char* ssid = "xxxxxxxx";
const char* password = "xxxxxxxxx";
unsigned int channelId = xxxx; // AmbientのチャネルIDを入力
const char* writeKey = "xxxxxxxxxxxxxxx"; // ライトキーを入力
const char* userKey = "xxxxxxxxxxxxxxx"; //ユーザーキーを入力

void setup 内で必要な処理は

  • wifi接続確認
  • Ambientの初期化
void setup() {
    M5.begin();

    WiFi.begin(ssid, password);  // Wi-Fi接続
    while (WiFi.status() != WL_CONNECTED) {  // Wi-Fi 接続待ち
        delay(100);
        M5.Lcd.printf(".");
    }
    M5.Lcd.println("\nwifi connect ok");

    ambient.begin(channelId, writeKey, &client); // チャネルIDとライトキーを指定してAmbientの初期化
}

最低限setup内はこれがあれば大丈夫でしょう。
しかしWifiの接続が速い時もあれば、かなり待つ時もあるのは仕様でしょうか。。。
void loop 内は以下のようにしました。定数の値は適当に定めてください。

  • 緯度・経度のデータをambientに飛ばす

がメインの処理になります。ボタンAを押すとGPSデータが記録されます。


void loop() {
    M5.update();
    if(M5.BtnA.wasPressed()) {
        M5.Lcd.println("Chase start!!");
        while(1){
           delay(REDRAW);
           if (++loopcount > PERIOD * 1000 / REDRAW) {
              char buf[16];

              loopcount = 0;

              while (!gps.location.isUpdated()) {
                  while (GPS_s.available() > 0) {
                      if (gps.encode(GPS_s.read())) {
                          break;
                      }
                      delay(0);
                  }
              }
              M5.Lcd.printf("lat: %5.2f, lng: %5.2f\r\n", gps.location.lat(), gps.location.lng());
              dtostrf(gps.location.lat(), 12, 8, buf);
              ambient.set(9, buf);
              dtostrf(gps.location.lng(), 12, 8, buf);
              ambient.set(10, buf);
              ambient.send();
           }  
        }
    }
}

ambientチャネル内に地図が表示され現在地がポイントされていたら成功です。

3.M5stackからLINEに通知を送る

さて、散歩ルートの時系列位置データが記録できたので、今度はそのambientチャネルのリンクをLINEで共有して通知できるようにしましょう。
二つの方法があります。

  • IFTTTを使いwebhookシステムを使ってLINEに通知させる
  • LINE Notifyを使い直接URLを叩く

前者だと1:1の通信(自分とのチャットなど)しかできないようです。今回は家族LINEのようなグループチャット内で通知させることを考えているので、後者のやり方を説明します。前者のやり方は以下のサイトが大変参考になります。:pray:
https://thousandiy.wordpress.com/2017/10/17/esp32_ifttt_line/
(もし、IFTTTを使ったグループチャットへの通知ができる場合はぜひ教えてください:relaxed:)

LINE Notifyを使い直接URLを叩く

webでの設定

LINE Notifyにアクセスし、ログインしてマイページにいきます。
スクリーンショット 2019-01-03 13.15.01.png
通知するトークルームを選択して、トークンを発行し控えます。
以上です!

Arduino IDE

GPSデータは上述の方法で取得できていると思うので、肝心のLINE NotifyのURLの叩き方(パラメータ付与したPOSTリクエスト)を記述します。
HTTPClient.hをインクルードしておきます。send関数なんか作っておいて引数に送りたい文字列を指定して、messageパラメータにその文字列を代入します。urlの後ろに?でパラメータを指定できます。リクエストヘッダに以下のように先ほど控えたトークンを記すのを忘れないようにしましょう。
httpResponseCodeにステータスコードを格納しておけばエラー処理ができます。

#include <HTTPClient.h>

void send(String value1) {
    //略(大事なとこだけ)
    HTTPClient http;
    http.begin("https://notify-api.line.me/api/notify?message=" + value1);
    http.addHeader("Authorization", "Bearer XXxxxXXXxxxxxxXXXXXXXxxxX");  //リクエストヘッダに先ほど控えたトークンをセット
    int httpResponseCode = http.POST("POSTING from M5stack");
}

余談ですけど、SSL化されたページ(https)へのリクエストなのにSSL証明書の確認はいらないんですかね...?slackの時は証明書発行したような。。。(ここらへん素人なので全然わかりません、教えてください!)

さて、メインの処理でこのsend関数を呼び出してあげればOKです!今回はサンプリングしたGPSデータから距離(m)を算出し送るようにしてます。ambientチャネルのURLも送ります。
最後に電源OFF!

void loop() {
  //略
  if (M5.BtnB.wasPressed()){
    M5.Lcd.println("finish walking!!");
    send(String(distance) + "m");  //散歩距離(GPSから算出した)
    send("https://ambidata.io/ch/channel.html?id=xxxx&private=true");  //idはチャネルID
    M5.powerOFF();  //電源OFF
  }
}

指定したLINEトークルームに通知が来ていれば成功!

実際に運用してみる

実際に試す前に、完成したシステムの全様を以下の動画にまとめましたのでご覧ください。
https://youtu.be/Skmwk9skz34
IMAGE ALT TEXT HERE

犬と散歩してみる

犬も不安そうな表情で見つめてきます:rolling_eyes:
kinakinasampo.JPG
ちゃんととれてるうううぅ!!
スクリーンショット 2019-01-01 16.41.18.jpg
LINEの通知はこんな感じです(これは別日にシステムテスト時に撮ったものですが)
IMG_1646.PNG

おわりに

M5Stackの入門、できましたでしょうか!?
この記事を見て、一人でも参考になったという方がいたら幸いです。
全コード参考にしたいという方はTwitter,Facebookまでご連絡ください。

追記

全コードを参考にしたい方向けに、youtubeのコメント欄に本プロジェクトのリポジトリを載せました:point_up: