NefryBTでフルカラーテープLEDを動かすことができたので、Node-RED MQTTブローカー経由でNefryBT+フルカラーテープLEDを動かしたメモです。
今回の仕組み
ノートPCインストールされたNode-REDにMQTTブローカーノードを立てて中継し、NefryBTとフルカラーテープLEDを動かす仕組みです。
さらに、タブレットからノートPCのIPで表示したNode-REDを閲覧して直接操作します。
Node-REDのフローの準備
Node-REDのフローはMQTTブローカーで中継の仕組みを作る部分の上部と、MQTT パブリッシュを行ってノートPC側からNefryBT側に通信する下部に分かれます。
MQTTブローカー
MQTTブローカーは、Node-REDが中継してPepperとMilkcocoa(NefryV2)が連携したときのMQTTブローカー実装を参考に設定します。
MQTTブローカーノード( node-red-contrib-mqtt-broker )をインストールして、debugノードをつなげます。
MQTTブローカーノードのプロパティは、一回開いて完了ボタンを押して設定します。
MQTT パブリッシュ
つづいて、MQTT パブリッシュの設定です。
injectノードから点灯状態を伝えるJSONデータ
{"led":1}
or
{"led":0}
を送り、MQTT outノードを使って、NefryBTが接続されているトピックへデータを送る流れになっています。
injectノード
injectノードの設定です。
MQTT outノード
MQTT outノードの設定です。
トピックは、後述するNefry BT内のArduinoでしているトピックと合わせます。サーバーはNode-REDと同一の場所なので、127.0.01:1883に指定します。
Node-REDフロー
今回のNode-REDのフローデータを置いておきます。
[ { "id": "a85796d5.f13b78", "type": "mosca in", "z": "ab3a5f76.c7464", "mqtt_port": 1883, "mqtt_ws_port": 8080, "name": "", "username": "", "password": "", "dburl": "", "x": 131, "y": 720, "wires": [ [ "c71bac71.51431" ] ] }, { "id": "d37d0f9a.14b3c", "type": "comment", "z": "ab3a5f76.c7464", "name": "MQTTブローカー", "info": "", "x": 121, "y": 680, "wires": [] }, { "id": "c71bac71.51431", "type": "debug", "z": "ab3a5f76.c7464", "name": "", "active": false, "console": "false", "complete": "payload", "x": 373, "y": 719, "wires": [] }, { "id": "a670d5df.1f7978", "type": "mqtt out", "z": "ab3a5f76.c7464", "name": "/sub/NefryBT/SAMPLE", "topic": "/sub/NefryBT/SAMPLE", "qos": "", "retain": "", "broker": "32a2c535.945fea", "x": 374, "y": 817, "wires": [] }, { "id": "a3322e0f.8fc5e", "type": "inject", "z": "ab3a5f76.c7464", "name": "", "topic": "", "payload": "{\"led\":1}", "payloadType": "json", "repeat": "", "crontab": "", "once": false, "x": 116, "y": 792, "wires": [ [ "a670d5df.1f7978" ] ] }, { "id": "cd0132a3.b849", "type": "inject", "z": "ab3a5f76.c7464", "name": "", "topic": "", "payload": "{\"led\":0}", "payloadType": "json", "repeat": "", "crontab": "", "once": false, "x": 118, "y": 877, "wires": [ [ "a670d5df.1f7978" ] ] }, { "id": "32a2c535.945fea", "type": "mqtt-broker", "z": "", "broker": "127.0.0.1", "port": "1883", "clientid": "", "usetls": false, "compatmode": true, "keepalive": "60", "cleansession": true, "willTopic": "", "willQos": "0", "willPayload": "", "birthTopic": "", "birthQos": "0", "birthPayload": "" } ]
NefryのArduinoソースコード
AWS IoTをNefryBTで使うメモ でMQTT通信を利用した PubSubClient でMQTTの送受信をさせて、MQTT outノードから送られてきたJSONデータは、ArduinoでJSONを扱う「ArduinoJSON」の参考にして、ArduinoJsonを利用してled = 1 or led = 0で判定できるようにしてます。
#include <Nefry.h> #include <WiFiClient.h> #include <PubSubClient.h> #include <ArduinoJson.h> #include <Adafruit_NeoPixel.h> IPAddress endpoint; const int port = 1883; const char *pubTopic; const char *subTopic; const char *deviceName; WiFiClient httpsClient; PubSubClient mqttClient(httpsClient); int INPUT_PIN = A0; // 今回センサーがつながったピン番号 A0 int OUTPUT_PIN = D2; // 出力ピン D2 // 入力の状態記録 int sensorValueState = LOW; // 光らせるLEDの数 #define NUMPIXELS 59 // 100cmで60個 // NeoPixel設定 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, OUTPUT_PIN, NEO_GRB + NEO_KHZ800); void setup() { //// NefryBT設定画面まわり //////////////////////////////////////// // NefryBT pubTopic = "/pub/NefryBT/SAMPLE"; subTopic = "/sub/NefryBT/SAMPLE"; deviceName = "NefryBT_SAMPLE"; // 複数台で利用する場合は必ずかぶらないように変更する // IPAddress型に収納。配列っぽく入れる。 endpoint[0] = 192; endpoint[1] = 168; endpoint[2] = 1; endpoint[3] = 50; //// 以下通常処理 //////////////////////////////////////// Serial.begin(115200); mqttClient.setServer(endpoint, port); mqttClient.setCallback(mqttCallback); pinMode(INPUT_PIN,INPUT); pixels.begin(); connectMQTT(); } void connectMQTT() { Serial.println("connectMQTT"); Serial.println(deviceName); while (!mqttClient.connected()) { Serial.print("."); if (mqttClient.connect(deviceName)) { 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); } } } char pubMessage[128]; 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"); StaticJsonBuffer<200> jsonBuffer; JsonObject& root = jsonBuffer.parseObject(str); // パースが成功したか確認。できなきゃ終了 if (!root.success()) { Serial.println("parseObject() failed"); return; } const char* message = root["message"]; int led = root["led"]; Serial.print("led = "); Serial.println(led); if( led == 1 ){ // 点灯 Serial.println("led on"); pixels.setBrightness(128); for(int i=0;i<NUMPIXELS;i++){ pixels.setPixelColor(i, pixels.Color(0,255,0)); pixels.show(); delay(50); } } else { // 消灯 Serial.println("led off"); pixels.setBrightness(0); for(int i=0;i<NUMPIXELS;i++){ pixels.setPixelColor(i, pixels.Color(0,0,0)); pixels.show(); delay(50); } } Nefry.ndelay(1000); } void mqttLoop() { if (!mqttClient.connected()) { connectMQTT(); } mqttClient.loop(); } void loop() { mqttLoop(); // センサー反応ON int sensorValueCurrent = digitalRead(INPUT_PIN); if ( sensorValueCurrent != sensorValueState ) { if( sensorValueCurrent == HIGH ){ Serial.println("sensor ON"); mqttClient.publish(pubTopic, "{\"flag\":1}"); } else { Serial.println("sensor OFF"); mqttClient.publish(pubTopic, "{\"flag\":0}"); } } // 入力の状態を次のループまで記憶 sensorValueState = sensorValueCurrent; }
動かしてみる
ここまで設定できたら、実際に動かしてみましょう。タブレットからノートPCのIPで表示したNode-REDを閲覧して直接操作しています。
無事操作できています!
Raspberry Pi内のバージョン情報
基本的なバージョン情報は以下に記載しております。
2017年後半のRaspberry Pi関連の設定情報をまとめておくメモ – 1ft-seabass.jp.MEMO
まとめ
ということで、NefryBTでNode-RED MQTTブローカー経由でフルカラーテープLEDを動かすことができました。今回は、単純な点灯ですが、MQTTでのデータのやり取りと、NefryBTでの点灯をうまく合わせれば、もっと細かい操作も可能ですね。
また、今回の動画はHoloLensで撮影したのですが、デモしやすいですね!
HoloLensの動画撮影は、手がフリーになれるので、やはりIoTデモ撮影するとき、とてもいいと改めて思った。 #HoloLens #WinMR
— 1ft_seabass (@1ft_seabass) 2017年10月6日
それでは、よき IoT & Node-RED Lifeを!