LoginSignup
7
4

Arduino Uno R4 WifiにてMQTT通信してみた。

Last updated at Posted at 2023-12-05

概要

  • Arduino Uno R4 WifiでMQTTで通信してみた。
  • ArduinoMQTTClientを使えば通信可能

構成

MQTTXをPCにインストールし、Shiftr.io経由でデータを送ってみた。
ArduinoがSubscriberになってデータを取得していくイメージ。

image.png

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フロー

image.png

[{"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であればこんな感じ。

image.png

{
    "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氏に感謝。

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4