🎉

M5UnitV2の検出結果をAmbientに送信するメモ

4 min read

はじめに

M5UnitV2流行ってますね。
私も手に入れたので、検出結果をAmbientに送信するまでの手順をメモします。

完成したコードはこちら。

https://github.com/tmitsuoka0423/m5unitv2-m5stickc-ambient

セットアップ

先駆者の記事を参考に進めていく。

https://qiita.com/airpocket/items/e6f736e539e18a314ae2
  • ドライバをダウンロードする
    • ドライバがRARファイルで提供されているので、7-zipを利用して解凍
  • デバイスマネージャ > ほかのデバイス > USB 10/100 LAN にドライバを追加する

無事認識。

Image from Gyazo

プリインストール済みの機能で遊ぶ

M5UnitV2をパソコンに接続した状態で、http://10.254.239.1/ にアクセスするとプリインストール済みの機能が使えます。

Image from Gyazo

いろいろ用意されていて、これを使って遊ぶだけでも結構楽しめる。

検出結果をAmbientに送信する

https://qiita.com/airpocket/items/e6f736e539e18a314ae2#8serial出力読み込み

上記の記事によると、

UnitV2のbuilt-in recognition functionの内、Camera StreamとAudio FFT以外の機能は、検出結果を問答無用でシリアル出力しています。データgrove端子を通じてUARTで出力されていますので、これを読み取れば外部の装置で検出結果を利用できます。

とのことなので、一旦、UnitV2 --> M5StickC --> Ambientという経路で送信することにします。

UnitV2上から直接curlとかでAmbientのAPIを叩くこともできそうですが、それは別途調査します。

M5UnitV2とM5StickCを接続する

手元にあったGroveケーブルで接続。

Image from Gyazo

UnitV2の出力をM5StickCで読み取る

M5StickCに以下のコードを書き込みます。

#include <M5StickC.h>

void setup() {
  M5.begin();

  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 33, 32);
}

void loop(){
  if(Serial2.available()) {
    String receiveString = Serial2.readStringUntil('\n');
    if(receiveString[0] == '{'){
      Serial.println(receiveString);
    }
  }
}

Face Detectorを起動すると、以下のようなJSONの出力を取得できました。

Image from Gyazo

形を整えるとこんな内容。

{
  "num": 1,
  "face": [
    {
      "x": 26.47280502,
      "y": 333.1088257,
      "w": 125.7219543,
      "h": 144.8911743,
      "prob": 0.997483611,
      "mark": [
        {
          "x": 42,
          "y": 380
        },
        {
          "x": 86,
          "y": 378
        },
        {
          "x": 48,
          "y": 404
        },
        {
          "x": 52,
          "y": 442
        },
        {
          "x": 84,
          "y": 440
        }
      ]
    }
  ],
  "running": "Face Detector"
}

JSONをデシリアライズ

UnitV2の出力がJSONなので、M5StickC上でデシリアライズして、必要なデータを取り出します。

今回は、ArduinoJsonライブラリを利用します。

【M5StickC Plus/Arduino】Arduinoでjsonを扱うを参考にさせていただきました。
ライブラリのインストール手順はこちらを参照ください。

#include <M5StickC.h>
#include <ArduinoJson.h>

DynamicJsonDocument doc(1024);

void setup()
{
  M5.begin();

  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 33, 32);
}

void loop()
{
  if (Serial2.available())
  {
    String receiveString = Serial2.readStringUntil('\n');

    // JSONをデシリアライズ
    deserializeJson(doc, receiveString);

    // こんな感じで中身を取り出せる
    double x = doc["face"][0]["x"];
    Serial.println(x);
  }
}

Ambientに送信する

先程のコードにAmbientへの送信処理を追加して完成です。

Ambientライブラリを利用するので、以下の手順に従ってインストールしてください。

https://ambidata.io/docs/esp8266/#library_import
#include <M5StickC.h>
#include <ArduinoJson.h>
#include <Ambient.h>
#include <WiFi.h>

WiFiClient client;
const char *ssid = "SSID";
const char *password = "PASSWORD";

Ambient ambient;
unsigned int channelId = 10000; // CHANNEL ID
const char *writeKey = "WRITE KEY";

int lastSendTime = 0;

DynamicJsonDocument doc(1024);

void setup()
{
  M5.begin();

  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 33, 32);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {}
}

void loop()
{
  if (Serial2.available())
  {
    String receiveString = Serial2.readStringUntil('\n');

    // JSONをデシリアライズ
    deserializeJson(doc, receiveString);

    // こんな感じで中身を取り出せる
    double x = doc["face"][0]["x"];
    Serial.println(x);

    // 一定間隔でAmbientに送信
    if (millis() - lastSendTime > 60000)
    {
      ambient.begin(channelId, writeKey, &client);
      ambient.set(1, x);
      ambient.send();

      lastSendTime = millis();
    }
  }
}

まとめ

M5UnitV2の検出結果をM5StickCからAmbientに送信する方法を紹介しました。
もっと良い方法を知ってる方は教えて下さい~。