Messing About with LoRa

In this post is to show how easy it is to do some very basic range testing with two LoRa devices, one operating as a transmitter and the other as a receiver.

LoRa IoT AM+T

In RK, we count ourselves among the pioneers in the use of low power radio for AM+T so we continue to keep an eye on the emerging technologies. One of these technologies is LoRa which is being aimed at a bunch of different IoT applications. LoRa can operate in two modes: peer-to-peer and LoRaWAN. LoRaWAN is ultimately the way to scale this technology and we will have a future blog entry on what we are doing to deploy a LoRaWAN basestation at our offices. In the meantime, lets have a look at what it takes to do some peer-to-peer testing.

First of all let me give credit to Paul who wrote this article. I’m going to refine it a little to make use of the equipment that we had at our disposal.

What we want to do in this post is to show how easy it is to do some very basic range testing with two LoRa devices, one operating as a transmitter and the other as a receiver.

The Motes

First of all we ordered two Microchip LoRa motes here. These operate on 868MHz (the legal frequency in Ireland and many other parts of the world). These are nice little gadgets with an OLED screen for reporting status. Also, there is an onboard PIC MCU. This means that you can write little programs that will allow the gadget to act in an untethered way.

Communicating with the Motes

The motes are based on the Microchip RN2483 LoRa modem. The RN2483, like a lot of devices these days, can be configured and operated with simple console commands. The list of available command can be found in this PDF. There are 3 levels of commands:

The command sys get ver returns the firmware version, it is a good way to ensure the mote works.

sys get ver
 RN2483 1.0.1 Dec 15 2015 09:38:09

Plugging in the Transmitter

I plugged one of the motes into a SolidRun CuBox-i that we had lying about. This uses the standard Debian distro that can be downloaded off SolidRuns website. I cannot see why you could not use Beaglebone Black, RPi or any other Linux/ARM setup for this.

Plugging in the Receiver

I plugged the other mote into my mac. This will be the receiver.

Transmitter Software

On the SolidRun, you need to take Paul’s script and run it. You may find that the serial port needs to be changed from /dev/ttyUSB0. The mote pretends to be a modem so it calls itself /dev/ttyACM0 in my case. This meant that i called Paul’s script as follows:

bash loratx.sh /dev/ttyACM0

Here is Pauls script:

#!/bin/bash
# LoRa loop send a message in loop over LoRa medium at default frequency
# module is connected to /dev/ttyUSB0 device
dev=$1

startRet() {
   (if read -t 3 ret < $dev; then echo $ret ; return 0 ; else return 1 ; fi) &
   wf=$!
}
checkRet() {
   wait $wf
   return $?
}


stty -F ${dev} 57600 cs8 -cstopb -parenb -echo

startRet ; echo "sys get ver" > $dev
if checkRet ; then
  startRet ; echo "mac pause" > $dev
  if checkRet ; then
     startRet; echo "radio set pwr 14" > $dev
     if checkRet ; then
        i=0
        while true ; do
           echo emiting $i
           startRet ; echo "radio tx 123456789AB" > $dev
           sleep 100
           i=$(( $i + 1 ))
        done
     else echo "error setting power"
     fi
  else echo "error setting mac in pause"
  fi

else echo "cant establish communication"
fi

Setting up the Receiver Side

On my mac, I coded up the following dirty little thing in python:

import serial
import time
import datetime
import sys

echo=False

def readlineCR(port):
    rv = ""
    while True:
        ch = port.read()
        rv += ch
        if ch=='r' or ch=='':
            return rv

def sendcmd(cmd):
    if echo:
        print (">>"+cmd)
    port.write(cmd+"rn")

def sendcmdprintresp(cmd):
    sendcmd(cmd)
    rcv = readlineCR(port)
    print "<<"+rcv

port = serial.Serial("/dev/tty.usbmodem1421", baudrate=57600, timeout=3.0)

sendcmdprintresp("sys get ver")

sendcmdprintresp("mac pause")


while True:
    sendcmd("radio rx 0")
    resp=readlineCR(port).strip()
    #print "<<"+resp
    if (resp == "ok"):
        while True:
           resp=readlineCR(port).strip()
           if (resp.startswith("radio_rx")):
               print "aRECEIVED at "+str(datetime.datetime.now().time())+": "+resp.split("  ")[1]
               break
           elif (resp.startswith("radio_err")):
               print "RECEIVED error"
               break;

           time.sleep(1)
    else:
        print "ERROR: "+resp
        print "WAITING TO CLEAR"
        time.sleep(10)

This assumes that the port is at /dev/tty.usbmodem1421. In my case it was but you will probably need to change it for your system. You will note that this prints an ASCII BELL character so you can hear each ping as it arrives.

Running the Tests

So anyhow I set everything up in the lab such that the mac was pinging nicely. To increase the frequency of the pings from every 100 seconds, you might want to change the "sleep 100” to something like “sleep 30”.

I left the transmitter in our lab. This lab is on the top floor of a four story building in Limerick city centre - a town that is mostly low-rise. This means that we are relatively high up with respect to much of the the local building stock. However, our building has a lot of metal along with a metal roof so I expect attenuation to be significant. To put it another way, my transmitter was placed in a rather sub-optimal location.

I then took the receiver to the basement car park of our building and I received every ping. This is impressive - you would certainly not see this with something like Zigbee unless you installed a bunch of repeaters.

Then I went driving to see where the range faltered. This map shows where I began receiving either 1) mostly errors or 2) nothing. The performance to the West was very good and this is not wholly surprising as there are far fewer buildings in this direction. Also the transmitter is situated above this low-lying region.

The performance to the East was less impressive. Right now I associate that with the extra building density and the urban canyon effect along with the rise and fall of the terrain - Limerick is built on some gentle rolling hills.

Overall, this technology looks very promising even when deployed in absolutely lousy conditions, like I just did. Very shortly we will be deploying a LoRaWAN base station for Limerick on The Things Network and we will be doing this in a much more professional way.

Contact us