E-textile Electric fabric “nüno” のデータをM5StackからMQTTでつないでNode-REDにつなげるメモです。
まずは動かす
今回 “nüno” をお借りして、早速動かさせていただきました。
tendots/nuno: Electric fabric touchpad "nüno"
こちらのソースコードを使って、M5Stackですぐに動かすことが出来ました。
つづいて押し込んでみる。圧力しっかりとれてて面白い! #etextile pic.twitter.com/hdxFESk8d7
— Tanaka Seigo (@1ft_seabass) July 24, 2019
Arduino的な動きですぐに可視化できるという点で、やはりM5Stackはとっつきやすいですね。
MQTTでデータを引き出してみる
さて、さらにM5StackであればMQTTでデータを引き出すこともスムーズです。MQTTブローカーは自分で立てたMQTTブローカーやテストで使いやすい shiftr.io であったり、Free MQTT service "Daily icecream" – mqtt.uko.jp など使ってみましょう。
Node-RED
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でデータを待っていると以下のように表示されます!
これは2本に指を同時に触っている、このようなセンシング状態です。
うまくMQTT化すること出来ました、こうするといろいろなものに連携がしやすくなりますね!
引き続き色々と試してまいります。