M5Stack（マイコン）で湿度・気温・気圧データ取得してAmbientに送ってみた

:::note warn

本記事は2020年06月16日に弊社技術ブログで書かれたものの移植記事です。古い情報が書かれている可能性があります。

:::

　本記事では、M5GO（マイコン）に同封されている、ENV SENSOR（湿度・気温・気圧センサ）から得たデータをUiFlow環境を使ってMicroPythonでAmbientに送信し、グラフ化して実際に見てみる所までを扱います。


# Ambient での作業
> AmbientはIoTデーターの可視化サービスです。マイコンなどから送られるセンサーデーターを受信し、蓄積し、可視化(グラフ化)します。

https://ambidata.io/

　M5stackやラズパイなどのマイコンからセンサーデータをAmbientに送信すると、Ambient側で数値を折れ線グラフや棒グラフ、さらにマイコンの稼働状況までグラフにしてくれます。Ambient公式の<font color="orange">「Ambientを使ってみる」</font>ページを参考にして、新規登録からグラフの出力までやってみましょう！

https://ambidata.io/docs/gettingstarted/


## Ambientのユーザー登録

　Ambient公式ページ右上のユーザー登録（無料）ボタンから、ユーザー登録画面に遷移します。上からメールアドレス、任意のパスワードを入力します。入力出来たら、画面中央にある「ユーザー登録（無料）」を選択して、入力したメールアドレスにユーザー登録確認メールが来るのを待ちましょう。

https://ambidata.io/usr/signup.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/a7e212eb-5eec-2102-2150-42f7e496a4d3.png)

　届くメールはこんな感じです。「以下のURLにアクセスしていただくと登録が完了します。」とのことなので、URLにアクセスして登録を完了してしまいましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/89bf77c8-c53a-7a57-be83-239aeac370a0.png)

　登録が完了したら、早速ログインしてみましょう！メールアドレスとパスワードを入れてログインをクリックしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/315aed8f-7fd3-d500-a94a-6936697f0a0a.png)

## チャネル生成

　ログインすると、Myチャネルに遷移します。Myチャネルでは、個人が作ったチャネルを確認できます。私のMyチャネルではブログ用チャネルとチャネル00001が確認できますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/660f3474-a4f2-3d35-34e5-06a7dfc6f47f.png)

　画面左下、青いボタンの「チャネルを作る」をクリックすると、新しいチャネルが生成されます。データを貯めるために、チャネルを作成しておきましょう。「チャネル*****」が作成されたら成功です。おあつらえ向きにチャネル名が「ブログ用」になっているものがありますので、このチャネルを本記事で使っていきます。取り敢えずマイコンからデータの送信に必要なのは、<font color="orange">［チャネルID］［ライトキー］</font>です。

# マイコン（M5stack）側でのプログラミング

　データの保存先を登録出来たところで、マイコン側でのプログラミングに入っていきます。今回はUIFlow（ドラッグアンドドロップで完結するブロック型プログラミングソフト）を使って実装していきましょう。

https://flow.m5stack.com/

> UIFlow（Blockly）でAmbientにデータを送るブロックを作りました。使い方を説明します。例題として、M5StickCとENV Hatで温度、湿度、気圧を測り、Ambientに送り、データを可視化します。

　調べてみたらなんか利用しやすそうなブロックがAmbient公式から発表されてる！Ambient公式ページ「UIFlow（Blockly）でAmbientにデータを送る」を参考に、Blocklyでのプログラミングを始めてみましょう。

https://ambidata.io/samples/m5stack/uiflow/

## Ambientブロックのダウンロード

　AmbientのGithubページから、Clone or downloadでZIPファイルをダウンロード（Download ZIP）するかDesktopに展開（Open in Desktop）します。

https://github.com/AmbientDataInc/UIFlow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/5ad9c950-129d-5c9b-c95b-bbee9be9adef.png)

　ダウンロードしたファイルを、UiFlowにロードします。**【Custom（Beta）】タブから、《Open *.m5b file》をクリックして、srcファイルの中のambient.m5bを選択**しましょう。
すると【Custom（Beta）】タブの下に<font color="orange">【ambient】タブ</font>が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/972768d0-0e59-34e0-fc30-b404c6219b97.png)

待ちに待ったプログラミング開始です！

## ENV SENSOR でデータ取得

　今回、使いたいセンサーは、ENV SENSOR なので、UiFlow画面の左下にあるUnitsの［＋］を押して、ENVのセンサーにチェックを入れましょう。センサーそのままの画像でも表示されているので、ぱっと見で分かりやすいですね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/579bf0bd-d55a-24e8-ec44-7a965ebfa808.png)

　画面左下のUnitsの欄にENVセンサーが表示されました。画面中央のUnitsの下の【環境】タブをクリックしてみます。《env0の気圧[hPa]》《env0の温度[℃]》《env0の湿度[%]》の３種類が測れそうですね。今回は、気圧・気温・湿度の３つ全てをセンサーで取得してみましょう！それぞれのブロックを環境タブから取り出しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/551cb522-e784-b0f0-c39e-d5e97501a979.png)

　後々の利便性を考えて、変数に気圧・気温・湿度を格納してみましょう。画面中央の【変数】タブを開き、《変数の作成…》から《pressure》、《temp》、《humid》をそれぞれ作成します。同じ【変数】タブから取り出したブロックに、上記で置いておいたブロックを組み合わせます。《pressureをenv0の気圧[hPa]にする》、《tempをenv0の気温[℃]にする》、《humidをenv0の湿度[%]にする》になるように配置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/2576df80-e436-7223-9826-424df5afef18.png)

　送信するリアルタイムの気圧・気温・湿度をM5stackの画面上で確認できるように、左上のLabelからM5stackの画面にラベルをドラッグアンドドロップしておきましょう。すると、画面中央の【UI】タブ以下に【ラベル】タブが増えていると思います。《ラベルlavel0に　を表示》の中に作った変数のtemp、pressure、humidを順に入れていきます。これらのラベル表示は、常時更新してほしい情報なので、【イベント】タブの中にある《ずっと》ブロックの中に入れておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/679a540c-5dfe-b13b-eaa6-79a47549e301.png)

## Ambientにデータ送信

やっと《ambient》ブロックの登場です！M5stackが起動している間データを測っていて欲しいので、《ラベル》ブロックの下部かつ《ずっと》ブロックの間に配置しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/d4e40fcf-8ff1-fc3d-89a9-75e8e89d9502.png)

　次に、送り先のチャネルIDとライトキーを《ambient》ブロックに入力しましょう。

<font color="orange">**channelId［自分のチャネルID］writeKey［'チャネルのライトキー'］**</font>

　私の「ブログ用」チャネルのチャネルIDは00000、ライトキーはbbbbbbbbbbbbbbbbbbbbでした。ここで一点注意があります！ライトキーを入力する時、<font color="orange">**ライトキーを「‘ ‘」で囲うことを忘れないように**</font>してください。見落としやすいポイントですが、しっかりエラーが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/0a96a748-8729-290a-cb88-6ffbfb74b28d.png)

　Ambientのチャネルに送るためのデータを用意します。Ambientは、１つのチャネルに “d1″～”d8″まで数値を送ることが出来ます。また、Ambientに数値を送るためには、key-value関係に整えなければなりません。d1では温度を送るよ、d2では気圧を送るよ、と指定してやる必要があります。

　それをやってくれるブロックが、画面中央の【Map】タブの中の《マップを作成》ブロックです。このままでは、key-valueを入力する所がありません。そこで、《マップを作成》ブロックの右下＋をクリックします。マップの中に《key　value　》というブロックが出来ました！
 
　そのブロックに、【テキスト】タブから空のブロックを取り出し、d1, d2, d3を入力してマップの中身のkeyの後に詰め込みます。【変数】タブから、temp, pressure, humidの変数を同じようにvalueの後に詰め込みましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/7bb46c40-eeca-4ee6-8cb7-159401625ee4.png)

　このままAmbientに毎秒データを送信しましょう！Ambient公式から制限が提示されてる！今回引っ掛かりそうな制限は、この２つくらいでしょうか。

>・送信から次の送信まではチャネルごとに最低5秒空ける必要があります。それより短い間隔で送信したものは無視されます。
・1チャネルあたり1日3,000件までデーターを登録できます。平均すると28.8秒に1回のペースです。

https://ambidata.io/refs/spec/

　毎秒データを送信することは出来なさそうです。（毎秒気象データを取る必要ないとは思いますが）

　Ambient公式の制限に則るためにも、データを取得し、送信する間隔を空けましょう。画面中央の【タイマー】タブから《　秒停止》のブロックを《ずっと》ブロックの最後に組み込みましょう。キリが良いので、私は1分間隔で環境データの取得と送信を行っています。この間隔はお好みで入力してください。入力されるのは一時停止秒数ということをお忘れなく！一時間ごとにデータの送信を行いたい場合、入力する数は3600です！

　UiFlow右上のRUNボタンから実行してみましょう！エラーメッセージが出た場合、もしくはAmbientにデータが送信されていない場合などは、UiFlowの設定からAPI Keyが誤っていないか、M5stackがUSB Modeになっていないか確認してみてください。

## Ambientで結果をグラフ化
　恐らくデータがAmbientに送信され始めたと思います。左側の【＋📊】ボタンから表示したいチャートの設定を行いましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/85e21bb2-7adf-a734-67e7-1c2c3d937365.png)

　気温のグラフ（d1で送信したもの）を表示してみましょう！グラフ名を入力し、d1の縦軸の設定を行います。チャートの左側、右側どちらにラベルを表示するかを選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/0a935edc-acea-5a3b-00e5-627fa6a286aa.png)

　気圧・湿度も同様、表示するように設定しました。チャート上部の300の数字は、300件のデータを折れ線グラフで表示していることを指します。用途に合った、表示件数に合わせて表示件数の増減が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/db1f52a8-3d48-2af7-7495-354b79975207.png)

## CSVファイルの出力

　さらに、Ambientは受け取ったデータをただ表示するだけではありません！送信したデータを、csv形式で自分のPCにダウンロードすることも出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/87fdc960-fbdf-df31-417a-1785661ffc50.png)

　ダウンロードできるcsvファイルの中身は下の画像のように、左からcreated（データが送信された時間）、d1、d2、d3…と続きます。成形されたデータなので、機械学習用にcsvファイルが欲しい！という方にもAmbientはおススメなのです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597915/f493c829-f367-cb2b-6515-ae90d2ed774c.png)

## （補足）Pythonコード
　ブロックエディタよりPythonコードの方が分かりやすい！という方（私も）向けに、サンプルコードを以下に表示しました。UiFlowの【< / >Python】エディタにペーストもしくは直打ちしてRUNでプログラムの実行ができます。その場合、ambientSend以下の「チャネルID」を自分で使用したいチャネルのチャネルID、「ライトキー」にチャネルのライトキーを入力してくださいね。

```python
from m5stack import *
from m5ui import *
from uiflow import *
import unit

setScreenColor(0x222222)
env0 = unit.get(unit.ENV)

# ラベルの位置を指定
label0 = M5TextBox(125, 40, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
label1 = M5TextBox(125, 110, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
label2 = M5TextBox(125, 170, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)

# 変数にセンサーから受け取ったデータを格納
temp = env0.temperature
humid = env0.humidity
pressure = env0.pressure

# ずっとラベルにセンサーデータを表示＆Ambientに送信
while True:
  label0.setText(str(temp))
  label1.setText(str(humid))
  label2.setText(str(pressure))
  import urequests
  def ambientSend(_channelId, _writeKey, _data):
    if isinstance(_data, list):
      __d = _data
    else:
      __d = [_data]
    try:
      req = urequests.request(method='POST', url=((('http://ambidata.io/api/v2/channels/' + str(_channelId))) + '/dataarray'),json={'writeKey':_writeKey,'data':__d}, headers={'Content-Type':'application/json'})
      _ret = True
    except:
      _ret = False
    return _ret

# 自分のチャネルID,ライトキーで認証
  ambientSend(チャネルID, 'ライトキー', {'d1':temp,'d2':humid,'d3':pressure})

# Ambientにデータ送信する間隔
  wait(60)
  wait_ms(2)
  ```

  # まとめ

　UiFlowを使って簡単なBlockly（MicroPython）プログラミングに挑戦してみました。M5stackから送信されたデータをPCで可視化できたのはちょっと達成感があります。当方偏頭痛持ちなので、頭痛が始まった時には見事気圧が下がってた、なんてこともリアルタイムで目視できました。

　また、Ambientに保存したデータをそのまま機械学習等に使いたいという場合、公式がAmbientライブラリーも提供してくれていますので、そちらもご覧ください。

https://ambidata.io/samples/dataprocess/pythonpandas/