easiでM5Stackも遠隔操作しよう

# はじめに

https://qiita.com/1stship/items/29be69531d6f2c2b0ccc
などで紹介している簡単マイコン遠隔操作プログラムeasiですが、[Wio LTE JP Version](https://soracom.jp/products/module/wio_lte/)の対応に続いて、[M5Stack Basic 3G 拡張ボードセット](https://soracom.jp/products/kit/3g_module_m5stack_set/)にも対応させました。

M5 Stackはケースに収まっていて設置が楽、画面がついているので文字や画像の表示ができ、ちょっとしたアナウンスをするのに便利ですよね。遠隔で内容が変えられれば、状況に合わせて適切な表示をすることが容易にできます。ちょっとやってみましょう。

# 準備

**注意**
すでにSORACOM Inventoryを使用中の場合、以下を実行すると費用が発生します。(初期費用100円、利用料金50円)
未使用の場合は150円の無料枠に入ります。

---

事前準備として、

- M5Stack Basic 3G 拡張ボードセットを入手していること
- SORACOM AirのSIMを3G拡張ボードに入れていること
- Arduino IDEをインストールすること
- M5Stackのボード定義がインストールされていること
- USBドライバがインストールされていること

が必要です。

これはソラコムさんが詳しく説明してくれているので、[こちらの資料](https://dev.soracom.io/jp/start/m5stack/)をご覧ください。（六角レンチで3G拡張ボードいったん分解するのが結構面倒だった。。）

準備ができたら、GitHubのリポジトリのリリースページからeasiの最新のM5Stack用アーカイブをダウンロードしましょう。
リリースページ： https://github.com/1stship/easi/releases
2020/5/31時点の最新アーカイブ: https://github.com/1stship/easi/releases/download/V1.1.0/easi_m5stack_V1.1.0.zip

アーカイブを展開し、easi.inoをArduino IDEで開き、M5Stackに書き込みます。

![m5stack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/306e8a3f-f542-17f8-b689-fd33d5312d11.png)

書き込みが終わると自動的にリセットがかかり、M5Stackの画面に
「easi version V1.1.0 is ready to play!」
と表示されるまで待ちます。1分程度かかります。通信の確立に結構時間かかるみたいなんですよね。。

![display.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/f3d4369e-c345-1fa0-aaf9-a7e1eaff7224.jpeg)

準備ができたので、まずは定番の再起動を試してみましょう。SORACOMコンソールにログインして、SORACOM Inventoryのデバイス管理メニューに入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/fd92e4fb-24ed-fddf-6d2e-acd39942d24e.png)

デバイスを選択して、詳細をクリックします。
![inventoryconsole.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/b716d127-6e32-1d27-9c9a-978181d2e053.png)


Reboot /3/0/4を探して、実行ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/795ee1cc-5148-438a-d045-d812168d32f1.png)

「コマンド実行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/95410a17-7a87-dfd8-73b6-b11e70495545.png)

M5Stackが再起動したと思います。このように簡単にSORACOMのユーザーコンソール、もしくはWebAPI、CLIによって、M5Stackを遠隔操作できるようになります。

Wio LTEでのいくつかの使い方をブログに書きましたので、詳細はこちらをご覧ください。

https://qiita.com/1stship/items/29be69531d6f2c2b0ccc
https://qiita.com/1stship/items/32508303c72e017e4501
https://qiita.com/1stship/items/f5ef2bd57fde336beb01

# 実装例

せっかく画面があるので、こちらから送った文字を画面に表示させてみましょう。テキスト表示に使えそうなLwM2Mのオブジェクトを探します。

https://www.openmobilealliance.org/wp/omna/lwm2m/lwm2mregistry.html

を見ると、オブジェクトID:3341に「Addressable Text Display」というオブジェクトがあります。位置を指定してテキストを表示するためのもののようですね。

https://www.openmobilealliance.org/tech/profiles/lwm2m/3341.xml

このオブジェクトの中を見ると、リソースID:5527に「Text」というWriteオペレーションがあります。X座標やY座標などの指定もできますが、ひとまずテキスト表示だけ使います。コードを短くするため、関係ないリソースやコメントは取り除いています。

```c
#include "easi.h"

#define EASI_M5_STACK
#define EASI_VERSION "V1.1.0"

Lwm2m lwm2m;
#include <M5Stack.h>
#define TINY_GSM_MODEM_UBLOX
#include <TinyGsmClient.h>
TinyGsm modem(Serial2);

void setup() {
  // 初期化
  Serial.begin(115200);
  M5.begin();
  M5.Lcd.clear(BLACK);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.println(F("M5Stack + 3G Module"));

  M5.Lcd.print(F("Modem Initialize..."));
  Serial2.begin(115200, SERIAL_8N1, 16, 17);
  modem.restart();
  M5.Lcd.println(F("done"));

  M5.Lcd.print(F("Connecting 3G..."));
  while (!modem.waitForNetwork()) M5.Lcd.print(".");
  M5.Lcd.println(F("done"));

  M5.Lcd.print(F("Connecting SORACOM..."));
  modem.gprsConnect("soracom.io", "sora", "sora");
  M5.Lcd.println(F("done"));

  M5.Lcd.print(F("Checking Network..."));
  while (!modem.isNetworkConnected()) M5.Lcd.print(".");
  M5.Lcd.println(F("OK"));

  delay(2000);

  lwm2mInit(&lwm2m, "m5stack");
  udpInit(&lwm2m.bootstrapUdp, "bootstrap.soracom.io", 5683);
  
  addInstance(3341, 0);
  setWriteResourceOperation(3341, 0, 5527, displayText);

  M5.Lcd.println(F("LwM2M Bootstraping..."));
  while (!lwm2mBootstrap(&lwm2m)){ }
  M5.Lcd.println(F("OK"));
  M5.Lcd.println(F("easi version " EASI_VERSION " is ready to play!"));
}

void loop() {
  if (!lwm2mCheckEvent(&lwm2m)){
    delay(100);
  }
}

void displayText(Lwm2mTLV *tlv){
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setCursor(10, 90);
  M5.Lcd.setTextSize(7);
  M5.Lcd.println((char *)tlv->bytesValue);
};
```

StringリソースはbytesValueを通じて渡すようになってましたので、それをLCDにそのまま表示してみました。コンソールから「Hello!」を送ってみると。。

![Hello.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/7d729ab3-be66-8cce-74a7-caa867a4cf78.jpeg)

ちゃんと画面に表示されましたね。

また以下のような感じでCLIでもできます。デバイスIDは適当ですので、試す場合には実際に使用するデバイスIDを入れてください。

```bash
soracom devices put-resource --device-id 'd-01234567890123456789' --object 3341 --instance 0 --resource 5527 --body '{"value":"M5Stack"}'
```

連続して色々文字を送って、画面変わる様子を動画にしてTwitterに上げておきました。

https://twitter.com/1st_ship/status/1267061346345971713

だいたいCLIの実行から1秒程度の遅延でM5Stackに届くみたいです。このあたりはどこで実行するかとか、CLIではなく直接WebAPIを呼び出すとか、どのくらいの間隔でマイコンが受信チェックするか、とかで改善すると思いますが、まあ任意のコマンドを遠隔地に送信できるシステムとしてはなかなか良いんじゃ無いかと思います。

# おわりに

M5Stackはケースに入っていて扱いやすく、画面、スピーカーなどがそのまま使えるので、IoTの可能性を色々試してみるのはとてもいいデバイスだと思います。遠隔操作ができるようになるとさらに可能性が広がると思いますので、M5Stack Basic 3G 拡張ボードセットをお持ちの方はぜひ[簡単マイコン遠隔操作プログラムeasi](https://github.com/1stship/easi)を試していただければと思います。