Node-RED MQTTブローカー経由でNefryBT+フルカラーテープLEDを動かすメモ
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を!