We're sending sensory data with a LoRaWAN node through a TTN gateway in order to connect a simple webservice with our own TTN API
- Arduino Mega 2560 (2x Serial (debug, com))
- Dragino LoRa GPS Shield + Dragino LoRa Bee v1.0
- USB cable
- Running IDE (Arduino, Atom, ..)
- Sensors, jumpers and optional breadboard (in this case we're using a proximity sensor)
- Computer running Windows 7 or higher, Mac OS X or Linux
- A running TTN Gateway
In order to use the .ino you'll need this library:
- install it using the Arduino Library manager ("Sketch" -> "Include Library" -> "Manage Libraries..."), or
- download a zipfile from github using the "Download ZIP" button and install it using the IDE ("Sketch" -> "Include Library" -> "Add .ZIP Library..."
- clone this git repository into your sketchbook/libraries folder.
For more info, see https://www.arduino.cc/en/Guide/Libraries
> On Windows, you might need to [install drivers](https://www.arduino.cc/en/Guide/ArduinoLeonardoMicro#toc2).
Manage your applications and devices via The Things Network Console.
To use the console, you need an account.
- Create an account.
- Select Console from the top menu.
Add your first The Things Network Application.
-
In the console, click add application.
- For Application ID, choose a unique ID of lower case, alphanumeric characters and nonconsecutive
-
and_
(e.g.hi-world
). - For Application Description, enter anything you like (e.g.
Hi, World!
).
- For Application ID, choose a unique ID of lower case, alphanumeric characters and nonconsecutive
-
Click Add application to finish.
You will be redirected to the newly added application, where you can find the generated Application EUI and default Access Key which we'll need later.
If the Application ID is already taken, you will end up at the Applications overview with the following error. Simply go back and try another ID.
The Things Network supports the two LoRaWAN mechanisms to register devices: Over The Air Activation (OTAA) and Activation By Personalization (ABP). In this workshop, we will use ABP.
In production, you'll want to use OTAA, which is the default. This is more reliable because the activation will be confirmed and more secure because the session keys will be negotiated with every activation. ABP is useful for workshops because you don't have to wait for a downlink window to become available to confirm the activation.
-
On the Application screen, scroll down to the Devices box and click register device.
-
Click Register.
You will be redirected to the newly registered device.
-
On the device screen, select Settings from the top right menu.
-
You can give your device a description like
My Uno - Workshop
-
Change Activation method to ABP.
-
Uncheck Frame counter checks at the bottom of the page.
Note: This allows you to restart your device for development purposes without the routing services keeping track of the frame counter. This does make your application vulnerable for replay attacks, e.g. sending messages with a frame counter equal or lower than the latest received. Please do not disable it in production.
-
-
Click Save to finish.
You will be redirected to the device, where you can find the Device Address, Network Session Key and App Session Key that we'll need next.
Activate your device and send your first byte to verify that it works.
-
In the Arduino IDE, select File > Examples > TheThingsNetwork > SendABP.
-
Set the values for
devAddr
,nwkSKey
andappSKey
using the information from the device in the console. Use the ๐ buttons next to fields to copy their (hidden) value.- For
devAddr
use the Device Address. - For
nwkSKey
use the Network Session Key. - For
appSKey
use App Session Key.
- For
-
Change the line
#define freqPlan REPLACE_ME
to:#define freqPlan TTN_FP_EU868
If you use a device with the RN2903 LoRa module, then use
TTN_FP_US915
instead.
-
Select Sketch > Upload
Ctrl/โ U
to upload the sketch.Wait for the status bar to say Done uploading.
-
Select Tools > Serial Monitor
Ctrl/โ Shift M
to open the Serial Monitor.Soon, you should see something like this:
Sending: mac tx uncnf 1 010203 Successful transmission
From the device or application in the console, select Data in the top right menu. You should soon see the messages come in. Click on the blue โถ to see all data:
As you can see you are sending 1 byte. In the sketch you have uploaded you can find we do this in the loop()
function:
void loop() {
byte payload[1];
payload[0] = (digitalRead(LED_BUILTIN) == HIGH) ? 1 : 0;
// Send it off
ttn.sendBytes(payload, sizeof(payload));
}
Instead of sending 1 byte, we're going to send real sensor data. But first, we need to connect our sensors. In this workshop, we will use a temperature sensor.
Use the Grove to 4-pin Male cables to connect the temperature and the button or water sensor:
-
Connect the black
GND
(ground) to one of the 3GND
on the Uno. -
Connect the red
VCC
(voltage) to the3v3
and5V
on the Uno (connect the temperature sensor to the 5V). -
Connect the yellow
SIG
(signal) to the Uno:- For the temperature sensor use an analog input:
A2
. - For the button or water sensor use a digital input:
2
from the group labeled as Digital.
- For the temperature sensor use an analog input:
Now that the sensors are connected, we have to write some code in the sketch to read their values.
-
Replace your
loop()
function with the following code:// See http://www.seeedstudio.com/wiki/Grove_-_Temperature_Sensor float getCelcius(int pin) { int a = analogRead(pin); float resistance = (1023.0 - a) * 10000 / a; return 1 / (log(resistance/10000)/3975 + 1 / 298.15) - 273.15; } bool wasPressedOrWet = false; void loop() { // Read digital sensor bool pressedOrWet = (digitalRead(2) == LOW); // State unchanged if (pressedOrWet == wasPressedOrWet) { return; } wasPressedOrWet = pressedOrWet; // Not pressed or wet if (!pressedOrWet) { return; } // Read the temperature float celcius = getCelcius(A2); // Log the value debugSerial.print("Temperature: "); debugSerial.println(celcius); // Encode float as int (20.98 becomes 2098) int16_t celciusInt = round(celcius * 100); // Encode int as bytes byte payload[2]; payload[0] = highByte(celciusInt); payload[1] = lowByte(celciusInt); ttn.sendBytes(payload, sizeof(payload)); }
-
Select Sketch > Upload
Ctrl/โ U
. -
Select Tools > Serial Monitor
Ctrl/โ Shift M
.When you press the button or place your finger on the water sensor you should see something like:
Temperature: 18.58 Sending: mac tx uncnf 1 0742 Successful transmission
-
Switch back to the Data screen in the console to verify you see the payload (here:
0742
) come in when you press the button.
The Things Network allows you to decode bytes to a meaningful data structure before passing it on to your application.
We will only use the decoder in this workshop. You can also use a converter to combine values or convert units and a validator to drop invalid payloads.
-
From the application in the Console, select Payload Functions from the top right menu.
-
Leave decoder selected and copy-paste the following JavaScript code:
function Decoder(bytes, port) { // Decode an uplink message from a buffer // (array) of bytes to an object of fields. var decoded = {}; // Decode bytes to int var celciusInt = (bytes[0] << 8) | bytes[1]; // Decode int to float decoded.celcius = celciusInt / 100; return decoded; }
-
Enter the bytes you saw in the Serial Monitor (e.g.
0832
in the Payload input and click Test.You should get an object with the temperature in celcius. For
0832
this would be:{ "celcius": 20.98 }
-
Click Save payload functions.
-
Select Data from the top right menu to see how the next payloads will be decoded:
A common use case is to invoke an HTTP request to an external web service. for this workshop we are going to process the sensor data and send it to IFTTT (If This Then That) to trigger an event of your own choice.
IFTTT is a free web-based service that you can use to create simple conditional statements, called applets. An applet is triggered by changes that occur within other web services such as Gmail, Facebook, Instagram, or The Things Network.
Let's start on IFTTT.
-
Go to IFTTT and create an account or login.
-
Select New Applet from your account menu.
-
Click This to Choose Trigger Channel.
- Search for
maker
. - Click the Maker channel.
The first time you'll need to click Connect, then Done in the popup that opens and finally Continue to the next step.
- Search for
-
Click Receive a web request.
- For Event Name, let's enter
workshop
.
- For Event Name, let's enter
-
Click That to configure an action, e.g. post a tweet on Twitter, e-mail or a notification to your phone.
Use the field
Value1
as ingredient. For example, a tweet could be:The temperature is: {{Value1}} #thethingsnetwork
-
Click Create action.
-
Click Finish. Good job! You created the Applet on IFTTT. The only thing you have to do now it connect The Things Network to your Applet and trigger the event with the sensor data.
-
Go back to your application in the Console and click on Integrations.
-
Add as a new integration the IFTTT Maker.
-
Think of a fancy Process ID, like
temperature-tweet
and fill in the Event Name you just created on IFTTT. -
To find your secret Key, go to ifttt.com/maker and then Settings. Your key is the last part of the URL (after
/use/
) -
As Value 1 write
celcius
Make sure you don't accidentally add a space before or aftercelcius
-
Click on Add Integration to finalize the integration.
It's time for a live demonstration. It's important to gather a small audience which you can impress with your end-to-end IoT application.
Now, use the button or water sensor to trigger the action you have configured on IFTTT.
You can even go one level further. Maybe you only want to activate the IFTTT event when the temperature is above or below a certain degree. You can enable or disable the trigger in the Decoder of the Payload Fuctions (remember where to find this?).
For doing so, you need to add the code before the return decoded;
decoded.trigger = decoded.celcius > 20;
You can replace the > 20
with any value that you want to set as the minimal temperature to activate the trigger.
๐ Congratulations! You just learned how to create an account, an application, register a device, send data from a device, decode it, process it and push it to IFTTT to connect to the world of APIs.
From this starting point, you can start building a real world application. Here are some useful links:
-
Visualize your data in a nice dashboard using the Cayenne - myDevices integration.
-
Send messages back to the device to control an LED
-
Create your own charts and maps, e.g. combine our Socket.io example with Flot or Google Maps API.
-
Integrate with IoT cloud platforms like Azure IoT Hub and AWS IoT.