Difference between revisions of "LoraWanNode"

From RevSpace
Jump to navigation Jump to search
Line 79: Line 79:
 
While taking the train from Leeuwarden to Gouda, I decided to transmit from the train onto the LoRa gateways in the neighborhood of Utrecht on the way home.
 
While taking the train from Leeuwarden to Gouda, I decided to transmit from the train onto the LoRa gateways in the neighborhood of Utrecht on the way home.
  
This was also a test for me for the device registration process, see also [https://www.thethingsnetwork.org/wiki/Backend/ttnctl/QuickStart this quickstart].
+
This was also a test for me for the device registration process, see also [https://www.thethingsnetwork.org/wiki/Backend/ttnctl/QuickStart this ttnctl quickstart].
 
I registered another personalized device.
 
I registered another personalized device.
  
Line 86: Line 86:
 
* the NwkSKey and AppSKey
 
* the NwkSKey and AppSKey
  
To register the device, do
+
To register the device, run:
<pre>./ttnctl-linux-amd64 devices TODO</pre>
+
<pre>ttnctl devices TODO</pre>
  
 
The NwkSKey and AppSKey are the ones that see when you do
 
The NwkSKey and AppSKey are the ones that see when you do
<pre>./ttnctl-linux-amd64 devices info 19800501</pre>
+
<pre>ttnctl devices info 19800501</pre>
 
I didn't need to do any reversing of bytes or anything like that, just copy the hex string into the Arduino code.
 
I didn't need to do any reversing of bytes or anything like that, just copy the hex string into the Arduino code.
  
 
To listen using the ttnctl utility, it's simply:
 
To listen using the ttnctl utility, it's simply:
<pre>./ttnctl-linux-amd64 subscribe
+
<pre>./ttnctl subscribe
 
   INFO Subscribing to uplink messages from all devices in application 70B3D57ED000078A
 
   INFO Subscribing to uplink messages from all devices in application 70B3D57ED000078A
 
   INFO Subscribed. Waiting for messages...     
 
   INFO Subscribed. Waiting for messages...     
Line 105: Line 105:
  
 
To see the message in plain text, add the --plain option:
 
To see the message in plain text, add the --plain option:
<pre>./ttnctl-linux-amd64 subscribe --plain
+
<pre>./ttnctl subscribe --plain
 
   INFO Subscribing to uplink messages from all devices in application 70B3D57ED000078A
 
   INFO Subscribing to uplink messages from all devices in application 70B3D57ED000078A
 
   INFO Subscribed. Waiting for messages...     
 
   INFO Subscribed. Waiting for messages...     
Line 122: Line 122:
 
To listen on the MQTT stream:
 
To listen on the MQTT stream:
 
<pre>mosquitto_sub -h staging.thethingsnetwork.org -p 1883 -t +/devices/+/up -u <application EUI> -P <application access keys></pre>
 
<pre>mosquitto_sub -h staging.thethingsnetwork.org -p 1883 -t +/devices/+/up -u <application EUI> -P <application access keys></pre>
 +
 +
The application EUI and application access keys are the ones that you see when you run:
 +
<pre>ttnctl applications</pre>
 +
 
resulting in
 
resulting in
 
<pre>
 
<pre>
Line 131: Line 135:
 
</pre>
 
</pre>
  
The application EUI and application access keys are the ones that you see when you do:
+
The payload field is your data, unencrypted just encoded as BASE64.
<pre>./ttnctl-linux-amd64 applications</pre>
 
 
 
The payload field is your data encoded in BASE64.
 

Revision as of 13:55, 12 August 2016

Project LoraWanNode
LoraWanNode.jpg
Description of how to set up an Arduino Pro Mini and an HopeRF RFM95 to create a LoraWAN node
Status In progress
Contact bertrik
Last Update 2016-08-12


Introduction

This page describes the steps needed to create a simple LoraWAN node for the-things-network, using an Arduino Pro Mini and a HopeRF RFM95 module. It doesn't currently contain any new work, it just describes the steps I've done to use existing code to get a LoraWAN node to work with a LoraWAN network.

I've tested this successfully on the-things-network (TTN) in the city of Utrecht and on two gateways during a meetup of the Haagse Makers on 2016-05-10.

Some of the messages received by the TTN: http://thethingsnetwork.org/api/v0/nodes/19740823

How to tell if it works

On the Arduino side, every time a packet has been successfully sent, you'll see a message containing "EV_TXCOMPLETE" on the serial output of the Arduino.

On the TTN side, you can go to http://thethingsnetwork.org/api/v0/nodes/YOUR_DEVICE_ADDRESS where you should see the contents of the message you just sent, along with information about the particular gateway that received your signal, received signal strength and with what settings (bandwidth, spreading factor) your packet was received.

Next steps

Stuff to do after this:

  • configure a node for over-the-air activation instead of hard-coding a pre-configured set of keys in the node, see also [1]
  • get a better idea of the messages exchanged in the LoraWAN protocol: log events in the onEvent() function, or log more communication with the radio
  • actually attach a data source (like a sensor) to the node
  • get a better idea of the performance, I'm getting the impression that RSSI was quite low and that a lot of my packets were not received by the network

Hardware

The hardware I've used is:

  • a HopeRF RFM95 module, soldered onto a breakout board for easy access to the pins
  • an Arduino mini pro, 8MHz/3.3V (you need the 3.3V version, a 5V mini pro won't work!)
  • a CP2104-based USB-serial converter to connect the Arduino to the development PC
  • "dupont" wire to connect everything together

The HopeRF RFM95 module is connected to the Arduino as follows:

  • pin VCC to arduino Vcc pin (3.3V)
  • pin GND to arduino Gnd pin
  • pin NSS to arduino pin D10 (SS)
  • pin SCK to arduino pin D13 (SCK)
  • pin MOSI to arduino pin D11 (MOSI)
  • pin MISO to arduino pin D12 (MISO)
  • pin DIO0 to arduino pin D4
  • pin DIO1 to arduino pin D5
  • pin DIO2 to arduino pin D7

Basically this connects the RFM95 to the SPI bus of the Arduino, connects the RFM95 to 3.3V power and connects some of the generic RFM95 I/Os (like interrupt signals) to the Arduino. I don't know if connection of all the DIOx pins is really needed. At least DIO2 on the RFM95 seems to be used exclusively for some frequency-hopping feature (which is AFAIK not used in LoraWAN), I guess you can ignore that signal.

Software

This section assumes you are running Linux (I've tested this with Debian Jessie) and that you have git already installed.

Tools

Libraries

I've used this LoRa LMIC library: https://github.com/things4u/LoRa-LMIC-1.51.git

Clone this library into ~/Arduino/libraries and restart the Arduino IDE

 cd ~/Arduino/libraries
 git clone https://github.com/things4u/LoRa-LMIC-1.51.git

Node firmware

The firmware used on the arduino is the nano-lmic-v1.51-F.ino from the examples directory of the LoRa LMIC library.

I made the following changes:

  • in the library: replaced all instances of "arduino.h" by "Arduino.h" (capital "A"). This was needed because I compile on Linux which uses case-sensitive file names.
  • changed the device address (variable "DevAddr") in the .ino file to another number (0x19 0x74 0x08 0x23)
  • changed the payload string in function do_send in the .ino file (to my e-mail address)

When running this code, you can see some debug messages coming in over the serial port at 115200 bps.

Results

2016-08-06: personalized Device (ABP)

While taking the train from Leeuwarden to Gouda, I decided to transmit from the train onto the LoRa gateways in the neighborhood of Utrecht on the way home.

This was also a test for me for the device registration process, see also this ttnctl quickstart. I registered another personalized device.

In the Arduino code, I copy-pasted the following

  • the device address (device address 0x19800501 this time)
  • the NwkSKey and AppSKey

To register the device, run:

ttnctl devices TODO

The NwkSKey and AppSKey are the ones that see when you do

ttnctl devices info 19800501

I didn't need to do any reversing of bytes or anything like that, just copy the hex string into the Arduino code.

To listen using the ttnctl utility, it's simply:

./ttnctl subscribe
  INFO Subscribing to uplink messages from all devices in application 70B3D57ED000078A
  INFO Subscribed. Waiting for messages...     
  INFO 7B2248656C6C6F223A226265727472696B4073696B6B656E2E6E6C227D DevEUI=0000000019800501
  WARN Your payload has a size of 29 bytes. We recommend to send no more than 20 bytes. DevEUI=0000000019800501
  INFO 7B2248656C6C6F223A226265727472696B4073696B6B656E2E6E6C227D DevEUI=0000000019800501
  WARN Your payload has a size of 29 bytes. We recommend to send no more than 20 bytes. DevEUI=0000000019800501
  WARN Disconnected, reconnecting...            error=pingresp not received, disconnecting

To see the message in plain text, add the --plain option:

./ttnctl subscribe --plain
  INFO Subscribing to uplink messages from all devices in application 70B3D57ED000078A
  INFO Subscribed. Waiting for messages...     
  WARN Sending data as plain text is bad practice. We recommend to transmit data in a binary format.
  INFO {"Hello":"bertrik@sikken.nl"}            DevEUI=0000000019800501
  WARN Your payload has a size of 29 bytes. We recommend to send no more than 20 bytes. DevEUI=0000000019800501
  INFO {"Hello":"bertrik@sikken.nl"}            DevEUI=0000000019800501
  WARN Your payload has a size of 29 bytes. We recommend to send no more than 20 bytes. DevEUI=0000000019800501
  WARN Disconnected, reconnecting...            error=pingresp not received, disconnecting
  WARN Disconnected, reconnecting...            error=pingresp not received, disconnecting
  INFO {"Hello":"bertrik@sikken.nl"}            DevEUI=0000000019800501
  WARN Your payload has a size of 29 bytes. We recommend to send no more than 20 bytes. DevEUI=0000000019800501
  WARN Disconnected, reconnecting...            error=pingresp not received, disconnecting

To listen on the MQTT stream:

mosquitto_sub -h staging.thethingsnetwork.org -p 1883 -t +/devices/+/up -u <application EUI> -P <application access keys>

The application EUI and application access keys are the ones that you see when you run:

ttnctl applications

resulting in

{"payload":"eyJIZWxsbyI6ImJlcnRyaWtAc2lra2VuLm5sIn0=","port":1,"counter":3,"dev_eui":"0000000019800501","metadata":[{"frequency":867.3,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":1954388012,"gateway_time":"2016-08-06T19:06:05.891844Z","channel":4,"server_time":"2016-08-06T19:06:05.926706718Z","rssi":-118,"lsnr":-10.5,"rfchain":0,"crc":1,"modulation":"LORA","gateway_eui":"AA555A00080605B7","altitude":40,"longitude":5.16738,"latitude":52.08393}]}
{"payload":"eyJIZWxsbyI6ImJlcnRyaWtAc2lra2VuLm5sIn0=","port":1,"counter":4,"dev_eui":"0000000019800501","metadata":[{"frequency":867.7,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":2168302684,"gateway_time":"2016-08-06T19:09:39.806484Z","channel":6,"server_time":"2016-08-06T19:09:39.840959922Z","rssi":-120,"lsnr":-0.5,"rfchain":0,"crc":1,"modulation":"LORA","gateway_eui":"AA555A00080605B7","altitude":39,"longitude":5.16738,"latitude":52.08392},{"frequency":867.7,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":1293339940,"gateway_time":"2016-08-06T19:08:29.876103Z","channel":6,"server_time":"2016-08-06T19:09:40.052999884Z","rssi":-112,"lsnr":-7,"rfchain":1,"crc":1,"modulation":"LORA","gateway_eui":"008000000000A888","altitude":15,"longitude":5.11127,"latitude":52.08906}]}
{"payload":"eyJIZWxsbyI6ImJlcnRyaWtAc2lra2VuLm5sIn0=","port":1,"counter":5,"dev_eui":"0000000019800501","metadata":[{"frequency":867.9,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":2382216124,"gateway_time":"2016-08-06T19:13:13.719895Z","channel":7,"server_time":"2016-08-06T19:13:13.760756309Z","rssi":-119,"lsnr":-11,"rfchain":0,"crc":1,"modulation":"LORA","gateway_eui":"AA555A00080605B7","altitude":39,"longitude":5.16739,"latitude":52.08393},{"frequency":867.9,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":1507253220,"gateway_time":"2016-08-06T19:12:03.787853Z","channel":7,"server_time":"2016-08-06T19:13:13.965280234Z","rssi":-108,"lsnr":3.5,"rfchain":1,"crc":1,"modulation":"LORA","gateway_eui":"008000000000A888","altitude":15,"longitude":5.11127,"latitude":52.08906}]}
{"payload":"eyJIZWxsbyI6ImJlcnRyaWtAc2lra2VuLm5sIn0=","port":1,"counter":7,"dev_eui":"0000000019800501","metadata":[{"frequency":868.1,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":2809949852,"gateway_time":"2016-08-06T19:20:21.45356Z","channel":0,"server_time":"2016-08-06T19:20:21.492938568Z","rssi":-121,"lsnr":-9,"rfchain":1,"crc":1,"modulation":"LORA","gateway_eui":"AA555A00080605B7","altitude":40,"longitude":5.16738,"latitude":52.08396},{"frequency":868.1,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":1934986644,"gateway_time":"2016-08-06T19:19:11.520236Z","channel":0,"server_time":"2016-08-06T19:20:21.699607758Z","rssi":-120,"lsnr":-14.8,"rfchain":0,"crc":1,"modulation":"LORA","gateway_eui":"008000000000A888","altitude":15,"longitude":5.11127,"latitude":52.08906}]}
{"payload":"eyJIZWxsbyI6ImJlcnRyaWtAc2lra2VuLm5sIn0=","port":1,"counter":8,"dev_eui":"0000000019800501","metadata":[{"frequency":868.3,"datarate":"SF12BW125","codingrate":"4/5","gateway_timestamp":3779659468,"gateway_time":"2016-08-06T19:23:55.36816Z","channel":1,"server_time":"2016-08-06T19:23:55.799624684Z","rssi":-117,"lsnr":-12,"rfchain":1,"crc":1,"modulation":"LORA","gateway_eui":"0000024B080E015D","altitude":82,"longitude":5.05359,"latitude":52.01008}]}

The payload field is your data, unencrypted just encoded as BASE64.