Introduction
Setup Arduino IDE
The Things Network Dashboard
Register Device (ABP)
Sending Some Data
Sending Sensor Value
Node-Red Server
Node Red Code
The Node-Red Flow
Freeboard.io Setup
Introduction
Just got your The Things Uno and want to start deploy some simple sensor right away?
Not a web developer or no access to a web server to host your data?
Just want to build a simple dashboard which show immediate information on the Internet?
Here is a simple guide that will focus on how to use Node-Red and Freeboard.io to setup your first TTN sensor dashboard :D
During the tutorial:
- Setting up Arduino IDE
- Simple Temperature sensor
- ABP (Activation By Personalization) on TTN
- Retrieving data from TTN backend via Node-Red
- Display information on public dashboard on the internet via dweet.io and freeboard.io
Setup Arduino IDE
- Download and install Arduino IDE
- Download the latest The Things Uno Arduino Library:
- Navigate to Sketch > Include Library > Manage Libraries....
- Search for TheThingsNetwork and install the library. - Connect the The Things Uno to your computer using the Micro-USB cable
- In the Arduino IDE, go to Sketch > Include Library > Add .ZIP Library and select the downloaded zip file
- Select Tools > Board > Arduino Leonardo
- Select Tools > Port > the port that identifies as Arduino Leonardo. For example, on Mac OS X:
- On Windows, in Control Panel, open the Device Manager to see which COM port you should use.
The Things Network Dashboard
Your applications and devices can be managed by The Things Network Dashboard.
- Create an Account
To use the dashboard, you need a The Things Network account. You can create an account here.
After registering and validating your e-mail address, you will be able to log in to The Things Network Dashboard.
- Create an Application
Create your first The Things Network application by clicking create application. Fill in the desired application name (e.g. <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">Hello world</code>) and click Create application.
You will be redirected to the newly created Application page.
Register Device (ABP)
The Things Network supports the two LoRaWAN mechanisms to register devices: activation by personalization (ABP) and over the air activation (OTAA). In this workshop, we use ABP.
- Register the Device
To register the device, go back to the dashboard and click Register Device on the application page. This will take you to the device registration page.
Select ABP. We will let both session keys to be randomly generated. To continue, click Register.
Now that the device is registered, the device page is shown:
6. Copy the AppKey for later:
- Click the <> so it becomes a #
- Click the eye so the key becomes visible
- Copy the Dev Address
- Copy the Network Session Key
- Copy the App Session Key
Sending Some Data
Configure Device
- In the Arduino IDE, open File > Examples > TheThingsUno > Workshop
- Change your <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">devAddr</code>, <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">nwkSKey</code>, <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">appSKey</code> to the values you can find on the device page in the dashboard. Hint: If you click the <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);"><></code> on the each of the fields on the Device page, their contents are shown as a C-style byte array literal which is extra handy for copy-pasting.
Use the information shown on the device page to fill in following code snippet:
Run The Application on Your Device
- Click Sketch > Verify/Compile and make sure that compilation works (Arduino says Done compiling)
- Click Sketch > Upload (Arduino says Done uploading)
- Go to Tools > Serial Monitor to see the output of your node. This should look like this:
<code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; border-radius: 3px; word-break: normal; white-space: pre; border: 0px; display: inline; overflow: visible; line-height: inherit; word-wrap: normal; background-image: initial; background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">Sending: mac tx uncnf 1 with 3 bytes Successful transmission Sending: mac tx uncnf 1 with 3 bytes Successful transmission ... </code>
Get Your Data
Go back to the dashboard. You should be receiving messages from your device in the Messages component on the device page. The payload you see here are three bytes.
You are sending these three bytes in the <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">loop()</code> function of your Arduino, which currently looks like this:
void loop() { // Create a buffer with three bytes byte data[3] = { 0x01, 0x02, 0x03 }; // Send it to the network ttu.sendBytes(data, sizeof(data)); // Wait 10 seconds delay(10000); }
Sending Sensor Value
Instead of sending three bytes, we're going to send real sensor values. But first, we need to connect our sensors. In this workshop, we're using a light and a temperature sensor.
Connecting Sensors
Both the light and the temperature sensor have three pins to connect: voltage <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">VCC</code>, signal <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">SIG</code> and ground <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">GND</code> (the pin <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">NC</code><code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: inherit;"> </code>is not connected). We are connecting these pins to the 5 Volts output <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">5V</code>, analog pins <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">A0</code> and <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">A1</code> for signal, and ground <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">GND</code> of The Things Uno.
Read Sensors
Now that the sensors are connected, we have to write some code in Arduino to read its values. Use this code snippet that replaces your current <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">loop()</code> function:
uint16_t getLight(int pin) { return analogRead(pin); } float getCelcius(int pin) { // See http://www.seeedstudio.com/wiki/Grove_-_Temperature_Sensor int a = analogRead(pin); float resistance = (1023.0 - a) * 10000 / a; return 1 / (log(resistance/10000)/3975 + 1 / 298.15) - 273.15; } void loop() { // Read the sensors. uint16_t light = getLight(A0); float celcius = getCelcius(A1); // Show the values in the serial monitor for debugging debugPrintLn("Light is " + String(light)); debugPrintLn("Temperature is " + String(celcius)); // To get rid of floating point and keep two decimals, multiply by 100 // e.g. 21.52 becomes 2152 int16_t temperature = (int16_t)(celcius * 100); // We need 4 bytes to send both values byte data[4]; data[0] = light >> 8; data[1] = light & 0xFF; data[2] = temperature >> 8; data[3] = temperature & 0xFF; // Send it to the network ttu.sendBytes(data, sizeof(data)); debugPrintLn(); // Wait 10 seconds delay(10000); }
Then, click Sketch > Upload to update your device.
Click Tools > Serial Monitor to verify that your device is sending sensor values:
<code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; border-radius: 3px; word-break: normal; white-space: pre; border: 0px; display: inline; overflow: visible; line-height: inherit; word-wrap: normal; background-image: initial; background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">Light is 782 Temperature is 19.82 Sending: mac tx uncnf 1 with 4 bytes Successful transmission Light is 779 Temperature is 19.82 Sending: mac tx uncnf 1 with 4 bytes Successful transmission ... </code>
Take a look at the device page on the dashboard. You should see your payload, e.g. <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">03 0B 07 BE</code>.
Unpacking The Bytes
To make working with payloads easier, The Things Network allows you to decode bytes to a meaningful data structure for your application. The payload functions are three functions: the decoder, the converter and the validator.
Here, we will only be using the decoder to decode the bytes your device is sending. Use the optional converter function to convert units (e.g. Celcius to Fahrenheit) and the optional validator function to check whether the payload is valid (e.g. invalidate outliers).
To set up the payload functions, go back to the Application view and click the edit button of Payload Functions. This will bring you to the Payload Function editor.
Here you can view, test and edit the payload functions for your application.
In the decoder section, enter the following to decode the payload. This is basically the reverse of what you did on the Arduino:
function (bytes) { var light = (bytes[0] << 8) | bytes[1]; var temperature = (bytes[2] << 8) | bytes[3]; return { light: light, celcius: temperature / 100.0 }; }
Before saving our payload function we can test it first by entering a test payload in the box below. For example, enter <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">03 0B 07 BE</code> and click Test. The test output should correspond to the temperature value we sent earlier:
{ "celcius": 19.82, "light": 779 }
When you are happy with the output of your payload function, click Save. All incoming messages will now be decoded using these payload functions. You can see if this worked by going back to the device page and looking at the messages. The payload will now be logged in its decoded form.
Node-Red Server
Node-RED allows you to build all kinds of flows with basic business logic. You can add switches, triggers, custom functions and install thousands of nodes with additional functionality, for example storing data in a database.
A common use case is to invoke a HTTP request to an external web service of your application.
To understand more about Node-Red, you can view this Node-Red workshop here.
For Jomhack, we have use a Node-Red Server with TTN library installed.
You can access the sample Node-Red Server here together with all the ready code:
http://mdec2.node-red.thethingslab.com/
To deploy on Nod
- In the dashboard, go to your application and click learn how to get data from this app. You need the AppEUI and Access Key in step 5 and 6
- From the input category in the toolbox on the left, drop a TTN node on your workflow
- Double-click the node named <code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157);">ttn</code>
- Enter as App EUI your App EUI from the dashboard (see step 1)
- Enter as Access Key your Access Key from the dashboard
- Enter as Broker
staging.thethingsnetwork.org
- Click Add
- From the output category, drop a new debug node on the flow and connect the first output of the ttn node to the input of the debug node.
Click Deploy and monitor the debug tab on the right for incoming messages. You will start seeing messages like:
<code style="font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; border-radius: 3px; word-break: normal; white-space: pre; border: 0px; display: inline; overflow: visible; line-height: inherit; word-wrap: normal; background-image: initial; background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">{ "light": 779, "celcius": 19.82 } </code>
Node Red Code
In case the code have been change, or you wish to deploy it over to your own Node-Red Server.
- Make sure the TTN Node-RED library is installed > http://flows.nodered.org/node/node-red-contrib-ttn
- The Node-RED server can access the internet to received data from TTN MQTT server.
Copy the following code to your clipboard
[{"id":"6e8bb698.a5bfd8","type":"ttn","z":"ecf3856a.0ed728","appEUI":"70B3D57ED00009C1","accessKey":"oREDsQ448PHFYVOqYeuXLZlqEwuw9wPpsb6EAvjwDOQ=","broker":"staging.thethingsnetwork.org","name":"ttn","x":50,"y":120,"wires":[["e64fcb95.19b038"],[]]},{"id":"f3ec54ce.0c13a8","type":"debug","z":"ecf3856a.0ed728","name":"","active":true,"console":"false","complete":"payload","x":410,"y":220,"wires":[]},{"id":"e64fcb95.19b038","type":"function","z":"ecf3856a.0ed728","name":"Payload - devEUI","func":"msg.payload.devEUI = msg.devEUI;\n\nreturn {\n payload: msg.payload\n}","outputs":1,"noerr":0,"x":230,"y":120,"wires":[["4366898d.bc9978","f3ec54ce.0c13a8"]]},{"id":"4366898d.bc9978","type":"switch","z":"ecf3856a.0ed728","name":"Split Topic","property":"payload.devEUI","propertyType":"msg","rules":[{"t":"eq","v":"00000000E5D91F60","vt":"str"},{"t":"eq","v":"00000000130D42BB","vt":"str"}],"checkall":"true","outputs":2,"x":410,"y":120,"wires":[["77f5cab9.880a34"],["12c5263f.ed3ada"]]},{"id":"77f5cab9.880a34","type":"function","z":"ecf3856a.0ed728","name":"Create Request 1","func":"return {\n payload: {\n devEUI: msg.payload.devEUI,\n temp: msg.payload.temp,\n light: msg.payload.light\n }\n}","outputs":1,"noerr":0,"x":650,"y":80,"wires":[["810fe74e.7ef018"]]},{"id":"12c5263f.ed3ada","type":"function","z":"ecf3856a.0ed728","name":"Create Request 2","func":"return {\n payload: {\n devEUI: msg.payload.devEUI,\n temp: msg.payload.temp,\n light: msg.payload.light\n }\n}","outputs":1,"noerr":0,"x":650,"y":160,"wires":[["c32f3ce6.3cd0c"]]},{"id":"810fe74e.7ef018","type":"http request","z":"ecf3856a.0ed728","name":"dweet-01","method":"POST","ret":"txt","url":"https://dweet.io/dweet/for/lora-sensor-1","x":820,"y":80,"wires":[[]]},{"id":"c32f3ce6.3cd0c","type":"http request","z":"ecf3856a.0ed728","name":"dweet-02","method":"POST","ret":"txt","url":"https://dweet.io/dweet/for/lora-sensor-2","x":820,"y":160,"wires":[[]]}]
You can then import the code into the Node-Red server by pressing on the top right corner and select import from clipboard.
The Node-Red Flow
Here is the explanation on the Node Red Flow:
- The TTN Node : - You should fill up all the field with your own device/dashboard key.
- Payload - devEUI function : This is use to add in additional information to the message payload the Node-Red going to send out. In this case, we are sending out devEUI of each device as well so the dashboard can display multiple sensor.
- Split Topic function : We use Node-RED switch node function to send each different sensor to a different message topic.
- Create Request function: As we will be using HTTP POST to send out the information to the dashboard, we need to structure our payload in a HTTP Request function.
- Dweet.io function : http://dweet.io/ is a very simple open JSON message publisher/subscriber tool. You can basically send the data over HTTP/HTTPS to dweet.io and then retrieve it through a web based RESTful API. (Please change the URL to something unique for your sensor)
Freeboard.io Setup
Freeboard.io is a free web based Dashboard that enable you to represent your data in a graphical way.
Please create a FREE account in freeboard.io and then we can proceed to create dashboard for our LoRa Sensor.
- Once your create a new user account, and proceed to create a new dashboard, you can then select the data source.
- Press ADD and select Dweet.io as data source and putting in the information as per setup in the Node-RED flow there.
- Press SAVE and if your sensor is currently sending out data via The Things Network, you should see the data start coming in from Data Source and the last updated timestamp will be shown.
- Click Add Pane > + (add widget) > Gauge and key in ‘Temperature’.
- Set the units as ‘C’ and min and max units as ‘0’ and ‘100’ respectively.
- Click Datasource >(name of datasource) >msg > temperature
- Once this is completed, a temperature gauge will be displayed. Do the same for Light as well.
That it, once the sensor data is coming in, the freeboard will display the data in real time :)
You can copy and save the freeboard URL and then share it with other people on your new sensor data dashboard !!!