E-textile Electric fabric “nüno” のデータをM5StackからMQTTでつないでNode-REDにつなげるメモ

E-textile Electric fabric “nüno” のデータをM5StackからMQTTでつないでNode-REDにつなげるメモです。

まずは動かす

今回 “nüno” をお借りして、早速動かさせていただきました。

tendots/nuno: Electric fabric touchpad "nüno"

こちらのソースコードを使って、M5Stackですぐに動かすことが出来ました。

Arduino的な動きですぐに可視化できるという点で、やはりM5Stackはとっつきやすいですね。

MQTTでデータを引き出してみる

さて、さらにM5StackであればMQTTでデータを引き出すこともスムーズです。MQTTブローカーは自分で立てたMQTTブローカーやテストで使いやすい shiftr.io であったり、Free MQTT service "Daily icecream" – mqtt.uko.jp など使ってみましょう。

Node-RED

image

Node-REDではシンプルにMQTTから /pub/M5Stack のデータを受け取ります。

[{"id":"abb92dd9.73c38","type":"mqtt in","z":"b9c386da.e1d858","name":"","topic":"/pub/M5Stack","qos":"2","broker":"f732bc1c.35538","x":550,"y":420,"wires":[["9ef73f26.e92d4"]]},{"id":"33005480.1dedfc","type":"debug","z":"b9c386da.e1d858","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":930,"y":420,"wires":[]},{"id":"9ef73f26.e92d4","type":"json","z":"b9c386da.e1d858","name":"","property":"payload","action":"","pretty":false,"x":750,"y":420,"wires":[["33005480.1dedfc"]]},{"id":"f732bc1c.35538","type":"mqtt-broker","z":"","name":"127.0.0.1","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]

M5Stack

M5Stackのソースコードはこちらです。nüno のTouchtest のソースを動かした状態でソースを以下で書き換える形です。

#include <M5Stack.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <WiFi.h>

#include <Arduino.h>
#include <Wire.h>
#include "MTCH6102.h"

#define ADDR 0x25

MTCH6102 mtch = MTCH6102();
int len = 8;

// Wi-FiのSSID
char *ssid = "Wi-FiのSSID";
// Wi-Fiのパスワード
char *password = "Wi-Fiのパスワード";
// MQTTブローカーのアドレス
const char *endpoint = "MQTTブローカーのアドレス";
// MQTTのポート
const int port = 1883;
// デバイスID
char *deviceID = "M5Stack";  // デバイスIDは機器ごとにユニークにします
// メッセージを知らせるトピック
char *pubTopic = "/pub/M5Stack";
// メッセージを待つトピック
char *subTopic = "/sub/M5Stack";

long messageSentAt = 0;
int count = 0;
char pubMessage[128];

WiFiClient httpsClient;
PubSubClient mqttClient(httpsClient);

void setup() {
 delay(1000);
 
 byte data;

  // Initialize the M5Stack object
  M5.begin();
  M5.Lcd.fillScreen(TFT_BLACK);

   //I2c.begin();
  
  Serial.begin(115200);

  // START
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(10, 10);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(3);
  M5.Lcd.printf("E-Textile");
  
  // 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.");

  // INFO
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(0, 100);
  M5.Lcd.printf("deviceID: ");
  M5.Lcd.println(deviceID);
  M5.Lcd.printf("sub: ");
  M5.Lcd.println(subTopic);
  M5.Lcd.printf("pub: ");
  M5.Lcd.println(pubTopic);
  
  mqttClient.setServer(endpoint, port);

  connectMQTT();

  M5.Lcd.fillScreen(TFT_BLACK);
  
  //Wire.begin();
  mtch.begin();
  mtch.writeRegister(MTCH6102_MODE, MTCH6102_MODE_STANDBY);
  mtch.writeRegister(MTCH6102_NUMBEROFXCHANNELS, 0x10 );
  mtch.writeRegister(MTCH6102_NUMBEROFYCHANNELS, 0x03);//最低3点必要なため
  mtch.writeRegister(MTCH6102_MODE, MTCH6102_MODE_FULL);
  
  mtch.writeRegister(MTCH6102_CMD, 0x20);
  delay(500);
  
  // the operating mode (MODE)
  data = mtch.readRegister(MTCH6102_MODE);
  Serial.print("MODE: ");
  Serial.println(data,BIN);

  // Set mode to Touch only
  //mtch.writeRegister(MTCH6102_MODE, 0x02);


  data = mtch.readRegister(MTCH6102_MODE);
  Serial.print("MODE: ");
  Serial.println(data,BIN);

  data = mtch.readRegister(MTCH6102_NUMBEROFXCHANNELS);
  Serial.print("NUMBEROFXCHANNELS: ");
  Serial.println(data);

  data = mtch.readRegister(MTCH6102_NUMBEROFYCHANNELS);
  Serial.print("NUMBEROFYCHANNELS: ");
  Serial.println(data);


  data = mtch.readRegister(MTCH6102_NUMBEROFXCHANNELS);
  Serial.print("NUMBEROFXCHANNELS: ");
  Serial.println(data);

 data = mtch.readRegister(MTCH6102_NUMBEROFYCHANNELS);
  Serial.print("NUMBEROFYCHANNELS: ");
  Serial.println(data);
}
  
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);
        }
    }
}

void mqttLoop() {
    if (!mqttClient.connected()) {
        connectMQTT();
    }
    mqttClient.loop();
}


void loop() {
  // 常にチェックして切断されたら復帰できるように
  mqttLoop();
  
  M5.Lcd.clear();
  M5.Lcd.setCursor(0, 70);
  
  byte data; 
  float sensVals[10]={0,0,0,0,0,0,0,0,0,0};

  Serial.print("SENSORVALUE_RX <i>: ");
  //for (byte i = MTCH6102_SENSORVALUE_RX0; i < MTCH6102_SENSORVALUE_RX0+10; i++) {
  for (int i = 0; i < len; i++) {
     data = mtch.readRegister(MTCH6102_SENSORVALUE_RX0+i);
     
    //Serial.print(data);
    //Serial.print(", ");

    sensVals[i] = data;
    M5.Lcd.print(data);
    M5.Lcd.print(", ");
  }
  
  for (int i = 0; i<len; i++){
    float prev;
    if(i==0){
       prev = 0;
    }else{
       prev=sensVals[i-1];
    }
    M5.Lcd.drawLine(i*30, 240-(prev/255)*240, (i+1)*30, 240-(sensVals[i]/255)*240, TFT_WHITE);
  }
  delay(100);
  
  for (int i = 0; i<len; i++){
    float prev;
    if(i==0){
       prev = 0;
    }else{
       prev=sensVals[i-1];
    }
    M5.Lcd.drawLine(i*30, 240-(prev/255)*240, (i+1)*30, 240-(sensVals[i]/255)*240, TFT_BLACK);
  }

  long now = millis();
  if (now - messageSentAt > 1000) {
    messageSentAt = now;
    // データをJSON化
    sprintf(pubMessage, "{\"sensVals\":[%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f]}", sensVals[0] , sensVals[1] , sensVals[2] , sensVals[3] , sensVals[4] , sensVals[5] , sensVals[6] , sensVals[7] , sensVals[8]);
    // データ送信
    Serial.print("Publishing message to topic ");
    Serial.println(pubTopic);
    Serial.println(pubMessage);
    mqttClient.publish(pubTopic, pubMessage);
  }

   
  Serial.println();
  M5.Lcd.println();

  
  
  //delay(100);
 }


  

こちらを以下の設定をして書き込みます。M5StackのMQTTについての詳しい設定は、M5StackとNode-REDをMQTTで連携するメモでも書かれていますので、よろしければご参考ください。

M5StackとNode-REDをMQTTで連携するメモ

動かしてみる

さてこのM5Stackを起動してNode-REDでデータを待っていると以下のように表示されます!

image

これは2本に指を同時に触っている、このようなセンシング状態です。

image

うまくMQTT化すること出来ました、こうするといろいろなものに連携がしやすくなりますね!

引き続き色々と試してまいります。