Mapping LoRaWAN coverage in Southampton

Having setup some LoRaWAN base stations to provide coverage of the Southampton area we wanted to see if there are any black spots without coverage, and therefore where new basestations should be deployed. We are also looking to do more work with positioning of LoRaWAN devices so need transmissions from known locations. Rather than developing our own mapping system we decided to build upon TTN Mapper developed by JP Meijers. This can be achieved using a simple node and an application running on your phone to provide the GPS location. We chose not to use this as it requires setting up an app, whereas having a standalone device is much easier to pass between people.


Having decided upon a standalone hardware based solution it was a matter of chosing which hardware to use. For another project we are using pycom devices; the LoPy in particular. This provides a LoRaWAN package in a convenient form factor which is programmed using Python. They also provide an expansion board the Pytrack which adds GPS connectivity to the board.

Having decided on the hardware we could then work out which of the other peripherals that the expansion board had to use. It was decided it would also be interesting to log GPS co-ordinates locally on the devices so that these could be compared to the data received at the base stations to identify gaps in coverage.

To build the hardware we used the following parts

Parts list

The battery is connected to via the switch to the pytrack PCB. This means the board can be turned on/off without having to open the case. The case still has to be opened to charge the battery as there is currently no external USB connector. There is also currently no way of viewing the debug LED when the case is closed. The battery and PCB are secured in place using velcro.

Pytrack node
Pytrack node


The easiest way for the data to be imported into TTN mapper is to use one of their standard formats. They accept simple ascii but recommend a more efficient binary encoding of the data. In order to check you have encoded the data correctly you can add a custom payload to the things network. This is provided in the comments in a git repo available at, but also reproduced below.

function Decoder(bytes, port) {
  var decoded = {}; = ((bytes[0]<<16)>>>0) + ((bytes[1]<<8)>>>0) + bytes[2]; = ( / 16777215.0 * 180) - 90;
  decoded.lon = ((bytes[3]<<16)>>>0) + ((bytes[4]<<8)>>>0) + bytes[5];
  decoded.lon = (decoded.lon / 16777215.0 * 360) - 180;
  var altValue = ((bytes[6]<<8)>>>0) + bytes[7];
  var sign = bytes[6] & (1 << 7);
    decoded.alt = 0xFFFF0000 | altValue;
    decoded.alt = altValue;
  decoded.hdop = bytes[8] / 10.0;
  return decoded;

Using this decoder has two advantages, you can see that the data you are sending makes sense and you verify that it is in the correct format to be understood by TTN Mapper.

Example decoded payload containing lat, lon, alt and hdop
Example decoded payload from a device

The software for this is available from It forms two parts, a part to run on the device. This was programmed using Visual Studio Code with the Pymakr plugin. Setup instructions are available from the pycom docs. Any details that are device specific are stored in a default version is given in the repo and below. The correct details should be put in for your device.

APP_KEY = "" #Application key from the things network
APP_EUI = ""                 #The EUI for the app
JOIN_TIMEOUT = 0                             #passed to the LoRaWAN join function
GPS_TIMEOUT = 30                             #How long to wait for a GPS reading per attempt
POST_MESSAGE_SLEEP = 60 #How long to wait between messages - affects GPS sample rate when connected
GPS_READ_INTERVAL = 10  #How often to read the GPS if not on the LoRaWAN network

TTN mapper relies on getting latitude, longitude, altitude and HDOP. The default library that pycom provide for the pytrack only provides the latitude and the longitude, as the rest of the data is not provided in the particular NMEA string that they are parsing. However, consulting the datasheet for the GPS module showed that the module also produces


NMEA strings which do contain the required information. The provided library was therefore modified to include an additional function which provides the required information. This will be tested a bit more comprehensively before submitting a pull request to add this to the core library.

Once you have given the required details to TTN Mapper as per the FAQ you should see a purple marker appear which represents your mobile device, with coverage details being added to the map periodically. An example is shown below.

TTN Mapper screenshot showing some base stations (Blue) and 2 mobile nodes (Purple)

As well as submitting the data to TTN mapper we wanted to keep a record of the positions from the device for a forthcoming project in which we would need the raw data to compare again. In order to do this we have a python application which subscribes to an MQTT stream from the application and logs data into a monogodb store.

        "_id" : ObjectId("59c641d6c7a447dd52f8ba75"),
        "hdop" : 1,
        "timestamp" : "2017-09-23 11:13:26",
        "lon" : -1.39849,
        "alt" : 70,
        "gateways" : [
                        "rssi" : -96,
                        "snr" : -1,
                        "gw_id" : "eui-b827ebfffee36ef8"
                        "rssi" : -102,
                        "snr" : 9,
                        "gw_id" : "eui-7276fffffe0102df"
                        "rssi" : -72,
                        "snr" : 9.8,
                        "gw_id" : "eui-b827ebfffeac4b12"
                        "rssi" : -104,
                        "snr" : 9,
                        "gw_id" : "eui-7276fffffe0103f0"
                        "rssi" : -106,
                        "snr" : 7,
                        "gw_id" : "eui-7276fffffe0103f0"
                        "rssi" : -122,
                        "snr" : -7,
                        "gw_id" : "eui-7276fffffe0103ec"
                        "rssi" : -99,
                        "snr" : 8,
                        "gw_id" : "eui-7276fffffe0103ec"
        "lat" : 50.93727,
        "serial" : "70B3D5499247643E",
        "sf" : "SF7BW125"

Creating a GPS position logger for the LoRaWAN network has been an interesting task, and it has been very easy to iterate and add functionality. It is a very simple project to complete and it can be interesting seeing which base-stations are able to receive your signals.