Arduino talking MQTT to Node-Red

There are some great Arduino modules with integrated ESP-8266 wireless chips, some of the more popular modules are:

  • Adafruit HUZZAH
  • NodeMCU
  • WeMos

These modules allow you to do some interesting IoT (Internet of Things) projects. To connect the Arduino modules to PCs, Raspberry Pi’s or Linux nodes that are a number of communication choices. MQTT (Message Queue Telemetry Transport) is becoming one of the standards for this and it is pre-installed with Node-Red.

Plant Moisture Monitoring MQTT Example

Ard_mqtt_overview2

For our example we wanted to do a simple plant moisture example that used a solar charger and an Arduino Wemos module. We then setup an MQTT server on our Node-Red Raspberry Pi with a web dashboard.

Our goal was to get the MQTT technologies working, with some moisture inputs (and not a final plant monitoring system).

Moisture Sensors

Moisture sensors are very low cost and they start at about $2. The basic moisture sensor has 3 inputs; VCC, GND, and AO. Some sensors also include a digital output with a potentiometer to adjust the digital 0-1 moisture limit.

Our Arduino plant moisture setup is good for testing but not a good long term solution. When voltage is applied long term to moisture sensors ionization in the soil will cause a combination of false reading and deterioration of the sensor plates. We plan to do a future project where we will use relays to turn the sensors on/off and we will include solenoid values in a watering system.

MQTT on Arduino

There are a number of excellent MQTT libraries for Arduino, for this example we used the PubSubClient library. This library can be installed from the Arduino IDE by selecting the menu items:

Sketch -> Add Library -> Manage Libraries

To get MQTT setup you’ll need to:

  • define the SSID and password for your WAN
  • define the IP address for the MQTT server (the Node Red/Raspberry Pi node)
  • define some topic for the data

The nice thing about MQTT is that you can define topics for each of your data points. For this example we define the topic humidity to show the moisture sensor value, and msgtext to show the message (‘Needs Water’ or ‘).

Below is our sample Arduino code for passing the moisture data to our MQTT server.

/*
 Basic ESP8266 MQTT publish client example for a moisture sensor
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
const char* ssid = "YOUR_SSID_NAME";
const char* password = "YOUR_PASSWORD";
const char* mqtt_server = "YOUR_NODE_RED_IP";

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  // Connecting to a WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're reconnected
  Serial.println("In reconnect...");
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Arduino_Moisture")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
}

void loop() {
  char msg[10];
  char msgtext[25];
  String themsg;
  if (!client.connected()) {
    reconnect();
  }
  
  int soil_moisture=analogRead(A0);  // read from analog pin A0
  Serial.print("analog value: ");
  Serial.println(soil_moisture);
  
  if((soil_moisture>300)&&(soil_moisture<700)) {
    Serial.println("Humid soil");
    sprintf(msgtext,"Humid soil",soil_moisture);
  } 
  else if ((soil_moisture>700)&&(soil_moisture<950)){
    Serial.println("Moist Soil");
    sprintf(msgtext,"Moist Soil",soil_moisture);
  }
  else if (soil_moisture <300) ){
    Serial.println("Needs water");    
    sprintf(msgtext,"Needs water",soil_moisture);
  }
  else
  {
      sprintf(msgtext,"Sensor Problem",soil_moisture);
  }

  sprintf(msg,"%i",soil_moisture);
  client.publish("humidity", msg);
  client.publish("soil", msgtext);
  delay(5000);
}

Node-Red

Node-Red is an excellent visual programming environment that is part of the Raspberry Pi base install. Node-Red is a simple tool to create your own Internet of Things applications. The base Node-Red installation includes MQTT interfacing components but it does not include an MQTT server.

If you don’t have a Raspberry Pi you can install Node-Red on Window, Mac OS or Linux systems. I’ve had good results running Node-Red on a very old low end laptop running Xubuntu, (see steps 1-3 in this linked guide).

MQTT Server on Node-Red

There are a number of free internet MQTT servers (iot.eclipse.org) that can be used or an MQTT server can be loaded directly on a local server (i.e. Mosquito).

Mosca is a standalone MQTT server that can be installed directly into Node-Red. The Mosca Node-Red component can be either installed at the command line by:

cd $HOME/.node-red

npm install node-red-contrib-mqtt-broker

Or the component can be install within the Node-Red web interface by selecting the “manage palette” option, and then search for mosca.

mosca_install

After Mosca is installed, all that is required is that a “mosca” node needs to be dragged and dropped into the Node-Red project.

mosca_mqtt_nodes

To connect the Arduino module to Node-Red mqtt inputs are added to the project.  The Arduino topics are defined in Node-Red by double-clicking on the mqtt node and then define the topic to match the Arduino topic.

mqtt_topic

After the MQTT connections are configured Web dashboards can present the final data. The Web dashboards offer a number of different components that could be used for this example I used a gauge and a text node.

To compile and view the Node-Red application, click on the Deploy button on the right side of the menu bar. To access the web dashboard enter: http://your-ip:1880/ui . Below is a example of what you should see.

NodeRed_MQTT_GUI

Final Thoughts

The Mosca MQTT server component allows for a simple standalone architecture to connect wireless Arduino modules into a Node-Red IoT solution.

We can also load Node-Red on Raspberry Pi data collection nodes, and have them publish data to a central Node-Red server.

 

 

 

15 thoughts on “Arduino talking MQTT to Node-Red

  1. Great blog and thank you for the example code. I’ve started my own Raspberry Pi project monitoring my fish tank, and am looking to upload data to Adafruit to create a dashboard. Just read several of you blogs and enjoyed them. Looking forward to reading more in the future hopefully

    Like

    1. Hi I have to make a project very similar to yours but unlike you I am supposed to publish on the node red dashboard the values of a simulated temperature.
      I understood that the topic in node red has to match the one in the Arduino code.
      My program on Arduino is working (although it is not completed) and producing the random values of the temperature. On node red on the mqtt node I read connected. The dashboard is also shown on the localhost/ui page but the needle of the gauge is not moving . I have not understood yet how to write the missing code on Arduino that is supposed to send the Json string to node red so that I can read all the values of the temperature on the debug flow and accordingly on the gauge.

      Like

      1. Hi Paul,
        For this blog example I had the Arduino published the MQTT message as just a simple string. Not a JSON string. I wanted to keep things easy so I generated a new MQTT topic for each of my input values.

        Using JSON with MQTT makes a lot of sense because you can associate a value, quality, status etc all in one message. However you’ll need to then to parse the message in NodeRed. NodeRed supports a number of ways to do this, like Javascript in a function node. This isn’t so bad and I’ve had to do it when I manage an SQL message.

        Also there are some Arduino JSON libraries that might help you in managing your MQTT message formatting.

        Good luck with it.
        Pete

        Pete

        Liked by 1 person

      1. Hi,
        For my original example I used a free Internet MQTT broker (server). However there a lots of free ones that you can load on your local LAN. Mosquitto is good, but there is also one available in Node-Red.

        For phone access, simply use the Node-Red dashboards. This will create a light web interface that your phone can connect to.

        Like

  2. I have noticed you don’t monetize funprojects.blog, don’t waste your traffic,
    you can earn extra cash every month with new monetization method.
    This is the best adsense alternative for any type of website (they approve all
    sites), for more details simply search in gooogle: murgrabia’s
    tools

    Like

    1. Thanks a lot for your reply Pete. I would like to try to send the data of the temperature to NOde Red with a simple string before trying with Json but stil I have no idea how to do it. Could you tell me please which is the part of your Arduino code that turns the datum of the moisture into a String and then sends it to NOde Red,?

      Like

      1. Hi,
        As I look back I realize I should have added more comments. The key would be:

        // use pin A0 to read the moisture sensor
        int soil_moisture=analogRead(A0)

        // convert the moisture value to a string
        sprintf(msg,”%i”,soil_moisture);

        // publish the MQTT topic: humidity
        client.publish(“humidity”, msg);

        Like

  3. hello what to do if i keep on getting these error?

    Attempting MQTT connection…failed, rc=-2 try again in 5 seconds

    Like

    1. Hi,
      I believe a -2 error is a no connection error. This would occur if you’re talking to an Internet MQTT broker that is no longer available.

      There are some good light weight free brokers like Mosquito that you could install on a local node.

      Regards
      Pete

      Like

  4. Hello,
    I installed mosquitto on my windows and its running in local mode.
    I was trying to search the net but i can’t seem to find the ip that will be used in arduino for mqtt server.
    What ip will i use?
    Node red and mqtt connection was successful but i can’t connect the nodemcu and mqtt.

    Like

Leave a comment