In short; The Things Network is built up by people placing Gateways virtually all over the world that picks up LoRaWAN radio packets and forwards them to the backend of The Things Network. From there developers can access and process the data sent from their nodes in applications (living in the cloud).
But it's a good start to play with the technique, anyway. And cheap.
Software
First you need to install Windows IoT Core on your Raspberry Pi. This is done by following these instructions from Microsoft.
Next you will need to get my code, either clone or download it from my GitHub repository.
You will also need Visual Studio, preferably Visual Studio 2017. There is a free but very competent community edition which you may use.
Now you open up the Dragino.Lora.Demo.Gateway.sln
solution file from my GitHub repository in Visual Studio.
In the top bar of Visual Studio, choose Arm as the solution platform and Remote Machine as target.
Open up the MainPage.xaml.cs
source code file and locate the four YOUR EDITING IS REQUIRED HERE!
-comments.
Here's what you need to consider in those places:
#1. Configuring the radio chip
The first comment points out where you configure the LoRa radio chip by specifying the LoraWanGatewaySettings
-object instance.
The default is Europe868
, but depending on where you live (and your radio chip hardware) you might need to change this.
Either use one of the predefined ones, or create a custom one. Take a look at how the predefined ones are created, if you need to create a custom!
#2. Configuring the connection to the LoRa expansion board
The second edit-comment in the MainPage code file is found in the GetTransceiverPinSettings()
method.
It's here you tell how your transceiver expansion board is wired to your Raspberry Pi. If you are using the LoRa/GPS HAT --
or using an Arduino Shield with the wiring according to my schematics below -- you can leave the code as is.
But if you used a custom wiring you will need to uncomment the last lines and specify the pin numbers yourself.
#3. Using a GPS
Locate the UseGpsManager()
method. Depending on which expansion board you have, a GPS module might be present.
The default code assumes that you have one, and returns true
. If you don't have a GPS module, change this to false
.
#4. Specifying the Gateway EUI
The last part of the code you will need to configure is the EUI of your gateway and is found in the GetGatewayEui()
-method.
The EUI is a globally unique ID for your gateway. Unfortunately there is no unique ID provided by the LoRa module itself,
so, for instance the MAC address of the Raspberry Pi could be used instead.
Using the MAC address
If you want to use the MAC address it's slightly more complicated, because there isn't (yet) an API giving you this information in Windows IoT Core.
There is a however workaround, and that is to call the embedded REST API (the same that you can visit in a web browser to configure your device).
The URI that gives the MAC address information is found at https://localhost:8080/api/networking/ipconfig
.
But you must provide the user name and password to get access to this API; i.e. the credentials you used during the installation of Windows IoT Core on the device.
The default in the code is Administrator
and p@ssw0rd
.
Using a hard coded EUI
You can also specify any EUI you want by removing the two top lines of this method and uncomment the last one which simply returnes a fixed value at new GatewayEui("0123456789ABCDEF")
.
Obviously you should change the 0123...EF
to your own unique hexadecimal value.
The Things Network
Now it's time to register your gateway on The Things Network. For this you need to create an account there.
The next step is to go to the console and click the register gateway link. Now register your gateway using the following setup:
As Protocol, use packet forwarder since this gateway implementation is not a full-blown gateway connector.
As Gateway EUI you enter the EUI used by your application (see above). If you decided to use the MAC address you might need to start the application once to see the EUI
written in the debug console of Visual Studio (in the output window). This is written by the line that says WriteLog("The gateway EUI: " + gatewayEui);
Place a breakpoint there, start the code and see what it prints:
Stepping past the WriteLog line will reveal the EUI if it's unknown to you
Then you should give your gateway a name in the Description field, and choose the correct Frequency Plan depending on where you live and which radio module you are using.
If you like you can also click on the map to tell where your gateway is, and below you can specify your Antenna Placement.
At the bottom of the page, click the Register Gateway button when you are finished.
Your newly registered gateway
Click the Settings button in the top right corner and set the Router address:
Setting the Router address in the gateway settings
Click the Update Gateway button and then the Overview button to go back to the main screen.
Your gateway is now configured and The Things Network now expects it to deliver the radio packets it receives.
Run the Gateway application
Now you should be all set to run the gateway application. Just press F5 in Visual Studio (given that you have specified the target remote machine - i.e. your Raspberry Pi - in the Debug tab of the project properties).
If you now look at the Overview tab in the gateway console on The Things Network site, you can see if your gateway successfully can communicate with the network. The Last Seen should update around every 30 seconds:
Your gateway is up and running
The MainPage in your application has a timer that ticks every 30 seconds. When it ticks is calls the SendStatus()
method. This makes the gateway code send a short JSON status message to the backend, basically telling it that it is still alive and kicking.
The field below on the overview page is Received Messages (3 in my screenshot). This value goes up when the radio chip successfully receives a full packet (from anyone sending anything on your channel) and the gateway implementation succeeds in forwarding it to the backend. Depending on where you live your gateway will pick up packets more or less frequently.
The Transmitted Messages will stay 0 since this gateway is just a packet forwarder -- it never transmit any radio messages from The Things Network.
The debug output in Visual Studio
When running the application, open up the Output window in Visual Studio to see some details of what's happening:
GPS information
Having a GPS chip on your LoRa expansion board will show all serial communication data received from that module. Those lines starts with GPS:
in the log window.
Please note that even though your GPS coordinates are sent to The Things Network in the JSON status message, your gateway configuration will not be updated by The Things Network backend. I don't know why.
Note: Since you are probably now sitting indoors, trying out this project, you may need to place your Raspberry Pi (or at least the LoRa expansion board) in a window frame for it to successfully receive GPS signals.
A blue led will start flashing on the LoRa expansion board when the GPS receives signals from the satellites.
Sending status information
Every 30 seconds, when the main page calls the SendStatus method, you will see a line saying something like:
Packages: 10 / 4 / 4
The first number tells how many radio packets the LoRa chip has received. The second number how many of those that were OK (correct CRC and no timeout). The last number tells how many packets the gateway has forwarded to backend of The Things Network. In my example (10/4/4) only 4 packets were perfectly fine and 6 packets was not received correctly and was discarded.
The line after shows the JSON message that will be sent, and it will look something like this:
Sending JSON: {"stat":{"time":"2017-05-07 16:21:39 GMT","lati":55.597447,"long":12.958467,"alti":-7,"rxnb":0,"rxok":0,"rxfw":0,"ackr":100,"dwnb":0,"txnb":0}}
After that you will see the same JSON message as it is actually transferred to the backend, as a series of bytes transferred over the UDP protocol:
UDP sending (to "router.eu.thethings.network"): 01, F6, 29, 00, 19, C6, 83, A9, 64, 9B, 61, 29, 7B, 22, 73, 74, 61, 74, 22, 3A, 7B, 22, 74, 69, 6D, 65, 22, 3A, 22, 32, 30, 31, 37, 2D, 30, 35, 2D, 30, 37, 20, 31, 36, 3A, 32, 31, 3A, 33, 39, 20, 47, 4D, 54, 22, 2C, 22, 6C, 61, 74, 69, 22, 3A, 35, 35, 2E, 35, 39, 37, 34, 34, 37, 2C, 22, 6C, 6F, 6E, 67, 22, 3A, 31, 32, 2E, 39, 35, 38, 34, 36, 37, 2C, 22, 61, 6C, 74, 69, 22, 3A, 2D, 37, 2C, 22, 72, 78, 6E, 62, 22, 3A, 30, 2C, 22, 72, 78, 6F, 6B, 22, 3A, 30, 2C, 22, 72, 78, 66, 77, 22, 3A, 30, 2C, 22, 61, 63, 6B, 72, 22, 3A, 31, 30, 30, 2C, 22, 64, 77, 6E, 62, 22, 3A, 30, 2C, 22, 74, 78, 6E, 62, 22, 3A, 30, 7D, 7D (155 byte(s)).
Lastly, if everything worked as it should, you will see a short acknowledge from the backend, basically saying that it has received your message:
UDP receiving (from "52.169.76.203"): 01, F6, 29, 01 (4 byte(s)).
Receiving a packet successfully
When a radio packet is received successfully you will see something like this in the debug log:
[1] Packet RSSI: -104, RSSI: -102, SNR: 56.2, Length: 26
[2] Message Received: CRC OK, Rssi=-102, PacketRssi=-104, PacketSnr=56.2, Buffer:[40, 3f, 16, 01, 26, 80, 12, 00, 01, a3, ba, da, b8, b0, 59, 14, 67, 5b, 11, 55, 40, 06, fa, e7, ad, 4a], 2017-05-07 17:00:27
[3] Received: CRC OK, Rssi=-102, PacketRssi=-104, PacketSnr=56.2, Buffer:[40, 3f, 16, 01, 26, 80, 12, 00, 01, a3, ba, da, b8, b0, 59, 14, 67, 5b, 11, 55, 40, 06, fa, e7, ad, 4a], 2017-05-07 17:00:27
[4] Sending JSON: {"rxpk":[{"time":"2017-05-07T17:00:27.1374110Z","tmst":2387966326,"freq":868.1,"chan":0,"rfch":0,"stat":1,"modu":"LORA","datr":"SF7BW125",
"codr":"4/5","rssi":-104,"lsnr":56.200000762939453,"size":26,"data":"QD8WASaAEgABo7rauLBZFGdbEVVABvrnrUo="}]}
[5] UDP sending (to "router.eu.thethings.network"): 01, 19, FD, 00, 19, C6, 83, A9, 64, 9B, 61, 29, 7B, 22, 72, 78, 70, 6B, 22, 3A, 5B, 7B, 22, 74, 69, 6D, 65, 22, 3A, 22, 32, 30, 31, 37, 2D, 30, 35, 2D, 30, 37, 54, 31, 37, 3A, 30, 30, 3A, 32, 37, 2E, 31, 33, 37, 34, 31, 31, 30, 5A, 22, 2C, 22, 74, 6D, 73, 74, 22, 3A, 32, 33, 38, 37, 39, 36, 36, 33, 32, 36, 2C, 22, 66, 72, 65, 71, 22, 3A, 38, 36, 38, 2E, 31, 2C, 22, 63, 68, 61, 6E, 22, 3A, 30, 2C, 22, 72, 66, 63, 68, 22, 3A, 30, 2C, 22, 73, 74, 61, 74, 22, 3A, 31, 2C, 22, 6D, 6F, 64, 75, 22, 3A, 22, 4C, 4F, 52, 41, 22, 2C, 22, 64, 61, 74, 72, 22, 3A, 22, 53, 46, 37, 42, 57, 31, 32, 35, 22, 2C, 22, 63, 6F, 64, 72, 22, 3A, 22, 34, 2F, 35, 22, 2C, 22, 72, 73, 73, 69, 22, 3A, 2D, 31, 30, 34, 2C, 22, 6C, 73, 6E, 72, 22, 3A, 35, 36, 2E, 32, 30, 30, 30, 30, 30, 37, 36, 32, 39, 33, 39, 34, 35, 33, 2C, 22, 73, 69, 7A, 65, 22, 3A, 32, 36, 2C, 22, 64, 61, 74, 61, 22, 3A, 22, 51, 44, 38, 57, 41, 53, 61, 41, 45, 67, 41, 42, 6F, 37, 72, 61, 75, 4C, 42, 5A, 46, 47, 64, 62, 45, 56, 56, 41, 42, 76, 72, 6E, 72, 55, 6F, 3D, 22, 7D, 5D, 7D (259 byte(s)).
[6] UDP receiving (from "52.169.76.203"): 01, 19, FD, 01 (4 byte(s)).
Line [1] tells some overall information about the packet. RSSI means Received Signal Strength Indicator, SNR is the Signal-to-Noise Ratio. Length is the number of bytes received.
Line [2] and [3] tells the same thing as the first line, but in more detail; including the actual bytes received.
Line [4] shows the composed JSON message that will be sent to The Things Network to inform about the received packet.
Line [5] is the JSON as it actually will be transferred, and line [6] is the acknowledge from the backend of The Things Network.
Receiving a bad radio packet
Sometimes a packet is not received correctly. The reason could be bad reception (a distant transmitter) or collisions with other messages.
You will see something like this in the debug output:
Message Received: Bad CRC, Rssi=-94, PacketRssi=-102, PacketSnr=59.2, Buffer:[40, 3f, 1a, 01, 26, 80, 04, 00, 01, fb, 75, 0b, 03, a7, 30, 17, a8, 05, 6e, b0, 29, 89, 6e, 81, b8, 7d], 2017-05-07 16:45:01
You will still get access to the packet data in the MainPage (if you would like to do some analysis or further processing), but it will not be forwarded to The Things Network.
Resources
I have had great help creating this project from the following resources:
...and countless of other online resources from here & there...