M5stickcとNode-REDで呼び出しボタンを作る


先週末のMakerFaireTokyo2020、東京に見に行くことはできませんでしたがTwitterのハッシュタグをから@motomsの[お菓子配りロボット](https://twitter.com/motomi0509/status/1311982674458759169)に行きつき、
qiita記事よりステッピングモーターを使っていることを見て、私もステッピングモーターを動かしてみたくなりました。
ですが、うまく回すことができず・・・

急遽方針を替え、先週[スイッチサイエンス](https://www.switch-science.com/catalog/6470/)さんに再入荷した[M5StickC Plus](https://www.switch-science.com/catalog/6470/)購入しました。なので今回はMQTTを利用して呼び出しに使えそうなシステムを構築していきます。

今回の記事は@1ft-seabassさんの記事を参考に作りました。ありがとうございます！


>[M5StackとNode-REDをMQTTで連携するメモ](https://www.1ft-seabass.jp/memo/2018/05/10/m5stack-meets-nodered-with-mqtt/)


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">M5stickcとNode-REDをMQTTで連携しました。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a>　<a href="https://twitter.com/hashtag/M5Stack?src=hash&amp;ref_src=twsrc%5Etfw">#M5Stack</a> 　<a href="https://twitter.com/hashtag/NodeRED?src=hash&amp;ref_src=twsrc%5Etfw">#NodeRED</a><a href="https://t.co/lW2PyHrh3t">https://t.co/lW2PyHrh3t</a> <a href="https://t.co/VYx71p0elR">pic.twitter.com/VYx71p0elR</a></p>&mdash; Toshiki (@Hirasawa1987) <a href="https://twitter.com/Hirasawa1987/status/1314214418163531776?ref_src=twsrc%5Etfw">October 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

プログラムは **Arduino IDE** を使って書きます．


##使用したもの

M5StickC Plus

ESP32内蔵．Bluetooth 4.0とWi-Fi．6軸(ジャイロ・加速度)センサ. 赤色LED. 1.14 インチ 135x 240 LCDなどが付いていて**2,200円**で買うことができます。安い・・・

![b8077191-3a52-4799-890a-514788b7f85c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/ca0b553f-524b-8f7a-dfd7-18b7bcfff981.jpeg)

##開発環境
arduino-1.8.13

##ライブラリ

以下のライブラリをで躓きました、現在の最新バージョンは6.16.1になっており書き方が変わっている模様、チャレンジしてみましたが解けずにバージョンを5に下げて再度インストールしました。

>ArduinoJson　5.13.5

[![Image from Gyazo](https://i.gyazo.com/b38c8f61469c5a153414a06af3da1f82.png)](https://gyazo.com/b38c8f61469c5a153414a06af3da1f82)

##コード

```c 
#include <M5StickCPlus.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <WiFi.h>
//#include <M5Stack.h>
#include <ArduinoJson.h>
 
// Wi-FiのSSID
char *ssid = "";
// Wi-Fiのパスワード
char *password = "";

// MQTTの接続先のIP
const char *endpoint = "";
// MQTTのポート
const int port = 1883;
// デバイスID
char *deviceID = "M5Stack";  // デバイスIDは機器ごとにユニークにします
// メッセージを知らせるトピック
char *pubTopic = "/pub/M5Stack";
// メッセージを待つトピック
char *subTopic = "/sub/M5Stack";
 
////////////////////////////////////////////////////////////////////////////////
   
WiFiClient httpsClient;
PubSubClient mqttClient(httpsClient);
   
void setup() {
    Serial.begin(115200);
     
    // Initialize the M5Stack object
    M5.begin();
 
    // START
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setCursor(10, 10);
    M5.Lcd.setTextColor(WHITE);
    M5.Lcd.setTextSize(3);
    M5.Lcd.printf("START");
     
    // Start WiFi
    Serial.println("Connecting to ");
    Serial.print(ssid);
    WiFi.begin(ssid, password);
   
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
 
    // WiFi Connected
    Serial.println("\nWiFi Connected.");
    M5.Lcd.setCursor(10, 40);
    M5.Lcd.setTextColor(WHITE);
    M5.Lcd.setTextSize(3);
    M5.Lcd.printf("WiFi Connected.");
     
    mqttClient.setServer(endpoint, port);
    mqttClient.setCallback(mqttCallback);
   
    connectMQTT();
}
   
void connectMQTT() {
    while (!mqttClient.connected()) {
        if (mqttClient.connect(deviceID)) {
            Serial.println("Connected.");
            int qos = 0;
            mqttClient.subscribe(subTopic, qos);
            Serial.println("Subscribed.");
        } else {
            Serial.print("Failed. Error state=");
            Serial.print(mqttClient.state());
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}
   
long messageSentAt = 0;
int count = 0;
char pubMessage[128];
int led,red,green,blue;
   
void mqttCallback (char* topic, byte* payload, unsigned int length) {
 
    String str = "";
    Serial.print("Received. topic=");
    Serial.println(topic);
    for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
        str += (char)payload[i];
    }
    Serial.print("\n");
 
//    StaticJsonDocument<200> jsonBuffer;
    StaticJsonBuffer<200> jsonBuffer;
//    deserializeJson(root, str);
    JsonObject& root = jsonBuffer.parseObject(str);
   
    // パースが成功したか確認。できなきゃ終了
    if (!root.success()) {
      Serial.println("parseObject() failed");
      return;
    }
    // JSONデータを割りあて
    const char* message = root["message"];
    led = root["led"];
    red = root["r"];
    green = root["g"];
    blue = root["b"];
 
    Serial.print("red = ");
    Serial.print(red);
    Serial.print(" green = ");
    Serial.println(green);
    Serial.print(" blue = ");
    Serial.println(blue);
 
    if( led == 1 ){
      // RGBカラー uint16_t に変換
      // uint16_t RGB = red << 11 | green << 5 | blue;
      uint16_t RGB = ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);
      // 背景カラー反映
      M5.Lcd.fillRect(0, 0, 320, 240, RGB);
      // テキスト反映
      M5.Lcd.setCursor(10, 120);
      M5.Lcd.setTextColor(WHITE);
      M5.Lcd.setTextSize(5);
      M5.Lcd.printf(message);
    } else {
      // 消灯
      M5.Lcd.fillScreen(BLACK);
    }
 
    delay(300);
     
}
  
void mqttLoop() {
    if (!mqttClient.connected()) {
        connectMQTT();
    }
    mqttClient.loop();
}
 
void loop() {
 
  // 常にチェックして切断されたら復帰できるように
  mqttLoop();
 
  // 5秒ごとにメッセージを飛ばす
  long now = millis();
  if (now - messageSentAt > 5000) {
      messageSentAt = now;
      sprintf(pubMessage, "{\"count\": %d}", count++);
      Serial.print("Publishing message to topic ");
      Serial.println(pubTopic);
      Serial.println(pubMessage);
      mqttClient.publish(pubTopic, pubMessage);
      Serial.println("Published.");
  }
}
```


#M5StickCPlusのライブラリがない

```
#include <M5StickCPlus.h>
```
上記のライブラリはそのまま読み込むとエラーになります。**Arduino IDE**にライブラリはなく[M5StickC-Plus](https://github.com/m5stack/M5StickC-Plus)からダウンロードして**Arduino IDE**のあるフォルダのarduino-1.8.13\librariesにダウンロードした`M5StickC-Plus-master`をそのまま入れることで動くようになります。

#Node-REDでボタンを作る
今回はNode-REDについての説明は省きます。
こんな感じ
![IMG_1379.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/b53e99a9-4be0-c31e-7787-9c9ea9659521.png)
![b6b38633b11f73256e54b95e872404e6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/3b87cf3e-558c-162e-99dc-033cea93473e.png)


```
[{"id":"bd5d98b0.ea3798","type":"mosca in","z":"b9127b1e.46bcf8","mqtt_port":1883,"mqtt_ws_port":8080,"name":"","username":"","password":"","dburl":"","x":190,"y":200,"wires":[["2a1722bd.4c329e"]]},{"id":"c971a4cd.862768","type":"comment","z":"b9127b1e.46bcf8","name":"MQTTブローカー","info":"","x":180,"y":160,"wires":[]},{"id":"2a1722bd.4c329e","type":"debug","z":"b9127b1e.46bcf8","name":"","active":false,"console":"false","complete":"payload","x":432,"y":199,"wires":[]},{"id":"32e6c56c.7b3bfa","type":"mqtt out","z":"b9127b1e.46bcf8","name":"","topic":"/sub/M5Stack","qos":"","retain":"","broker":"4a0d61bd.b18f2","x":620,"y":260,"wires":[]},{"id":"63e877b8.8cc848","type":"ui_button","z":"b9127b1e.46bcf8","name":"","group":"56ac95d6.615a4c","order":3,"width":"6","height":"1","passthru":false,"label":"青","tooltip":"","color":"","bgcolor":"blue","icon":"","payload":"{     \"led\": 1,     \"r\": 0,     \"g\": 0,     \"b\": 255,     \"message\": \"blue\" }","payloadType":"json","topic":"","x":210,"y":260,"wires":[["32e6c56c.7b3bfa"]]},{"id":"7b4d354.3be44cc","type":"ui_button","z":"b9127b1e.46bcf8","name":"","group":"56ac95d6.615a4c","order":3,"width":0,"height":0,"passthru":false,"label":"赤","tooltip":"","color":"","bgcolor":"red","icon":"","payload":"{\"led\":1,\"r\":255,\"g\":0,\"b\":0,\"message\":\"red\"}","payloadType":"json","topic":"","x":210,"y":300,"wires":[["32e6c56c.7b3bfa"]]},{"id":"f75be591.879748","type":"ui_button","z":"b9127b1e.46bcf8","name":"","group":"56ac95d6.615a4c","order":3,"width":0,"height":0,"passthru":false,"label":"ﾐﾄﾞﾘ","tooltip":"","color":"","bgcolor":"green","icon":"","payload":"{\"led\":1,\"r\":0,\"g\":255,\"b\":0,\"message\":\"green\"}","payloadType":"json","topic":"","x":210,"y":340,"wires":[["32e6c56c.7b3bfa"]]},{"id":"c923f183.eb3c5","type":"ui_button","z":"b9127b1e.46bcf8","name":"","group":"56ac95d6.615a4c","order":3,"width":0,"height":0,"passthru":false,"label":"off","tooltip":"","color":"","bgcolor":"black","icon":"","payload":"{\"led\":0,\"r\":0,\"g\":0,\"b\":0,\"message\":\"close\"}","payloadType":"json","topic":"","x":210,"y":380,"wires":[["32e6c56c.7b3bfa"]]},{"id":"4a0d61bd.b18f2","type":"mqtt-broker","z":"","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"56ac95d6.615a4c","type":"ui_group","z":"","name":"ウィザード","tab":"e0028a22.5c7e58","disp":false,"width":"6","collapse":false},{"id":"e0028a22.5c7e58","type":"ui_tab","z":"","name":"製造二課　TP通知","icon":"dashboard","order":18,"disabled":false,"hidden":false}]
```

#参考記事
[【IoT初級者へ】M5StickC ではじめる MQTT 通信](https://qiita.com/Rone_Loreto/items/6a8991e88c1a31cba924)

#終わりに
M5Stackシリーズはとにかく価格が安く、パーツも豊富なので、頭の中にアイデアをパパっと実現できると思います、プロトタイプを作るのにおすすめです！