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
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.
After Mosca is installed, all that is required is that a “mosca” node needs to be dragged and dropped into the Node-Red project.
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.
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.
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.
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
LikeLike
Hi. I was reading about your fish tank project sounds really interesting.
Have fun.
Pete
LikeLike
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.
LikeLike
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
LikeLiked by 1 person
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
LikeLike
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,?
LikeLike
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);
LikeLike
hello what to do if i keep on getting these error?
Attempting MQTT connection…failed, rc=-2 try again in 5 seconds
LikeLike
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
LikeLike
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.
LikeLike
Hi,
You’ll need to install an MQTT broker, the free Internet that I wrote about is no longer available. You can load the Mosca broker directly into NodeRed, but there are others.
LikeLike