# How to have multiple Arduinos over MQTT (with Mosca)

**URL:** <https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419>\
**Category:** General\
**Tags:** mqtt\
**Created:** [5 March 2022 23:07 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419 "2022-03-05T23:07:38Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![jjjjn2](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jjjjn2](https://discourse.nodered.org/u/jjjjn2)\
**Post date:** [5 March 2022 23:07 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/1 "2022-03-05T23:07:38Z")

</div>

Hi, I have been able to connect an Arduino WiFi to Node-RED over MQTT and I want to launch a big-scale project where I'll have multiple Arduinos with multiple sensors sending data to node. How would I organize this, have multiple nodes? This is the code I have been able to use so far:

```auto
/* This example shows how to use MQTT on the main dev boards on the market
 * HOW TO USE:
 * under connect method, add your subscribe channels.
 * under messageReceived (callback method) add actions to be done when a msg is received.
 * to publish, call client.publish(topic,msg)
 * in loop take care of using non-blocking method or it will corrupt.
 * 
 * Alberto Perro - Officine Innesto 2019
 */
 
#define BROKER_IP "10.0.0.90"
#define DEV_NAME "mqttdevice"
#define MQTT_USER "mqtt"
#define MQTT_PW "password"

const char ssid[] = "Xf123456";
const char pass[] = "11050927";

#include <MQTT.h>

#ifdef ARDUINO_SAMD_MKRWIFI1010
#include <WiFiNINA.h>
#elif ARDUINO_SAMD_MKR1000
#include <WiFi101.h>
#elif ESP8266
#include <ESP8266WiFi.h>
#else
#error unknown board
#endif
#include <Wire.h>
#include <Adafruit_MPL3115A2.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); 
Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();

WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;

void connect() {
  Serial.print("checking wifi...");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }

  Serial.print("\nconnecting...");
  while (!client.connect(DEV_NAME, MQTT_USER, MQTT_PW)) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("\nconnected!");
  client.subscribe("/main_topic"); //SUBSCRIBE TO TOPIC /main_topic
}

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, pass);

  // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
  // You need to set the IP address directly.
  //
  // MQTT brokers usually use port 8883 for secure connections.
  client.begin(BROKER_IP, 1883, net);
  client.onMessage(messageReceived);
  connect();

  lcd.begin(16,2); // initializing the LCD 16 x 2
  lcd.setBacklightPin(3,POSITIVE); // Enable or Turn On the backlight 
  lcd.setBacklight(HIGH);
}

void loop() {
  if (! baro.begin()) {
    Serial.println("Couldnt find sensor");
    return;
  }
  
  float tempC = baro.getTemperature();
  Serial.print(tempC); Serial.println("*C");
  
  float altm = baro.getAltitude();
  Serial.print(altm/-6); Serial.println(" meters");
  
  client.loop();
  if (!client.connected()) {
    connect();
  }

  String txt = "Hello World!";
  
  char data[6];
  dtostrf(tempC, 5, 2, data);
  
  // publish a message roughly every second.
  if (millis() - lastMillis > 1000) {
    lastMillis = millis();
    client.publish("/main_topic", data); //PUBLISH TO TOPIC /main_topic MSG world
  }
    
  lcd.home();
  lcd.print(altm/-6);
  lcd.setCursor(0,1);
  lcd.print("Meters");
  lcd.setCursor(9,0);
  lcd.print(tempC);
  lcd.setCursor(9,1);
  lcd.print("Celsius");
  lcd.setCursor(7,0);
  lcd.print("|");
  lcd.setCursor(7,1);
  lcd.print("|");
}

```

Note: I used sample code from the Arduino projects page ([Interfacing Arduino MKR or ESP via MQTT - Node-RED 101 - Arduino Project Hub](https://create.arduino.cc/projecthub/officine/interfacing-arduino-mkr-or-esp-via-mqtt-node-red-101-4833bc)), and added my sensor and LCD tweaks

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [6 March 2022 00:50 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/2 "2022-03-06T00:50:03Z")

</div>

You probably want to give each arduino a unique name and publish your data to a topic which includes that name, something like sensors/arduino5.

In Node-red you only need one mqtt-in node, subscribed to sensors/# .

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [6 March 2022 09:57 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/3 "2022-03-06T09:57:06Z")

</div>

Or possibly use meaningful names, such as the room name for example, so that if later you change it from an arduino to a zigbee device you don't have unhelpful topics hard coded into your flows.

---

<div class="post-metadata">

**Author:** ![jjjjn2](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jjjjn2](https://discourse.nodered.org/u/jjjjn2)\
**Post date:** [7 March 2022 01:21 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/4 "2022-03-07T01:21:48Z")

</div>

So it would be something like this?

```auto
[
    {
        "id": "3379850d.902a8a",
        "type": "mqtt in",
        "z": "25945dac9d08dddc",
        "name": "",
        "topic": "/sensors/#",
        "qos": "0",
        "datatype": "auto",
        "broker": "179e5f19.296bb9",
        "nl": false,
        "rap": false,
        "inputs": 0,
        "x": 600,
        "y": 500,
        "wires": [
            [
                "9b59d15d.6d1d28",
                "eb01070fccaa53b5"
            ]
        ]
    },
    {
        "id": "179e5f19.296bb9",
        "type": "mqtt-broker",
        "name": "",
        "broker": "10.0.0.90",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    }
]

```

---

<div class="post-metadata">

**Author:** ![jjjjn2](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jjjjn2](https://discourse.nodered.org/u/jjjjn2)\
**Post date:** [7 March 2022 01:23 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/5 "2022-03-07T01:23:49Z")

</div>

I currently don't have multiple Adafruit sensors but I'm planning to expand, so for this example I wrote a simple code for a message

```auto
/* This example shows how to use MQTT on the main dev boards on the market
 * HOW TO USE:
 * under connect method, add your subscribe channels.
 * under messageReceived (callback method) add actions to be done when a msg is received.
 * to publish, call client.publish(topic,msg)
 * in loop take care of using non-blocking method or it will corrupt.
 * 
 * Alberto Perro - Officine Innesto 2019
 */
 
#define BROKER_IP "10.0.0.90"
#define DEV_NAME "mqttdevice"
#define MQTT_USER "mqtt"
#define MQTT_PW "password"

const char ssid[] = "Xf123456";
const char pass[] = "11050927";

#include <MQTT.h>

#ifdef ARDUINO_SAMD_MKRWIFI1010
#include <WiFiNINA.h>
#elif ARDUINO_SAMD_MKR1000
#include <WiFi101.h>
#elif ESP8266
#include <ESP8266WiFi.h>
#else
#error unknown board
#endif

WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;

void connect() {
  Serial.print("checking wifi...");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }

  Serial.print("\nconnecting...");
  while (!client.connect(DEV_NAME, MQTT_USER, MQTT_PW)) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("\nconnected!");
  client.subscribe("/sensors/message"); //SUBSCRIBE TO TOPIC /mesage_topic
}

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, pass);

  // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
  // You need to set the IP address directly.
  //
  // MQTT brokers usually use port 8883 for secure connections.
  client.begin(BROKER_IP, 1883, net);
  client.onMessage(messageReceived);
  connect();

}

void loop() {
  
  client.loop();
  if (!client.connected()) {
    connect();
  }

  String txt = "Hello World!";

  // publish a message roughly every second.
  if (millis() - lastMillis > 1000) {
    lastMillis = millis();
    client.publish("/sensors/message", txt); //PUBLISH TO TOPIC /altitude_topic MSG world
  }
    
}

```

Of course I also changed the topic in the other code for the Arduino that has the sensor

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [7 March 2022 01:47 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/6 "2022-03-07T01:47:05Z")

</div>

You should not use a leading slash in your MQTT topic, so subscribe to sensors/# not /sensors/#

In your Arduino code you could do something like this, though choose a system that matches your current and future plans:

```auto
#define DEV_NAME "garagedoor"
#define MQTT_BASE "sensors/"
#define MQTT_TOPIC MQTT_BASE DEV_NAME

```

Which makes MQTT\_TOPIC on this device = sensors/garagedoor.

On another Arduino` #define DEV_NAME "kitchen/temperature"` will publish to sensors/kitchen/temperature

Subscribing to sensors/# will catch both of these topics.

---

<div class="post-metadata">

**Author:** ![jjjjn2](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jjjjn2](https://discourse.nodered.org/u/jjjjn2)\
**Post date:** [7 March 2022 01:52 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/7 "2022-03-07T01:52:39Z")

</div>

So, like this?

```auto
/* This example shows how to use MQTT on the main dev boards on the market
 * HOW TO USE:
 * under connect method, add your subscribe channels.
 * under messageReceived (callback method) add actions to be done when a msg is received.
 * to publish, call client.publish(topic,msg)
 * in loop take care of using non-blocking method or it will corrupt.
 * 
 * Alberto Perro - Officine Innesto 2019
 */
 
#define BROKER_IP "10.0.0.90"
#define DEV_NAME "thermo"
#define MQTT_BASE "sensors/"
#define MQTT_TOPIC "sensors/thermo"
#define MQTT_USER "mqtt"
#define MQTT_PW "password"

const char ssid[] = "Xf123456";
const char pass[] = "11050927";

#include <MQTT.h>

#ifdef ARDUINO_SAMD_MKRWIFI1010
#include <WiFiNINA.h>
#elif ARDUINO_SAMD_MKR1000
#include <WiFi101.h>
#elif ESP8266
#include <ESP8266WiFi.h>
#else
#error unknown board
#endif
#include <Wire.h>
#include <Adafruit_MPL3115A2.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); 
Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();

WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;

void connect() {
  Serial.print("checking wifi...");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }

  Serial.print("\nconnecting...");
  while (!client.connect(DEV_NAME, MQTT_USER, MQTT_PW)) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("\nconnected!");
  client.subscribe("sensors/temp"); //SUBSCRIBE TO TOPIC /altitude_topic
}

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, pass);

  // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
  // You need to set the IP address directly.
  //
  // MQTT brokers usually use port 8883 for secure connections.
  client.begin(BROKER_IP, 1883, net);
  client.onMessage(messageReceived);
  connect();

  lcd.begin(16,2); // initializing the LCD 16 x 2
  lcd.setBacklightPin(3,POSITIVE); // Enable or Turn On the backlight 
  lcd.setBacklight(HIGH);
}

void loop() {
  if (! baro.begin()) {
    Serial.println("Couldnt find sensor");
    return;
  }
  
  float tempC = baro.getTemperature();
  Serial.print(tempC); Serial.println("*C");
  
  float altm = baro.getAltitude();
  Serial.print(altm/-6); Serial.println(" meters");
  
  client.loop();
  if (!client.connected()) {
    connect();
  }

  String txt = "Hello World!";
  
  char data[6];
  dtostrf(tempC, 5, 2, data);
  
  // publish a message roughly every second.
  if (millis() - lastMillis > 1000) {
    lastMillis = millis();
    client.publish(" sensors/temp", data); //PUBLISH TO TOPIC /altitude_topic MSG world
  }
    
  lcd.home();
  lcd.print(altm/-6);
  lcd.setCursor(0,1);
  lcd.print("Meters");
  lcd.setCursor(9,0);
  lcd.print(tempC);
  lcd.setCursor(9,1);
  lcd.print("Celsius");
  lcd.setCursor(7,0);
  lcd.print("|");
  lcd.setCursor(7,1);
  lcd.print("|");
}

```

---

<div class="post-metadata">

**Author:** ![jjjjn2](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jjjjn2](https://discourse.nodered.org/u/jjjjn2)\
**Post date:** [7 March 2022 01:55 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/8 "2022-03-07T01:55:28Z")

</div>

I have another question how do I edit how the msg.payload will be displayed? For example, I tried it before and it was like this:

Message:  
Temperature: Hello World!ºC

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [7 March 2022 02:19 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/9 "2022-03-07T02:19:59Z")

</div>

One reason to use #define is to avoid embedding "magic" strings and numbers in the body of your code.  
So you should define the MQTT topic you will publish to just once at the top of the program.

Your code has an MQTT topic defined (sensors/thermo) but you don't use it; down in your loop() you have

```auto
client.publish(" sensors/temp", data);

```

It should be `client.publish( MQTT_TOPIC, data);`

You have not followed my suggestion for the definition of MQTT\_TOPIC as an automatic concatenation of MQTT\_BASE and DEV\_NAME. Your version should work fine.

> [@jjjjn2](#):
>
> I have another question how do I edit how the msg.payload will be displayed? For example, I tried it before and it was like this:
> 
> Message:  
> Temperature: Hello World!ºC

Although I see where you define a string as "Hello World!", I can't see from your code how that or ºC gets into msg.payload.

Personally, I wouldn't include units in the mqtt message since I know I always use Celsius.

---

<div class="post-metadata">

**Author:** ![jjjjn2](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jjjjn2](https://discourse.nodered.org/u/jjjjn2)\
**Post date:** [7 March 2022 02:32 UTC](https://discourse.nodered.org/t/how-to-have-multiple-arduinos-over-mqtt-with-mosca/59419/10 "2022-03-07T02:32:18Z")

</div>

Ok thank you
