Control Your IoT Cloud Kit via MQTT and Node-RED

We are going to use popular tools such as Node-RED and the MQTT protocol to create a simple dashabord esposing data and a simple UI

Components and Supplies

Apps and Online Services

About This Project

We are going to make our MKR IoT Bundle connect to a local server (this very same technology could be hosted on AWS or wherever).

The connection is going to be held through MQTT, a lightweight message protocol developed for machine to machine communication.

In order to do this we need to do some work on the server side. I'm using a Raspberry PI with Node-RED on it, but you can host an instance of Node-RED on Windows/MAC/Linux or on the Cloud (Bluemix, AWS, etc..).

This tutorial heavily relies on Interfacing Arduino MKR or ESP via MQTT - Node-RED 101 we did back in January. We are touching all the points and adding the data visualisation, but don't hesitate to go through that tutorial in order to see all the steps in the setup of the Cloud instance.

The Server

In order to prepare your Node-RED instance properly you need to install two Nodes: Node-RED Dashboard and an MQTT brocker written in node.js.

Once you are done, copy the flow you find in the software section in your palette by doing import > clipboard

Node-RED Flow you can download from this hackster tutorial
Node-RED Flow you can download from this hackster tutorial
I tried my best to make the dashboard fit in the screen, but you can do much more better.
I tried my best to make the dashboard fit in the screen, but you can do much more better.

The Client

We are using the Iot Prime MKR Bundle to visualise Light, Humidity, Pressure and Temperature using MQTT. We are going to create a channel for each one of this data, as well as the two relays.

We'll be using the MQTT Library by Joël Gähwiler 256dpi (you should be able to run everything from your Arduino Online Editor sketch, by adding Wifi information to have the board connecting to the internet.

Don't forget the MKR_ENV Library you need to use the data from the board (if going with the online IDE, it's going to be imported automatically 👌

The sending of the data is done in loop:

1// read environmental data
2 float t = ENV.readTemperature();
3 float h = ENV.readHumidity();
4 float p = ENV.readPressure();
5 float l = ENV.readLux();

and later published, casted ina a

string()

1if (millis() - lastMillis > 1000) {
2 lastMillis = millis();
3 client.publish("/hello", "world");
4 client.publish("/temp", String(t));
5 client.publish("/humidity", String(h));
6 client.publish("/pressure", String(p));
7 client.publish("/light", String(l));
8 }

In order to read the value of the pushbutton of the Node-RED Dashboard, I've nested two condition inside of the

messageReceived
function.

If the topic is

/relay1
or
relay2
, trigger it (and trigger the onboard LED, as a notification)

1void messageReceived(String &topic, String &payload) {
2 Serial.println("incoming: " + topic + " - " + payload);
3 if (topic == "/relay1") {
4 if (payload == "true") {
5 digitalWrite(R1, HIGH);
6 digitalWrite(led, HIGH);
7 } else if (payload == "false") {
8 digitalWrite(R1, LOW);
9 digitalWrite(led, LOW);
10 }
11 }
12 if (topic == "/relay2") {
13 if (payload == "true") {
14 digitalWrite(R2, HIGH);
15 digitalWrite(led, HIGH);
16 } else if (payload == "false") {
17 digitalWrite(R2, LOW);
18 digitalWrite(led, LOW);
19 }
20 }
21}

You can

#copypasta
the code and test & tweak it yourself!

JSON

Node-Red Dashboard Flow

This flow is visualizing the data sent via MQTT to the brocker.

1[{"id":"703b47b.5c41fb8","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"c6c9dfb0.bec5f8","type":"mqtt in","z":"703b47b.5c41fb8","name":"","topic":"/temp","qos":"0","datatype":"auto","broker":"447166d7.c2fef","x":410,"y":340,"wires":[["963ce144.613608","60eacc81.fe61cc"]]},{"id":"963ce144.613608","type":"debug","z":"703b47b.5c41fb8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":380,"wires":[]},{"id":"ab49bd0c.be7e08","type":"mqtt out","z":"703b47b.5c41fb8","name":"","topic":"","qos":"","retain":"","broker":"447166d7.c2fef","x":690,"y":460,"wires":[]},{"id":"4413b98b.0ee328","type":"mosca in","z":"703b47b.5c41fb8","mqtt_port":1883,"mqtt_ws_port":8080,"name":"","username":"","password":"","dburl":"","x":170,"y":60,"wires":[[]]},{"id":"3b910073.fdd5b","type":"mqtt in","z":"703b47b.5c41fb8","name":"","topic":"/pressure","qos":"0","datatype":"auto","broker":"447166d7.c2fef","x":400,"y":260,"wires":[["80205d8.49f8aa","5cd668ff.28609"]]},{"id":"3276f36c.216f24","type":"mqtt in","z":"703b47b.5c41fb8","name":"","topic":"/humidity","qos":"0","datatype":"auto","broker":"447166d7.c2fef","x":400,"y":180,"wires":[["1a729bd7.be63bc","de157a7a.f73d5"]]},{"id":"cfb5c9ec.9f535","type":"mqtt in","z":"703b47b.5c41fb8","name":"","topic":"/light","qos":"0","datatype":"auto","broker":"447166d7.c2fef","x":410,"y":100,"wires":[["30e59264.6e30f6","5c96c4f7.74d53c"]]},{"id":"80205d8.49f8aa","type":"debug","z":"703b47b.5c41fb8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":300,"wires":[]},{"id":"1a729bd7.be63bc","type":"debug","z":"703b47b.5c41fb8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":710,"y":220,"wires":[]},{"id":"30e59264.6e30f6","type":"debug","z":"703b47b.5c41fb8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":140,"wires":[]},{"id":"5c96c4f7.74d53c","type":"ui_chart","z":"703b47b.5c41fb8","name":"","group":"61cb93ff.8cf4a4","order":4,"width":"0","height":"0","label":"Light","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":690,"y":100,"wires":[[]]},{"id":"de157a7a.f73d5","type":"ui_chart","z":"703b47b.5c41fb8","name":"","group":"61cb93ff.8cf4a4","order":5,"width":"0","height":"0","label":"Humidity","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":700,"y":180,"wires":[[]]},{"id":"5cd668ff.28609","type":"ui_chart","z":"703b47b.5c41fb8","name":"","group":"61cb93ff.8cf4a4","order":6,"width":"0","height":"0","label":"Pressure","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":700,"y":260,"wires":[[]]},{"id":"60eacc81.fe61cc","type":"ui_chart","z":"703b47b.5c41fb8","name":"","group":"61cb93ff.8cf4a4","order":7,"width":"0","height":"0","label":"Temperature","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":710,"y":340,"wires":[[]]},{"id":"898e8fb0.ac40d8","type":"ui_switch","z":"703b47b.5c41fb8","name":"","label":"Relay 1","tooltip":"","group":"61cb93ff.8cf4a4","order":2,"width":"0","height":"0","passthru":false,"decouple":"false","topic":"/relay1","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":400,"y":420,"wires":[["ab49bd0c.be7e08","1919344d.9c56a4"]]},{"id":"1919344d.9c56a4","type":"debug","z":"703b47b.5c41fb8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":420,"wires":[]},{"id":"5bd7c311.0385fc","type":"ui_switch","z":"703b47b.5c41fb8","name":"","label":"Relay 2","tooltip":"","group":"61cb93ff.8cf4a4","order":3,"width":"0","height":"0","passthru":false,"decouple":"false","topic":"/relay2","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":400,"y":500,"wires":[["ab49bd0c.be7e08","1919344d.9c56a4"]]},{"id":"447166d7.c2fef","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":""},{"id":"61cb93ff.8cf4a4","type":"ui_group","z":"","name":"IoT MKR Prime Bundle Kit ","tab":"56fe067d.dd1478","disp":true,"width":"18","collapse":false},{"id":"56fe067d.dd1478","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Complete Sketch

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.