Low-cost LoRa IoT device:
a step-by-step tutorial
Prof. Congduc Pham
http://www.univ-pau.fr/~cpham
Université de Pau, France
Contents
q We will show how to build a low-cost IoT device
for sensing surveillance applications using LoRa
radio technology
q The gateway part will be shown in a separate
tutorial
q The target hardware platform is an Arduino Pro
Mini in its 3.3v, 8MHz version: the original from
Sparkfun or a clone from various providers
q Let’s get started…
2
Assembling the hardware
3
Get the Arduino board
Be sure to get the 3.3v and
8MHz version
You can get the original board designed by Sparkfun or get one of the various clones
available mainly from Chinese manufacturer. The last solution is very cost-effective as the
Pro Mini board can be obtained for less than 2€ a piece. Some boards may not be working
as reported by some people but in my own experience, all the boards I got from Chinese
manufacters have been working great.
4
Prepare the board (1)
When you receive the board, it will probably come with the appropriate
header pins that must be soldered to the board. Just use a regular soldering
station to solder the header pins to the board. The 6-pin header on one side
of the board (see red rectangle) will be used to connect an FTDI cable to
program the board. This will be explained in the « software » section.
5
Prepare the board (2)
You can solder a row of header pins (left) on the ground pin (GND) in order
to have several ground pins for the various sensors that will be connected
to the device. But don’t forget to link all the pins together to get the GND
signal on all the pins (right).
6
Now the radio module (1)
GND
CS
CLK
MISO
MOSI
VCC
If you go for the inAir9 from Modtronix, then the header pins can come fully assembled.
Order with the 6mm header pins to have enough length to connect F/F breadboard
cables (left). Connect the SPI pins with the F/F cables. Try to use different colors. I use
the following colors: MOSI (blue), MISO (green), CS (white), CLK (orange). Then
connect also the VCC (red) and the GND (black or any other dark color) of the radio
board. 7
Now the radio module (2)
GND
MISO
MOSI
CLK
CS VCC
If you take the HopeRF RFM 92W/95W
you may need the adaptor breakout and
to go though some delicate but simple
soldering tasks! It is not difficult but you
have to trained a bit before! Then, like
for the inAir9, use F/F breadboard cable Another breakout from Tindie
https://www.tindie.com/products/leon
to connect the SPI pins, using different ahi/rfm95-lora-breakout-board/
colors as explained previously.
Another breakout from
https://github.com/ccadic/RFM95LORA_Breadboard
8
The WaziHat PCB
q WAZIUP has a simple RFM95 breakout mainly for
the gateway, but can be used for devices
q Contact A. Rahim (arahim"at"fbk.eu) for
more information
Short WAZIHAT version 9
Freely available RFM95
breakout
q We also propose a very simple RFM95 breakout
that can be used for gateway and end-device
q The zipped Gerber archive can be
freely downloaded from
https://github.com/CongducPham/LowCostLoRaGw
10
Connecting the radio
module
GND CAUTION: the radio
module needs 3.3v, not 5v!
Most of Arduino boards
have a 3.3v pin so you can
use this pin to power the
radio module. Example wth
an Arduino Nano:
MISO
CLK
CS
MOSI
VCC
3.3v
GND
CS
Now, just connect the corresponding SPI pins of the radio module
to the SPI pins on the board. MOSI (blue) is pin 11, MISO (green)
is pin 12, CS (white) is pin 10 and CLK (orange) is pin 13 (left
picture). Then connect also the VCC (red) and the GND (black) of
the radio board to the VCC and the GND of the board (right
CLK
MISO
MOSI
VCC
picture). The VCC of the board gets 3.3v from the on-board
voltage regulator.
11
Connecting the radio
module on other boards
q If you use other Arduino boards, check on the
specific Arduino web page where are the SPI
pins. Example with Arduino MEGA:
SPI: 50 (MISO), 51 (MOSI), 52 (SCK). These pins support SPI
communication using the SPI library. The SPI pins are also broken out
on the ICSP header, which is physically compatible with the Arduino
/Genuino Uno and the old Duemilanove and Diecimila Arduino boards.
12
Connecting the SPI CS
q The SPI Chip Select (CS) or SS (Slave Select) of
the radio module needs to be connected to a
specific pin on the board.
q Starting from November 3rd, 2017, the CS pin is
pin 10 for all Arduino boards regardless of their
size
13
Low-cost integration
with simple, free PCB
Arduino Pro Mini @3.3V
1.5€ https://github.com/CongducPham/LowCostLoRaGw#pcbs
With integrated antenna
https://github.com/FabienFerrero/UCA_Board
4€
https://github.com/hallard/Mini-LoRa
14
Boards with integrated
LoRa radio module
q Most of boards with integrated LoRa module use
the HopeRF RFM9x
Ideetron Nexus. CS pin is pin 10
Adafruit Feather 32u4/M0
CS pin is pin 8
IoT-MCU LoRa radio node. CS pin is pin 10
Heltec LoRa. CS pin is pin 18
15
Getting, compiling &
uploading the software
16
Getting the software
Fisrt, you will need the Arduino IDE 1.6.6 or later (left). Get the entire ZIP archive of the
LowCostLoRaGw github repository at https://github.com/CongducPham/LowCostLoRaGw
Unzip the archive and copy the content of the Arduino folder in your Arduino IDE sketch folder
If you already have a libraries folder in your sketch folder, copy the content of the new libraries
folder in your libraries folder
17
Compiling
Open the Arduino_LoRa_Simple_temp sketch and select the Arduino Pro Mini board with its 3.3V
& 8MHz version.
Then, click on the « verify » button
18
Uploading (1)
Some clone version, check the VCC pin
VCC
Original Sparkfun version
For the Pro Mini, you need to have an FTDI breakout cable working at 3.3v level (there is also 5v
version but our advised Pro Mini version is running at 3.3v to reduce energy consumption). Be
careful, on some low-cost Pro Mini version (Chinese manufacturer for instance) the pins may be
in reversed order. The simplest way in to check the VCC pin and make it to correspond to the
VCC pin of the FTDI breakout.
19
Uploading (2)
Connect the USB end to your computer and the USB port should be detected in the Arduino IDE.
Select the serial port for your device. It may have another name than what is shown in the
example. Then click on the « upload » button
20
Generic behavior
setup
Physical Physical Physical
sensor sensor sensor measure
reading reading reading xxxxxx
(encrypt)
transmit
Physical Activity duty-
sensor cycle, low sleep
management power
Arduino Pro Mini @3.3V
wake-up
AES Long-range Logical sensor
encryption transmission management
21
Serial monitor and checking
that device is sending
You can see the output from the sensor if it is connected to your computer. Use the Arduino IDE
« serial monitor » to get such output, just to verify that the sensor is running fine, or to debug new
code. Be sure to use 38400 baud. If you get the "Packet sent, state 0" result, it is most likely that
your device is sending OK, but to be sure, you need to check data reception on the gateway.
22
Setting PA_BOOST
q The Semtech SX1272/76 has actually 2 lines of RF
power amplification (PA): a high efficiency PA
up to 14dBm (RFO) and a high power PA up to
20dBm (PA_BOOST)
q Some radio modules only wire the PA_BOOST
and not the RFO: RFM95 for instance has only
PA_BOOST line
Uncomment the « #define PABOOST » statement, compile and upload again
23
More platforms are
supported!
Ideetron Nexus Teensy3.1/3.2
More to come…
Adafruit Feather 32u4/M0
LoRa radios that
our library already
HopeRF Modtronix NiceRF
supports Libelium LoRa
RFM92W/95W inAir9/9B LoRa1276
Long-Range communication library
24
LoRa radios that
our library already
HopeRF Modtronix NiceRF
supports Libelium LoRa
RFM92W/95W inAir9/9B LoRa1276
Arduino Due
Arduino MEGA2560 w/Libelium
Arduino Uno Multiprotocol shield
Arduino Pro Mini
Arduino Nano
Arduino Due
Ideetron Nexus Teensy3.2
RFM95W
25
Adding a physical sensor
26
Temperature sensor
OUT
VCC
VCC
GND
RADIO
OUT
For the moment, there is no physical sensor connected to the board, so you will probably get
random value when running the sensor. The Arduino_LoRa_Simple_temp example uses the
LM35DZ physical sensor to get the ambient temperature. The GND should be connected to one
of the board’s GND, the VCC should be connected to digital pin 9 and the OUT pin should be
connected to the analog A0 pin.
27
Understanding analog
output
Vcc is 3.3V (the output of digital 9 will power the sensor)
If 0 means 0V and 1024 means 3300mV (10-bit resolution) then 3300mV/1024=3.22mV is the
granularity of the measure
A digital value of 100 means 100*3.22mV=322mV
If the sensor output is 10mV/1°C then the physical temperature is 322mV/10mV=32.2°C
28
Reading analog pin value
OUT
// sensor output connected to A0 analog pin
value = analogRead(A0);
// now need to convert to Celcius degree
And converting into Celcius
Temp = value * 3300.0/1024.0; // 3300/1024=3.22
Temp = Temp / 10; // 10mV means 1°C
// now process and transmit the data
29
Generalization
q Depending on the sensor type, getting the physical measure
from the analog/digital value follows a specific function provided
by the sensor’s manufacturer
q Depending on the microcontroller board, the number of I/O pins
and the operating voltage may differ
q However the process is always the same:
q Connect the sensor to the microcontroller board
q Read analog or digital pin
q Convert read value into meaningful physical measure
q Then process and/or transmit
30
Several physical
sensors per device
Physical sensor will be derived from Sensor
base class and offers a unique
get_value() function that will be called
periodically
A sensor with several physical sensor will
simply loop over all the connected sensors to
call the get_value() function
Several physical sensors can be connected to a board. Currently supported sensors:
All simple analog sensors (value on 1 analog wire: e.g. LM35Z temp. sensor or Davis leaf
wetness Vantage)
All simple digital sensors (binary value low/high)
Most of one-wire digital sensor such as DHT22 sensor
For specific sensors, get_value() will simply use specific provided/developped library
31
Running on battery &
using low-power mode
32
Connecting a battery
- +
Remove the power led
GND
VCC
GND
VCC
as explaine here:
http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/
The advantage of using the Arduino Pro Mini running at 3.3v is that energy consumption can be
low especially when the board is put in « sleep mode » for low-power operation. Remove the
power led to further reduce consumption.
You can use 4 AA batteries to provide 4x1.5v=6v. Using only 3 batteries may lead to insufficient
voltage difference.This will be injected into the RAW pin of the board, therefore using the on-
board voltage regulator to get the 3.3v.
33
Compiling for low-power
Uncomment the « #define LOW_POWER » statement, compile and upload
Change the value of idlePeriodInMin to X minutes if needed
34
Reducing further power
consumption
By removing the voltage regulator, you can use a
single 3.6v Lithium-based battery or 2 regular AA
batteries that provides about 3.1v
You can use the VCC pin on the programming
header to power the board, as the other VCC pin
is needed for the radio module
In sleep mode, the board now draws about 12uA,
allowing for much longer lifetime
35
Running for several
years!
Low-Power library from RocketScream
Wakes-up every
10min, take a
measure (temp) and
Can run for more than 1 year send to GW
with 1 measure/10min
Can run for several years
2500mAh with 1 measure/1h
5μA in deep sleep
mode, about
40mA when active
and sending!
Thanks to T. Mesplou and P. Plouraboué for their help 36
Sending to a gateway
37
Default configuration
\!##TC/18.5
#define DEFAULT_DEST_ADDR 1
#define LORAMODE 1
#define node_addr 6
The default configuration in the Arduino_LoRa_Simple_temp example is:
Send packets to the gateway (one or many if in range)
LoRa mode 1
Node short address is 6
38
Securing with
Application Key (1)
q End-device can use application key (app key) on 4 bytes
to allow filtering mechanisms at the gateway side.
q The app key is defined in the end-device sketch
(Arduino_LoRa_temp) and the feature is activated by
uncommenting #define WITH_APPKEY
#ifdef WITH_APPKEY
///////////////////////////////////////////////////////////////////
// CHANGE HERE THE APPKEY, BUT IF GW CHECKS FOR APPKEY, MUST BE
// IN THE APPKEY LIST MAINTAINED BY GW.
uint8_t my_appKey[4]={5, 6, 7, 8};
///////////////////////////////////////////////////////////////////
#endif
q At the gateway side, post_processing_gw.py has a list of
allowed app key
app_key_list = [
#change/add here your application keys
'\x01\x02\x03\x04',
'\x05\x06\x07\x08' ]
39
Securing with
Application Key (2)
q With app key enforcement at gateway, all LoRa data to be
uploaded on clouds will need a valid app key, otherwise the
data will be discarded as shown below:
--- rxlora. dst=1 type=0x12 src=6 seq=136 len=17 SNR=9 RSSIpkt=-56
rcv ctrl pkt info (^p): 1, 18, 6,136,17,9,-56
splitted in: [1, 18, 6, 136, 17, 9, -56]
(dst=1 type=0x12 src=6 seq=136 len=17 SNR=9 RSSI=-56)
got first framing byte
--> got app key sequence
app key is: [9, 10, 11, 12]
not in app key list
invalid app key: discard data
q This is configured in the gateway_conf.json file. Set to true
40
How to use app key
q App key can be used to differenciate data from
one organization to another
q Sensing devices of a given organization will use the
same app key
q The gateway is configured to only accept this app key
q App key can be used to distribute the gateway
task in case several gateways in the same
organization are deployed
q Sensing devices will be caterorized with 2 app key
q Each gateway will allow only one of these 2 app key
q In this way, data that can be received by 2 gateways
will be processed by only 1 gateway
41
Securing by encryption
(1)
q Arduino_LoRa_temp is an extended version of
Arduino_LoRa_Simple_temp with data
encryption feature.
q Data will be encrypted using 128-bit AES
algorithm following the LoRaWAN encryption
method.
q Uncomment #define WITH_AES
42
Securing by encryption
(2)
q Encryption ensures confidentiality. The two 16-
byte encryption keys are defined in the end-
device sketch (Arduino_LoRa_temp)
q And should also be declared in the loraWAN.py
script on the gateway
AppSKey = '2B7E151628AED2A6ABF7158809CF4F3C'
NwkSKey = '2B7E151628AED2A6ABF7158809CF4F3C'
43
Securing by encryption
(3)
q With encryption at device and decryption at gateway, there is
more robust integrity check of the messages.
q Note that app key can still be used with AES, even if different
gateways may have different encryption keys.
q To enable decryption at gateway, AES feature should be
activated (set to true) in the gateway_conf.json file.
q Otherwise, the gateway will not be able to decrypt and
therefore will not be able to push meaningfull data to clouds
44
Gateway to cloud
Data received at the gateway will be pushed to IoT clouds. We provide python script examples
for many IoT cloud platforms. Most of clouds with REST API can be easily integrated.
Now, have a look at the « Low-cost LoRa gateway: a step-by-step tutorial »
45