Now there’s a larger coverage area of LoRaWAN in Liverpool that provides free access to the public The Things Network service, it’s the ideal time to start connecting more devices, more sensors, and taking advantage of this long range, low power, low cost way of connecting devices to the internet.

The great Arduino library from The Things Network means that getting started with using LoRaWAN is just a matter of finding coverage and a LoRaWAN modem. At the current time though, the TTN hardware has not started shipping, so we made some LoRaWAN shields, and ran a hackday at DoES Liverpool to get more people connected.

As is traditional in hackdays, progress on the day was captured in a shared document. While the main focus for many was on setting up their first LoRaWAN connection, and finding out how LoRaWAN might fit in with their project ideas, there were some great projects taking shape.

Links to the shared document:

Temperature Sensor

One of my focues of the day was to complete an initial hello world for those new to Arduino, or those looking for a base to start using LoRaWAN that goes from sensor to online recording.

Using a DS18B20 temperature sensor, take a reading, report it over LoRaWAN to The Things Network (TTN) using the Cayenne payload structure, set the payload interpreter to Cayenne, connect to myDevices Cayenne, and create a dashboard to show current temperature.

Getting started:

Device Info sketch for the Uno & shield:

#include <TheThingsNetwork.h>
#include "SoftwareSerial.h"

// RN2483 pins on the LoRaWAN shield
#define RN_RX 2
#define RN_TX 3

//#define lora Serial1
SoftwareSerial lora(RN_RX, RN_TX); // RX, TX

#define debugSerial Serial
#define loraSerial lora

TheThingsNetwork ttn(loraSerial, Serial, TTN_FP_EU868);

void setup()
{
  debugSerial.begin(115200);
  loraSerial.begin(57600);
  delay(1000);
}   

void loop()
{
   debugSerial.println("Device Information");
   debugSerial.println();
   ttn.showStatus();
   debugSerial.println();
   debugSerial.println("Use the EUI to register the device for OTAA");
   debugSerial.println("-------------------------------------------");
   debugSerial.println();
   delay(10000);
}
  • Make an account on The Things Network,
  • go to the TTN console
  • select applications and + add application
  • Set
    • Application ID (you’ll need to use when you use the application),
    • Description (up to you)
    • Handler registration to ttn-handler-eu
  • From your application page, + register device
    • Device ID (something you can uniquely identify that radio with),
    • Device EUI (reported from the sketch above),
  • Then load a basic sketch onto your device to test the data transfer:
#include <TheThingsNetwork.h>
#include "SoftwareSerial.h"

// Set your AppEUI and AppKey
const char *appEui = "0000000000000000"; // replace with your `App EUI`
const char *appKey = "00000000000000000000000000000000"; // replace with your `App Key`

// RN2483 pins on the LoRaWAN shield
#define RN_RX 2
#define RN_TX 3

//#define lora Serial1
SoftwareSerial lora(RN_RX, RN_TX); // RX, TX

#define debugSerial Serial
#define loraSerial lora

TheThingsNetwork ttn(loraSerial, Serial, TTN_FP_EU868);


void setup()
{
   loraSerial.begin(57600);
   debugSerial.begin(115200);

   // Wait a maximum of 10s for Serial Monitor
   while (!debugSerial && millis() < 10000)
     ;

   debugSerial.println("-- STATUS");
   ttn.showStatus();

   debugSerial.println("-- JOIN");
   ttn.join(appEui, appKey);
}

void loop()
{
   debugSerial.println("-- LOOP");

   // Prepare payload of 1 byte to indicate LED status
   byte payload[1];
   payload[0] = (digitalRead(LED_BUILTIN) == HIGH) ? 1 : 0;

   // Send it off
   ttn.sendBytes(payload, sizeof(payload));

   delay(10000);
}
  • Load the sketch and watch on the serial monitor
  • Also watch on the data tab to see the incoming data

Send temperature:

  • Add the OneWire and DallasTemperature libraries to the Arduino IDE,
  • Connect the DS18B20 sensor to power, ground, and the signal wire to pin D6 on the arduino (or another of your choice),
  • connect a 4.7k resistor between power and the signal line (this is requred for proper opperation of the sensor, but in a pinch you’ll probably get away with two 10k resistors in parallel),
  • load the following sketch (after changing the appEui and appKey) to match your application:

This example uses the Cayenne LPP format so it can be recreated back into a JSON objects without having to do any custom float to byte array translation or javascript re-building

#include <SoftwareSerial.h>
#include <TheThingsNetwork.h>
#include <CayenneLPP.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Set your AppEUI and AppKey
const char *appEui = "0000000000000000";
const char *appKey = "00000000000000000000000000000000";

// RN2483 pins on the sensor dev shield
#define RN_RX 3
#define RN_TX 4

// Data wire is plugged into port 6 on the Arduino
#define ONE_WIRE_BUS 6

SoftwareSerial lora(RN_RX, RN_TX); // RX, TX

#define loraSerial lora
#define debugSerial Serial

TheThingsNetwork ttn(loraSerial, debugSerial, TTN_FP_EU868);
CayenneLPP lpp(51);

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// arrays to hold device address
DeviceAddress deviceAddress;

void setup()
{
   loraSerial.begin(57600);
   debugSerial.begin(115200);

   // Wait a maximum of 10s for Serial Monitor
   while (!debugSerial && millis() < 10000)
     ;

   // Get device address
   if (!sensors.getAddress(deviceAddress, 0)) Serial.println("Unable to find address for Device 0");

   // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
   sensors.setResolution(deviceAddress, 12);

   debugSerial.println("-- STATUS");
   ttn.showStatus();

   debugSerial.println("-- JOIN");
   ttn.join(appEui, appKey);
}

void loop()
{
   debugSerial.println("-- LOOP");

   // get the current temperature
   sensors.requestTemperatures();
   float degC = sensors.getTempC(deviceAddress);
   debugSerial.println(degC, 6);

   lpp.reset();
   lpp.addTemperature(1, degC);

   // Send it off
   ttn.sendBytes(lpp.getBuffer(), lpp.getSize());

   delay(30000);
}
  • New messages should appear in the application, data on the console with the a "temperature_1: xx.x" visible in the processed payload,
  • in the Things Network Console for your application set the Payload Formats to be Cayenne LPP,
  • create an account at myDevices Cayenne
  • Add newDevices & WigetsLoRa (beta)The Things NetworkCayenne LPP
  • Enter the Device EUI from the TTN console,
  • Back on the TTN console for the application → Applications+ add integration → choose Cayenne,
    • Enter a Process ID of your choice (anything),
    • Select an Access Key (one of the allowed MQTT passwords on the application to pass to Cayenne)
  • new data from this device will automatically propogate to myDevices Cayenne, so entries for temperature, RSSI and SNR for this device will appear when it next sends.
  • many attendees found that receiving mesages using node-red provided more flexibility in pricessing and using messages.