# Connecting Sensors to the Internet using LoRaWAN Hackday
> 15 July 2017
> public link: https://hackmd.io/s/H1lA3HLrb
> [#LoRaLIV](https://twitter.com/search?q=LoRaLIV)
[TOC]
## Schedule
* from 09:30 — Intros, hellos and general milling around,
* 10:00 — Introduction, running of the day and defining the challenges,
* 10:30 — Join a challenge and start building,
* 12:30 — Lunch,
* 13:00 — Afternoon hacking,
* 16:00 — End.
## Attendees
* [Adrian McEwen](http://mcqn.com) — [@amcewen](http://twitter.com/amcewen)
* [Patrick Fenner](http://defproc.co.uk) — [@DefProc](http://twitter.com/defproc)
## Challenges
It's traditional that hackdays define some challenges to the solved during the day. They provide some guidance and direction, but as one of the outcomes from today is to get some fresh ideas on uses for LoRaWAN, we'll start the day by creating some of our own.
### Temperature Sensor
An initial "hello world" for those new to Arduino, or those looking for a base to start from.
Using a DS18B20 temperature sensor, take a reading, report 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:
* [Arduino IDE](https://www.arduino.cc/en/Main/Software)
* [TTN library](https://github.com/TheThingsNetwork/arduino-device-lib)
* `Sketch` → `Include Library` → `Manage Libraries` → `The Things Network` → `install`
Device Info sketch for the Uno & shield:
```clike=
#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](https://account.thethingsnetwork.org/register),
* go to the [TTN console](https://console.thethingsnetwork.org/)
* 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:
```clike=
#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](https://www.pjrc.com/teensy/td_libs_OneWire.html) and [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library) 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:
:::info
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](https://www.thethingsnetwork.org/docs/devices/bytes.html)
:::
```clike=
#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](console.thethingsnetwork.org) for your application set the `Payload Formats` to be `Cayenne LPP`,
* create an account at [myDevices Cayenne](https://mydevices.com/cayenne/signup/)
* `Add new` → `Devices & Wigets` → `LoRa (beta)` → `The Things Network` → `Cayenne 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](https://www.thethingsnetwork.org/docs/applications/nodered/quick-start.html) provided more flexibility in pricessing and using messages.
### IoT Doorbell
Trying to find the most pointless usage for LoRaWAN:
> The #IoT #doorbell. Button -> #LoRaWAN -> #thethingsnetwork -> #mqtt -> #nodered -> #wifi -> the #ackers_bell #weeknotes #LoRaLiv
@amcewen: [instagram.com/p/BWkOpeNlqDC](https://www.instagram.com/p/BWkOpeNlqDC/)
Because adding LoRaWAN gives you a doorbell that will still work if you take the button to the other side of the country!
Uses the LoRaWAN connected [City Dash Button](https://github.com/mcqn/CityDash/), takes the MQTT message from TTN, through a [node-red](http://nodered.org) flow to trigger the wifi connected [Ackers Bell](https://twitter.com/ackers_bell).
## LMIC LoRa→LoRaWAN Adafruit Feather
Using the LMIC library to send LoRaWAN packets using the Adafruit Feather (M0 processor plus RFM95 LoRa radio).
Arduino IDE set up - https://learn.adafruit.com/adafruit-feather-m0-radio-with-lora-radio-module/setup
Arduino LMIC library - https://github.com/matthijskooijman/arduino-lmic
Lora set up guide (but for different network) - https://startiot.telenor.com/learning/getting-started-with-adafruit-feather-m0-lora/
And - https://wolfgangklenk.wordpress.com/2017/04/15/adafruit-feather-as-lorawan-node/
Using GPS inputs: https://github.com/ttn-liv/range-tracking/blob/master/console/payload_function.js
Notes:
```
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
```
## Make a Twine Game using LoRaWAN
Used [@davemee](https://twitter.com/davemee) [Twine-node-red](https://github.com/davemee/TwineNodered). We got partway there! More at cheapjack's [fork](https://github.com/cheapjack/TwineNodered)
### 433 to LoRaWAN bridge
Take a 433MHz radio input and pass the pulse length array remotely via LoRaWAN.
Although sucessful, the pulse length information is quite variable in lenght, and so should be better parsed on the payload end. Otherwise, if a more compact way of transferring the data was used, this would make for a very low power 433MHz scanner.
## Untackled challenges
* TTN mapping coverage
* Set-up a gateway
* Air quality measurement
* Health & Social Care solutions
* Flooded room monitoring and alerting
* Autonomous sensor