Local LoRaWAN infrastructure

Be your own network operator

Public Chat
Similar projects worth following
We are operating a LoRaWAN infrastructure that is run locally, with one gateway on a tall building and a ChirpStack server. For now data is being pushed into InfluxDB and can be viewed with Grafana.

This is part of a larger project where we are implementing a network of wireless low-power air quality sensors to deploy in the city of Magurele, Romania. The other projects are:


This may not be a very good idea. For most purposes you're much better off using something like The Things Network, as you're helping the community and vastly increasing your coverage by leveraging on said community. However, based on your coverage needs and future deployment plans this could actually make sense, as you gain guranteed quality of service and you won't run into costs as you scale. In this case I just wanted to see how feasible it is to run an isolated pocket of LoRaWAN.

LoRaWAN network architecture

A LoRaWAN network consists a multitude of interconnected hardware and software components, promising large coverage for low-power end-devices, leveraging on existing infrastructure wherever this is available.

  • End devices use the LoRa RF modulation to talk to gateways. Each device may be heard by multiple gateways and all copies of the messages are forwarded to the network server. Devices further away from a gateway can choose a lower data rate to increase their range
  • The network server handles deduplication of messages, forwards them to application servers and selects which gateway to use for downlink transmissions
  • Application servers decrypt and use the data from end devices. The same gateways and network server can service multiple applications.

Our local LoRaWAN implementation

The infrastructure consists of a gateway and a server, using the ChirpStack software for implementing the LoRaWAN protocol. For testing things out the server also runs basic persistency and visualisation with InfluxDB and Grafana.


Kerlink Wigrid station, placed on top of the tallest building in Magurele.

Network coverage, gathered on a drive around Magurele and Bucharest. Furthest packet received from 9.3km.

Gateway firmware

Of substantial help in updating the firmware and getting it connected to ChirpStack was the The Things Network help page. Gateway can load up new firmware from a USB drive at boot. Copies of the files used for this project are in the project's files section.

Gateway configuration

The gateway uses the Semtech Packet Forwarder (SPF) to interact with its LoRa modem. This software exposes a UDP interface to a server that runs the LoRaWAN stack. Configuration files for the SPF are stored in /mnt/fsuser-1/spf/etc and are global_conf.json and local_conf.json.

global_conf.json contains the channel plan and I am not sure if these channel indices need to be the same as the ones configured in ChirpStack. I aligned them just in case:

        "SX1301_conf": {
                "lorawan_public": true,
                "antenna_gain": 1,
                "clksrc": 1,
                "radio_0": {
                        "enable": true,
                        "type": "SX1257",
                        "freq": 868500000,
                        "tx_enable": true,
                        "tx_notch_freq": 129000,
                        "tx_freq_min": 863000000,
                        "tx_freq_max": 870000000,
                        "rssi_offset": -160
                "radio_1": {
                        "enable": true,
                        "type": "SX1257",
                        "freq": 867500000,
                        "tx_enable": false,
                        "rssi_offset": -160
                "chan_multiSF_0": { "enable": true, "radio": 0, "if": -400000 },
                "chan_multiSF_1": { "enable": true, "radio": 0, "if": -200000 },
                "chan_multiSF_2": { "enable": true, "radio": 0, "if": 0 },
                "chan_multiSF_3": { "enable": true, "radio": 1, "if": 400000 },
                "chan_multiSF_4": { "enable": true, "radio": 1, "if": 200000 },
                "chan_multiSF_5": { "enable": true, "radio": 1, "if": 0 },
                "chan_multiSF_6": { "enable": true, "radio": 1, "if": -200000 },
                "chan_multiSF_7": { "enable": true, "radio": 1, "if": -400000 },
                "chan_Lora_std": {
                        "enable": true,
                        "radio": 0,
                        "if": -200000,
                        "bandwidth": 250000,
                        "spread_factor": 7
                "chan_FSK": {
                        "enable": true,
                        "radio": 0,
                        "if": 300000,
                        "bandwidth": 125000,
                        "datarate": 50000
                "tx_lut_0": {"dig_gain": 0, "pa_gain": 0, "mix_gain": 8, "rf_power"...
Read more »

Kerlink gateway system firmware

x-zip-compressed - 18.72 MB - 08/27/2022 at 09:18



"User" customization of firmware. Specifically this package contains the Semtech Packet Forwarder (SPF) which is the piece of software that takes LoRaWAN frames and sends them to a server.

x-gzip - 216.20 kB - 08/27/2022 at 09:18


Boot script to get Kerlink gateway to update firmware

x-zip-compressed - 2.35 kB - 08/27/2022 at 09:18


  • Setting up ChirpStack

    mihai.cuciuc08/28/2022 at 11:53 0 comments

    ChirpStack web interface is by default located at http://<SERVER_IP>:8080 with user/pass: admin/admin

    This is the minimum configuration needed to get end devices conected to your server

    1. Add a network server
    2. Add an organization
    3. Add a service profile
    4. Add your gateway. The Gateway ID needs to be identical to the one configured on the gateway, in /mnt/fsuser-1/spf/etc/local_conf.json under
              "gateway_conf": {
                      "gateway_ID": "1122334455667788"
    5. Add a device profile. Settings here might differ based on the LoRaWAN implementation your end-devices use. These settings are for the RN2483 with firmware version 1.0.5. Once you created the profile, edit it and check "Device supports OTAA" under Join.
    6. Create a Custom JavaScript codec. These are used to interpret the decrypted byte array coming from the sensor into more meaningful objects that can be forwarded to other pieces of software. We will package the first two bytes into a simple object
    7. Create an application
    8. [Optional] Create an InfluxDB integration. This requires that InfluxDB is installed. You will be able to see traffic from your sensor without this, but there will be no data persistency.
    9. [Optional] Create the database in InfluxDB. On your server do
      lora@loraserver:~$ influx
      Connected to http://localhost:8086 version 1.8.10
      InfluxDB shell version: 1.8.10
      > create database demodatabase 
    10. Under the newly created application, create a device. The DeviceEUI should be unique within your network. The RN2483 comes preprogrammed with a unique device EUI that you can use.
    11. Set the Application key for this device. You can generate a random one from the button on the right
    12. Send some data from your end device. Assuming you are using a RN2483 modem, you can use the follwing commands (modem responses included)
      mac set deveui 1234567890abcdef
      mac set appkey 00112233445566778899aabbccddeeff
      mac join otaa
      mac tx cnf 1 00ff
      mac tx cnf 1 01fe
      mac tx cnf 1 02fd
      mac tx uncnf 1 04bf
      mac tx uncnf 1 08f7
      mac tx uncnf 1 10ef
    13. Check that the data can be seen in ChirpStack
    14. [Optional] Use Grafana to show a plot of the two bytes you sent. You need to set the data source in Grafana appropriately to read from your InfluxDB database

View project log

Enjoy this project?



Nathann wrote 10/24/2022 at 09:20 point

I'm having trouble understanding what hardware you used and what other alternative hardware could be used instead. could you clear that up for me ? :3

  Are you sure? yes | no

mihai.cuciuc wrote 10/24/2022 at 16:19 point

I assume your question is about the gateway.

I used one of these but I'm not sure they're making them any more. However this is rather expensive for hobbyists, so for the future I'll use some of these that are ~$100 for the non-GPS version. These use the SX1308 chipset that has a somewhat lower sensitivity, but you can find other RAKwireless gateways with better performances on their website.

  Are you sure? yes | no

zeflo wrote 10/23/2022 at 08:55 point

Would it be possible to connect the gateway to your own servers and TTN at the same time? 

  Are you sure? yes | no

mihai.cuciuc wrote 10/24/2022 at 16:04 point

Ha, that's an interesting question! I don't see why the gateway couldn't send uplink packets to two servers and rely downlinks from both. Unless of course there's a conflict and both servers schedule a downlink at the same time. With the default configuration you can't do it just because the Semtech Packet Forwarder only has one "server_address" field. But since communication is over UDP I guess it's as simple as making a 3 line python script to work as a bidirectional tee between the packet forwarder and the two servers

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates