概要
- Arduino Uno R4 WifiでMQTTで通信してみた。
- ArduinoMQTTClientを使えば通信可能
構成
MQTTXをPCにインストールし、Shiftr.io経由でデータを送ってみた。
ArduinoがSubscriberになってデータを取得していくイメージ。
ArduinoMQTTClient
こちらのリンクを参照。似たような名前のライブラリが多いため注意。
コード
MQTTXから送られた文字列に応じてArduinoボード上のLEDが点灯する。
#include "WiFiS3.h"
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
#include <ArduinoMqttClient.h>
#include <string.h>
#include <stdlib.h>
char ssid[] = ""; // WifiのSSID
char pass[] = ""; // Wifiのパス
char mqtt_user[] = "public";
char mqtt_pass[] = "public";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "public.cloud.shiftr.io"; //ブローカーのIDやURL
int port = 1883; //PORT
const char subscribe_topic[] = "/led_arduino_switch"; //トピックID
const int LED_PIN = 0;
ArduinoLEDMatrix matrix;
byte frame[8][12] = {
{ 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
// 文字を描写するやつ
void drawText(const char text[]){
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(50);
// add the text
matrix.textFont(Font_5x7);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
}
void setup() {
// シリアル待機
Serial.begin(9600);
while (!Serial) {
;
}
// Wifiに接続
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
// ネットワークに接続
Serial.println("You're connected to the network");
Serial.println();
// MQTTに接続
mqttClient.setUsernamePassword(mqtt_user, mqtt_pass);
Serial.print("Attempting to connect to the MQTT broker.");
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.print("Subscribing to topic: ");
Serial.println(subscribe_topic);
// トピック購読
mqttClient.subscribe(subscribe_topic);
// 購読やめるときはこちら
// mqttClient.unsubscribe(topic);
Serial.print("Waiting for messages on topic: ");
Serial.println(subscribe_topic);
digitalWrite(LED_PIN, LOW);
matrix.begin();
matrix.renderBitmap(frame, 8, 12);
}
void loop() {
int messageSize = mqttClient.parseMessage();
char *str;
int i = 0;
if (messageSize) {
str = (char*)calloc(messageSize+1,sizeof(char));
// メッセージ受信
Serial.print("Received a message with topic '");
Serial.print(mqttClient.messageTopic());
Serial.print("', length ");
Serial.print(messageSize);
Serial.println(" bytes:");
// メッセージの受信をやり切る
while (mqttClient.available()) {
*(str+i) = (char)mqttClient.read();
i++;
}
*(str+i) = '\0';
Serial.println(str);
// 判定して表示!
if(strcmp(str,"on") == 0){
drawText(" ON! ");
}else if(strcmp(str,"off") == 0){
drawText(" OFF! ");
}
free(str);
i = 0;
Serial.println();
}
}
Node-REDフロー
[{"id":"8c6bb9a64f5626a8","type":"mqtt out","z":"48f0dd45f4685c27","name":"","topic":"led_arduino_switch","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"82a75067279577ee","x":470,"y":120,"wires":[]},{"id":"9e0180f01150d975","type":"inject","z":"48f0dd45f4685c27","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":170,"y":40,"wires":[["8c6bb9a64f5626a8"]]},{"id":"a7f828fbc09f36c9","type":"inject","z":"48f0dd45f4685c27","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":350,"y":40,"wires":[["8c6bb9a64f5626a8"]]},{"id":"260d0eec9665b4e2","type":"inject","z":"48f0dd45f4685c27","name":"heart","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ledmatrix\":[[0,0,1,1,0,0,0,1,1,0,0,0],[0,1,0,0,1,0,1,0,0,1,0,0],[0,1,0,0,0,1,0,0,0,1,0,0],[0,0,1,0,0,0,0,0,1,0,0,0],[0,0,0,1,0,0,0,1,0,0,0,0],[0,0,0,0,1,0,1,0,0,0,0,0],[0,0,0,0,0,1,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0]]}","payloadType":"json","x":170,"y":120,"wires":[["8c6bb9a64f5626a8"]]},{"id":"27e59c1d84842cbf","type":"inject","z":"48f0dd45f4685c27","name":"neutral","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ledmatrix\":[[0,0,0,0,1,1,1,0,0,0,0,0],[0,0,0,1,0,0,0,1,0,0,0,0],[0,0,1,0,0,0,0,0,1,0,0,0],[0,1,0,0,1,0,1,0,0,1,0,0],[1,0,0,0,0,0,0,0,0,0,1,0],[1,0,0,0,1,1,1,0,0,0,1,0],[0,1,1,0,0,0,0,0,1,1,0,0],[0,0,0,1,1,1,1,1,0,0,0,0]]}","payloadType":"json","x":170,"y":180,"wires":[["8c6bb9a64f5626a8"]]},{"id":"73aa618749ab8ebb","type":"inject","z":"48f0dd45f4685c27","name":"happy","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ledmatrix\":[[0,0,0,0,1,1,1,0,0,0,0,0],[0,0,0,1,0,0,0,1,0,0,0,0],[0,0,1,0,1,0,1,0,1,0,0,0],[0,1,0,0,0,0,0,0,0,1,0,0],[1,0,0,1,0,0,0,1,0,0,1,0],[1,0,0,0,1,1,1,0,0,0,1,0],[0,1,1,0,0,0,0,0,1,1,0,0],[0,0,0,1,1,1,1,1,0,0,0,0]]}","payloadType":"json","x":170,"y":240,"wires":[["8c6bb9a64f5626a8"]]},{"id":"c03751e1af63a141","type":"inject","z":"48f0dd45f4685c27","name":"unhappy","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ledmatrix\":[[0,0,0,0,1,1,1,0,0,0,0,0],[0,0,0,1,0,0,0,1,0,0,0,0],[0,0,1,0,1,0,1,0,1,0,0,0],[0,1,0,0,0,0,0,0,0,1,0,0],[1,0,0,0,1,1,1,0,0,0,1,0],[1,0,0,1,0,0,0,1,0,0,1,0],[0,1,0,0,0,0,0,0,0,1,0,0],[0,0,1,1,1,1,1,1,1,0,0,0]]}","payloadType":"json","x":180,"y":300,"wires":[["8c6bb9a64f5626a8"]]},{"id":"82a75067279577ee","type":"mqtt-broker","name":"shiftr.io","broker":"public.cloud.shiftr.io","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]
neutral, happy, unhappyについて
JSONに二次元配列を渡して、その配列で真になっている箇所を点灯させている。
たとえばneutralであればこんな感じ。
{
"ledmatrix": [
[0,0,0,0,1,1,1,0,0,0,0,0],
[0,0,0,1,0,0,0,1,0,0,0,0],
[0,0,1,0,0,0,0,0,1,0,0,0],
[0,1,0,0,1,0,1,0,0,1,0,0],
[1,0,0,0,0,0,0,0,0,0,1,0],
[1,0,0,0,1,1,1,0,0,0,1,0],
[0,1,1,0,0,0,0,0,1,1,0,0],
[0,0,0,1,1,1,1,1,0,0,0,0]
]
}
結果
うごいたー。いえーい。
おわりに
- Arduino上のコードは少し複雑だけど、受信さえできれば後は普通のコードにできそう。面倒な部分は別途ライブラリ化したほうが楽かも。
- Arduino社純正ボードでの知見はまだまだ少ない。もっと盛り上げていこう~!
参考
こちらのリンクで先程のライブラリを知った。Moheeb Zara氏に感謝。