Adafruit Feather as LoRaWAN node

Next to the Raspberry Pi as a LoRaWAN node I also wanted to have a really tiny node, as tiny as possible, and with the capability to operate it with a battery.

I ordered a Adafruit Feather 32u4 RFM95 LoRa Radio module, as it already has a RFM95 LoRa radio module attached, and as it has a connector and charger for Lithium Polymer batteries.


For the software part, I took the LMIC library for Arduino port from github and followed the instructions to get it up and working in the Arduino IDE.

To make it work for the Adafruit Feather 32u4 module, there was the need to adapt some settings. The pin mapping definition was changed as follows.

const lmic_pinmap lmic_pins = { 
   .nss = 8, 
   .rxtx = LMIC_UNUSED_PIN, 
   .rst = 4, 
   .dio = {7, 6, LMIC_UNUSED_PIN}, 

According to Adafruit, the radio module’s IO0 pin is already connected internally to pin 7 of the Adafruit feather module.

Additionally, I needed to connect the radio module’s IO1 pin with pin 6 using a wire bridge (see picture above). Connecting IO2 is not required (LMIC_UNUSED_PIN).

Further, there seems to be a little issue with the accurancy of the clock, which can cause problems with receiving data from the LoRa gateways, as the receive window can’t be hit exactly. For this reason, added the following line to work around this.

LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);

Having done that, the ttn-otaa.ino worked as expected: It took only one single request to join TTN using Over-the-Air-Activation (OTAA), and periodically sending a data record every 60 seconds.

Hardware Abstraction Layer (HAL) for LMIC 1.6

For users of a Dragino LoRa/GPS HAT (for Raspberry Pi) I have implemented a Hardware Abstraction Layer for the IBM LMIC 1.6 communication stack. This is similar to the solution of Ernst de Vreede, but as a difference it is based on IBM LMIC 1.6, which seems to be the most recent version of this communication stack. I tried not to touch the LMIC stack itself but only provide a HAL for RPi + LoRa HAT. I also tried not to put too much CPU load on the RPi when waiting for incoming messages.

Find the code in github at

  • The following LMIC examples are working yet with this HAL and TTN:
    examples/hello – Not using radio at all
  • examples/join – Join the TTN using OTAA (over the air activation)
  • examples/periodic – Join and periodically send a sensor value to TTN.

The examples work, however I would like to do some more analysis and fine tuning regarding the timing of the receive window, and I like to add more debug output to understand what is going on in the network in regards of the LoRaWAN protocol.

Note: I tested it with a Kerlink IoT Gateway. Single Channel Gateways won’t work.

LoRa Gateway for Tests

I currently have a Kerlink LoRa IoT Station 868 for testing.

The Things Network supports this gateway, instructions how to update the gateway’s firmware to make it communicate with TTN can be found here.

Let me quote from TTN:

The Kerlink LoRa IoT Station is is an industrial solution suitable for people who want to mount the gateway outside and who have sufficient technical skills to connect, mount and maintain the device themselves.

We have tested the device and although we have remarks about the somewhat older software that is being used, this device will do the job. A trained software engineer will be able to update the device using the software from The Things Network.


LoRaWAN Single Channel Gateway

For first steps with The Things Network, you can build a LoRa Gateway. This gateway will have some restrictions:

  • Listens only on one single channel (one single frequency) for nodes
  • Listens only with one predefined spreading factor (SF)
  • Only listens, does not send back any kind of acknowledge messages

Okay. These are pretty hard restrictions, maybe we better should name it “Forwarder” instead of “Gateway”.





You need to define the IP address of the TTN server in the gateway software

  • In main.cpp, update the IP address of TTN server.
    You can find the current IP addresses to use here: For different countries there are different server addresses. Pick the appropriate one.
  • For europe (EU), I choose # EU 433 and EU 863-870

    Note that you can’t enter this server name directly, you need to lookup the IP address before:

    $ nslookup
    Non-authoritative answer: canonical name =

    The IP address to use in main.cpp is

  • In the code of main.cpp, it should look like this:
    // define servers
    // TODO: use host names and dns
    #define SERVER1 ""
    //#define SERVER1 ""    // The Things Network:
  • Now compile the software and start it
    sudo ./single_chan_pkt_fwd
  • On start, it will output its Gateway ID, which is important for the next steps:
    pi@raspberrypi:~/single_chan_pkt_fwd $ sudo ./single_chan_pkt_fwd 
    SX1276 detected, starting.
    Gateway ID: aa:bb:cc:ee:ff:11:22:33
    Listening at SF7 on 868.100000 Mhz.

    This Gatway ID is unique for your gateway.

To create a gateway in TTN, you need to register at TTN and create an account. You then can register a gateway in the console.

  • Choose “bridge” as “Activation Method”
  • Cut and paste your Gateway ID as “Gateway EUI”
  • Choose the appropriate frequency plan
  • When you have filled out all fields, press button “Register Gateway” at the bottom of the page.


That’s it.

You now should have created you own experimental gateway in TTN and you should see that it has status “connected”.

Cross compiling to Raspberry Pi

Please don’t ask for the reasons, but the goal of today’s action was to get a cross compile environment running on Windows OS in order to compile to my RPi3 running Raspbian “jessie” (Raspbian GNU/Linux 8).

I write this blog post as a shortcut for people that like to do the same: Use the resources and comfortable IDE on a PC and do the code writing here, compile, link and finally transfer the executable binary to the Raspberry Pi and execute it there.


Downloaded Eclipse CDT as IDE for C/C++ programming.

Eclipse IDE for C/C++ Developers
Version: Neon.2 Release (4.6.2)

Precompiled GNU Toolchain for Windows32

Linaro provides several precompiled toolchains. It is up to you to select the right one.

It needs to fit the system architecture on the Raspberry Pi and the remote operating system you are running on (Raspian “jessie”).

There is a list of Linaro releases here:

For Windows32 as host/development system, I chose

Download it and extract it on your windows filesystem.


You additionally need build tools like “make”.

This can be downloaded from here:

Put the buildtool’s bin directory into your Windows PATH environment variable to make sure they are found by Eclipse. You possibly may need to restart Eclipse. If “make” ist not found when compiling some source files, then the reason is probably that the path to the buildtools is not configured properly.

Configuring Eclipse CDT

Create a new C project named “hello_world”, choose project type “Empty Project”. Toolchain “Cgross GCC” should be selected.

If you are ask for “Cross compiler prefix”, you enter


Note: Don’t forget the hyphen (“-“) at the end.

For “Cross compiler path”, navigate to the “bin” directory of your toolchain installation. In my case, it is


Note: There are two bin directories in the toolchain installation. Make sure to select the one that contains binary executables starting with the filename “prefix arm-linux-gnueabihf-“, e.g. “arm-linux-gnueabihf-gcc.exe”.

Hello World Application

Create a small hello_world.c file.

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("Hello World.\n");

Compile it in Eclipse using Project -> Build All, and that’s it (almost).

00:40:57 **** Build of configuration Debug for project hello_world ****
make all 
Building file: ../hello_world.c
Invoking: Cross GCC Compiler
arm-linux-gnueabihf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"hello_world.d" -MT"hello_world.o" -o "hello_world.o" "../hello_world.c"
Finished building: ../hello_world.c
Building target: hello_world
Invoking: Cross GCC Linker
arm-linux-gnueabihf-gcc  -o "hello_world"  ./hello_world.o   
Finished building target: hello_world

00:40:59 Build Finished (took 1s.449ms)

Looks good. You can see that arm-linux-gnueabihf-gcc was both used for compiling and linking.

Transfer binary executable to Raspberry Pi

The binary is located in the project subfolder debug. Transfer it to the remote Raspberry Pi. Eclipse provides a way to build connections to remote systems using New -> Other -> Remote System Explorer. You can use this to transfer files without having to leave the IDE.

On Rasperry Pi, make the file “executable” and execute it:

pi@rpi3:~ $ chmod u+x hello_world
pi@rpi3:~ $ ./hello_world
Hello World.

Works. Fine. Go to bed now.

New project: LoRaWAN hacking

Inspired by the first meeting of the The Things Network Community Stuttgart this week I decided to make first steps with LoRaWAN communication. I was looking for a solution that works without soldering, and actually Dragino provides a extension module for Raspberry Pi, which is intended to build LoRaWAN solutions.

Dragino LoRA/GPS HAT

I ordered via Maker Shop EXP TECH, and actually the hardware arrived just one day after ordering. Great service.


Next to the Semtech LoRa transceiver there is also a GPS receiver on the extension board.

As I already have experience with FSK modulation in the 868MHz band, I think the first steps will be to check out how to use this kind of communication, before switching to LoRa and LoRaWAN.


Obviously my software works well to receive messages from the radiator controllers if they are just sent sporadically – every now and then.

But the software is unable to receive sequences of messages, in case they are sent directly one after the other, without temporal gap. In fact, the Room Unit sents sequences of messages in case the temperature of a zone has to change.

Why does the software fail?

Because it tries to read one message into the 64 byte FIFO receive buffer. As it is not possible to find out how long the message will be (without decoding it), the software just reads until the 64 bytes are read. And this is fatal, as in this case the software already reads the beginning (e.g. the RF preamble of alternating “1” and “0”) from the subsequent message.


66 55 56 55 2B 2B 52 B2 AD 53 4A CD 52 B5 55 55 55 55 55 55 55 4C B5 2C AB 4B 4A B5 2C AB 32 CA B2 B5 4B 2C D2 B4 CD 59 55

What now?

  • Alternative #1: Forget to read messages in the FIFO buffer and decode after that, instead do “direct stream processing”, bit by bit ?
  • Alternative #2: Fill the FIFO buffer byte by byte, and somehow try to find out when the complete message is read, then (very quickly) process the message and receive the next message using the RF receiver. The problem is that it takes some amount of time to decode the message and send the result to the client – probably too much time so we miss the RF preamble of the subsequent message.