Project in progress
Interfacing Arduino MKR or ESP via MQTT - Node-RED 101

Interfacing Arduino MKR or ESP via MQTT - Node-RED 101

A very basic tutorial on how to interface a microcontroller to an MQTT broker and interact with data on Node-RED.

  • 2,091 views
  • 0 comments
  • 3 respects

Components and supplies

Apps and online services

About this project

Abstract

This article gives the very basic indications to use a microcontroller with network connectivity to send and receive data via MQTT. It also covers Node-RED implementation of MQTT.

Guide

First, check the microcontroller you have has network connectivity and is supported by Arduino IDE (or Arduino Web Editor).

Open the Arduino IDE and install all the necessary libraries to enable network (they should be installed by default).Install the MQTT client library by Joël Gähwiler (256dpi). To do so, open the Library Manager under Sketch->#include Library... and search lwmqtt. Hit install.After some time, you should have the library installed and be ready to code.

Code

Set your configuration:

#define BROKER_IP    "192.168.1.1"
#define DEV_NAME     "mqttdevice"
#define MQTT_USER    "mqtt_user"
#define MQTT_PW      "mqtt_password"
const char ssid[] = "wifi_ssid";
const char pass[] = "wifi_password";

under connect method put your topic subscriptions with client.subscribe(topic);

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("/hello"); //SUBSCRIBE TO TOPIC /hello
}

to publish call client.publish(topic, msg);

void loop() {
 client.loop();
 if (!client.connected()) {
   connect();
 }
 // publish a message roughly every second.
 if (millis() - lastMillis > 1000) {
   lastMillis = millis();
   client.publish("/hello", "world"); //PUBLISH TO TOPIC /hello MSG world
 }  
}

messageReceived is called when a message is published in a topic you subscribed, put here your stuff to do when data is received.

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

In loop() and messageReceived(topic, payload) avoid blocking methods, such as delay(), because they can lead to a crash.

Node-RED

On a PC install Node-RED. It is possible to install it in Windows, Mac or Linux, while the best fit is a Raspberry Pi.

If you have properly installed Node-RED you should install an MQTT Broker. You can look for "Mosca" in the "Manage Palette" Menu.

Once the Mosca MQTT Broker is installed you'll be able to add and configure your Broker by adding it to your flow. In order to make it working you'll have to setup (or disable) a mqtt user and password. We are using the one provided in the attached code.

You can deepen the knowledge of how MQTT and Node-RED work by viewing these two videos by Steve Cope. (Thanks Steve!)

1. How to Install The Mosca MQTT Broker on Node-RED 2. MQTT Publish and Subscribe Using Node Red

Let's go on!

We will now test the connection by injecting some commands and make them published on the Node-RED debug feed using a debug node.

Pro-Tip! You can copy and paste the above nodes in your flow by copying the following code and select menu > import > clipboard

[{"id":"3379850d.902a8a","type":"mqtt in","z":"a7e5fb79.b6fca","name":"","topic":"#","qos":"0","broker":"179e5f19.296bb9","x":270,"y":160,"wires":[["9b59d15d.6d1d28"]]},{"id":"9b59d15d.6d1d28","type":"debug","z":"a7e5fb79.b6fca","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":570,"y":200,"wires":[]},{"id":"6ff9ea89.aac6e4","type":"inject","z":"a7e5fb79.b6fca","name":"inject \"open\" command","topic":"/hello","payload":"open","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":320,"y":300,"wires":[["97f6e1c5.ab547"]]},{"id":"97f6e1c5.ab547","type":"mqtt out","z":"a7e5fb79.b6fca","name":"","topic":"","qos":"","retain":"","broker":"179e5f19.296bb9","x":620,"y":320,"wires":[]},{"id":"c8e9cb97.9ddfb","type":"inject","z":"a7e5fb79.b6fca","name":"inject \"closed\" command","topic":"/hello","payload":"closed","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":380,"wires":[["97f6e1c5.ab547"]]},{"id":"179e5f19.296bb9","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}] 

You'll have to properly configure the MQTT nodes, check the Security and IP address Sections.

If everything works fine, you should see the injected strings appearing in the debug area. 😎

Connect with Arduino

We are almost there! Now you have to know where is your MQTT broker aka which IP address has been given to it from your router. Plenty of ways, depending on where is your Node-RED installation (if it's in your computer for testing purposes, it's going to be your Computer IP address. My favourite way is using Fing. You'll have to copy the IP address on line 11 of our code, BROKER_IP.

So. If you uploaded the code in the Arduino you'll see the code is sending world on the channel /hello.

Success! 🙌 You are done!

... Well, I wanted to light a LED on the board. How do I do that?

OK, you want the Node-RED to send some data to the board and make something happening. Right? In order to do taht you have to edit the messageReceived function, which is called every time the Arduino MKR is receving data through MQTT.

In this case the board lights up the onboard led based on the payload of the MQTT command.

void messageReceived(String &topic, String &payload) {
 Serial.println("incoming: " + topic + " - " + payload);
 if (topic == "/hello") {
   if (payload == "open") {
     Serial.println("open");
     digitalWrite(LED_BUILTIN, HIGH); 
   } else if (payload == "closed") {
     Serial.println("closed");
     digitalWrite(LED_BUILTIN, LOW); 
   }
 }
}

You have successfully integrated a MQTT device in a go and return conversation!

Final Code & Flow

/* 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 & DG - Officine Innesto 2019
*/
#define BROKER_IP    "brockerIpAddress"
#define DEV_NAME     "mqttdevice"
#define MQTT_USER    "mqtt_user"
#define MQTT_PW      "mqtt_password"
const char ssid[] = "wifi_ssid";
const char pass[] = "wifi_password";
#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("/hello"); //SUBSCRIBE TO TOPIC /hello
}
void messageReceived(String &topic, String &payload) {
 Serial.println("incoming: " + topic + " - " + payload);
 if (topic == "/hello") {
   if (payload == "open") {
     Serial.println("open");
     digitalWrite(LED_BUILTIN, HIGH); 
   } else if (payload == "closed") {
     Serial.println("closed");
     digitalWrite(LED_BUILTIN, LOW); 
   }
 }
}
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();
 }
 // publish a message roughly every second.
 if (millis() - lastMillis > 1000) {
   lastMillis = millis();
   client.publish("/hello", "world"); //PUBLISH TO TOPIC /hello MSG world
 }
}

...and the Flow!

[{"id":"a7e5fb79.b6fca","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"3379850d.902a8a","type":"mqtt in","z":"a7e5fb79.b6fca","name":"","topic":"#","qos":"0","broker":"179e5f19.296bb9","x":270,"y":160,"wires":[["9b59d15d.6d1d28"]]},{"id":"9b59d15d.6d1d28","type":"debug","z":"a7e5fb79.b6fca","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":570,"y":200,"wires":[]},{"id":"6ff9ea89.aac6e4","type":"inject","z":"a7e5fb79.b6fca","name":"inject \"open\" command","topic":"/hello","payload":"open","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":320,"y":300,"wires":[["97f6e1c5.ab547"]]},{"id":"97f6e1c5.ab547","type":"mqtt out","z":"a7e5fb79.b6fca","name":"","topic":"","qos":"","retain":"","broker":"179e5f19.296bb9","x":620,"y":320,"wires":[]},{"id":"3c363c12.80b1bc","type":"mosca in","z":"a7e5fb79.b6fca","mqtt_port":1883,"mqtt_ws_port":8080,"name":"","username":"mqtt_user","password":"mqtt_password","dburl":"","x":150,"y":60,"wires":[[]]},{"id":"c8e9cb97.9ddfb","type":"inject","z":"a7e5fb79.b6fca","name":"inject \"closed\" command","topic":"/hello","payload":"closed","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":380,"wires":[["97f6e1c5.ab547"]]},{"id":"179e5f19.296bb9","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Code

MQTTexample.inoArduino
MQTT example code
/* 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    "192.168.1.1"
#define DEV_NAME     "mqttdevice"
#define MQTT_USER    "mqtt_user"
#define MQTT_PW      "mqtt_password"

const char ssid[] = "wifi_ssid";
const char pass[] = "wifi_password";

#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("/hello"); //SUBSCRIBE TO TOPIC /hello
}

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();
  }
  // publish a message roughly every second.
  if (millis() - lastMillis > 1000) {
    lastMillis = millis();
    client.publish("/hello", "world"); //PUBLISH TO TOPIC /hello MSG world
  }  
}

Comments

Similar projects you might like

Interfacing Arduino With Node-RED

by Gokul Periyasamy

  • 17,400 views
  • 1 comment
  • 14 respects

Smart Garbage Monitoring System Using Arduino 101

Project tutorial by Technovation

  • 21,474 views
  • 7 comments
  • 32 respects

Arduino MKR GSM 1400 and DTMF

by Arduino_Genuino

  • 17,394 views
  • 0 comments
  • 29 respects

IoT arduino ESP Garage Door opener (UD)

Project in progress by David Smerkous

  • 11,646 views
  • 6 comments
  • 17 respects

Arduino 101 Home BLE System

Project tutorial by Alexis Santiago Allende

  • 2,697 views
  • 0 comments
  • 12 respects
Add projectSign up / Login