empowering creative people

Building a LoRaWAN Nano Gateway to The Things Network

warning: this is a "nano" gateway and not intended for long-term use on the TTN. It's a just-for-fun tutorial that we wanted to explore and share how things went, but there are gotchas. This gateway will only operate on 3-channels. Also, nodes (remote devices) require customisation to work with a nano-gateway properly. If you'd like to setup a "real" gateway that supports all 8-channels and works just the way it should for others that might want to connect to it, then consider getting a full-fledged gateway such as this. Again, please don't leave a nano-gateway permanently on TTN, it can be confusing if someone else tries to connect to it, as most of the channels are not operational.

In this article we'll see how to build a Nano Gateway to The Things Network (TTN) using a Pycom device with LoRa: a LoPy4 or a FiPy.

When you build an IoT project using LoRaWAN you only want to worry about two things: your IoT devices and the Internet service (or "platform") your IoT devices communicate with. Everything in between is down to the LoRaWAN network which, in this case, is The Things Network. It takes some configuring, but this "internet plumbing" should just work. But what if there's no coverage where you are?

The Things Network Coverage Map shows LoRaWAN gateways that are already set up and available for you to use for free. But if you're outside a coverage area, you'll need your own gateway. If you have the means and the motivation, you can set up a permanent Gateway with access to the Internet and register it with TTN so everyone can use it. As of today that's about a $1,000 (AUD) investment. Makers and IoT experimenters would much rather build a Nano Gateway which is far less expensive.

Newcastle, Australia coverage map for The Things NetworkNewcastle, Australia coverage map for The Things Network


We'll assume you already have an account with The Things Network (TTN) and have logged in. It's free, so go ahead and do that now if you haven't already. We'll also assume you have the Atom IDE installed with the Pymakr plug-in and your Pycom device is on it's expansion board with the antenna attached and plugged into your PC with a USB cable. You will also have done a firmware update and in doing so selected the correct LoRa region for where you are in the world. For help with any of these steps please refer to Internet of Things with Pycom and Adafruit IO - From Zero to Hero for in-depth coverage.

Building a Nano Gateway

The Things Network logo

In TTN Console we find two things: Applications and Gateways. We only need to consider Gateways. If you are in a coverage area for one or more existent gateways, you don't need to set up your own gateway: just create an application and register your devices to it. More on this in my next article. For now we'll be setting up a gateway anyway so that everyone can get started with LoRaWAN and TTN, even if they're not in a coverage area.

The Pycom Documentation contains The Things Network. Read through that to ensure you've got an understanding of the process we're about to go through. To build the Nano Gateway we need two things: configuration done on TTN and code running on our Pycom device.

Jumping back up to heading Register a Nano-Gateway we'll follow the link in the first paragraph that takes us to 5.3.6 LoRaWAN Nano-Gateway. Again, read through the documentation here.

Each gateway on TTN has a Gateway ID and sample code is provided that creates a unique Gateway ID using the unique identifier (MAC) that's built into the Wi-Fi network adaptor on all Pycom devices. We need to add a print statement to the last line so we can see that the Gateway ID is:

from network import WLAN
import binascii
wl = WLAN()
print("Gateway EUI: {}".format(binascii.hexlify(wl.mac())[:6] + 'fffe' + binascii.hexlify(wl.mac())[6:]))

Configuring a New Nano Gateway on TTN

Now we can go to TTN web site and create a Gateway. At the Console click Gateways. On the Gateways page click register gateway. The web site has changed since Pycom's documentation went up, but the fundamentals are all there. It's best to check the I'm using the legacy packet forwarder option first, as this affects the Gateway box above it. The top box now becomes Gateway EUI and we can past in the Gateway EUI we just generated in Atom. Give this gateway any Description that's useful.

Selection of the Frequency Plan is very important. We must select the region that we programmed into our LoRa device when we did the firmware update. Note that operating a device on the wrong region is most likely illegal. As I'm in Australia I use the Australia AU915 frequency plan. Having selected that, TTN automatically changes the Router selection to one more appropriate for my location: ttn-router-asia-se. Don't forget to put a marker on the map to show where you are and select Indoor/Outdoor for your antenna placement. Then we can click Register Gateway at the bottom of the page. We'll need to refer to some of these settings when we configure our code to run on the Pycom device that will be our Nano Gateway.

Having created your Nano Gateway on TTN, you can select it from the Gateways list and you now have three tabs with which to manage it: Overview, Traffic and Settings. The Settings tab breaks down into six further categories.

Running Nano Gateway Code on a Pycom Device

5.3.6 LoRaWAN Nano-Gateway in the documentation gives various code files but it's best to download the latest code from Github. So, Download Pycom Libraries from Github to get all the latest files. Unzip the download file and then find the lorawan-nano-gateway folder under examples. Move it to a place that suits you and rename it if you wish. This will be our starting code.

Let's look at what we get. There's no boot.py file, which would be run first every time our device restarts. There is a main.py file which is run automatically. Looking at the code there we see it imports config.py and nanogateway.py so we should look at those two. config.py has a few TTN settings we'll need to adjust. nanogateway.py looks like it does all the work of operating the gateway. I don't see any settings in there we might need to change. The other four files all have 'node' in their name, so it seems we can use those to connect to our gateway using another Pycom device.


Now it would be helpful to have Atom and the TTN web site side-by-side on the screen, so we can copy and check settings between the two. Having already generated the Gateway EUI, we don’t need to do anything with that – it's unique and stays the same. SERVER should be router.au.thethings.network for region AU915 (see forum post: New addresses for cloud services: update your gateways). PORT stays at 1700. Having previously failed to get an NTP connection to pool.ntp.org I changed that to au.pool.ntp.org. I used my own Wi-Fi credentials to set up an Internet connection.

There is a code block giving settings for EU868 region and another, commented out, for the US915 region. If you're in either of those regions you only need to ensure the right part of the code is in operation and away you go. I can't use either of these regions, so I need to work out how these settings work and decide what to replace them with. I'm disconcerted by the need to program in the LoRa frequency. Again, it seems a mistake here could result in me using a frequency that's illegal in my region. But having once accidentally set the wrong frequency I was happy that I saw this error message:

Traceback (most recent call last):
  File "main.py", line 19, in <module>
  File "nanogateway.py", line 167, in start
ValueError: frequency 868100000 out of range

In their LoRaWAN Frequencies Overview, TTN outlines the frequencies used in each region. In EU863-870 the first uplink channel is at 868.1 MHz which lines up exactly with our config.py file showing LORA_FREQUENCY = 868100000. Likewise, the US902-928 configurations that are commented out use LORA_FREQUENCY = 903900000, exactly matching uplink channel 1 from the documentation on 903.9 MHz. Following this logic, the first uplink channel for AU915-928 is at 916.8 MHz, or 916800000. I created a configuration block for AU915 like this:

# for AU915
LORA_FREQUENCY = 916800000
LORA_GW_DR = "SF7BW125" # DR_5

I checked that the LORA_GW_DR (LoRa Gateway Data Rate) of SF7BW125 (Speading Factor 7 and BandWidth 125) was applicable as specified in the other regions. The correct setting for the node is LORA_NODE_DR = 5.

With these settings locked down, I went ahead and uploaded the code to my LoPy4. After the automatic reset, it connected to TTN. The Status (Gateways – select the gateway – Overview) changed to "connected" and the Last Seen time was reset. Each time the gateway sent a heartbeat message I could see the Last Seen time resetting again.

[   123.289] Push ack
[   148.266] Pull ack
[   173.276] Pull ack
[   183.264] Push ack
[   198.275] Pull ack
[   223.271] Pull ack

The Things Network: gateway not connected The Things Network: gateway not connected The Things Network: gateway connectedThe Things Network: gateway connected


There we have it! A working LoRaWAN gateway. Now we can build out LoRaWAN projects even when we don't have access to The Things Network through someone else's gateway. Bring on the projects! Other companion articles will show how to build LoRaWAN nodes to use your gateway and how to push data to/from them as well as integrating other systems with TTN.

warning: this is a "nano" gateway and not intended for long-term use on the TTN. It's a just-for-fun tutorial that we wanted ...

Have a question? Ask the Author of this guide today!