Hands on with LoRa in North America. #1

There are plenty of activities around LoRa in Europe, especially in The Netherlands. Open and totally free, city wide networks are being deployed thanks to “The Things Network” team, but also commercial country wide deployments by operators like KPN. At the same time, LoRa in North America seems to lag slightly behind, most likely due to FCC regulations calling for more complexity and sophistication in a gateway component.

In Europe, the LoRa gateway needs to have just one SX1301 concentrator capable of supporting up to 8 separate bands.

The ETSI requires to support minimum 3 channels operating at the following frequencies:

  • 868.10
  • 868.30
  • 868.50

with duty cycle restricted to <1%.

In North America, FCC defines 64 x 125kHz channels and 8 x 500kHz channels (plus 8 downstream channels), however it calls for min 50 channels to operate at full power.

FCC regulation requires hopping over at least 50 channels when using maximum output power. It is possible to have end-devices with less channels (at least six 125 kHz channels) when limiting the end- device transmit power to 21 dBm.

NOTE: please see the post about hybrid mode operation.

Since Samtech’s SX1301 concentrator operates in hybrid mode and provides 8 x 125kHz + 1 x downstream channels, you can see that a “full” gateway will require 8 SX1301 concentrators thus making it relatively complex and expensive in comparison to European counterpart.

At this point, LoRa Multitech Conduitgateways from Multitech operate with just one SX1301 concentrator, thus operating in hybrid mode on one of the 8 sub-bands (with 8 channels per sub-band). Lab-link will be using 6 Sx1301 concentrators, which apparently will allow them to operate at full power (“full gateway mode”), most likely by providing 48 125kHz and 6 500kHz channels at the same time (to be confirmed). At the same time, Kerlink already provides engineering samples of their gateways operating in hybrid mode.  NOTE: please see the post about hybrid mode operation. 

In the near future, I will write a dedicated post to clarify confusion behind LoRa frequency requirements for North America.

Since, I am writing this article in Canada (Industry Canada follows closely FCC regulations), I will be testing North American variants.

LoRa Multitech ConduitFor the gateway, I will be using ultra versatile Multitech Conduit preloaded with mLinux.In addition, I installed Multitech’s LoRa module  with a single SX1301 and operating at 915MHz frequency. Since one SX1301 can handle only 8 channels or 1 sub-band I will have to choose one in my configuration.



I also decided to start with Multitech MultiConnect mDot Developer Kit.

mDot, LoRa in North America

The mDot provides DB9 and microUSB connectors. In order to use AT command set, you will actually need to connect both to your system. The DB9 will be your actual console, and the USB will provide power plus can act as a debug console, if needed.

First, we need to configure the Multitech Conduit. Unit comes preconfigured with and no default gateway defined (meaning that you will not be able to access it from outside your LAN). My version did not come with a 3G radio which most likely would be configured as your default route. In order to change the IP to accommodate your setup you can either ssh (as root with password root) to (just change your laptop’s IP temporarily and connect it directly to Multitech’s box) or you can use supplied screwdriver 😉 and remove the front Multitech logo to get access to a USB console port.

Use vi to edit /etc/network/interfaces to something like:
post-up echo "nameserver" > /etc/resolv.conf

You can see that I not only modified the IP address but I also added a gateway statement which basically defines a default route on your network (router’s IP address) and I also defined a DNS server. Since the system is also intended to work with a 3G radio and dynamically assigned IP addresses via DHCP server of your mobile operator, /etc/resolv.conf will not persistently hold your changes.
This is the quickest way around to get your statically defined DNS server into resolv.conf.

For the first config, we will use private LoRa network. The Multitech box contains several components to allow you to act as a gateway or gateway + network server. Actually, you can also add your application server there as well.

Lora Public vs Private

For our testing, we will not really use an application server. Initially, I will use gateway + network server functionality to display incoming packets via mqtt.

So, let’s configure our Conduit box to work as gateway+network server in a Private LoRa mode using North American band.

Connect to your conduit system and configure the LoRa Network parameters:
mkdir /var/config/lora
cp /opt/lora/lora-network-server.conf.sample /var/config/lora/lora-network-server.conf

Then using vi open /var/config/lora/lora-network-server.conf and modify as below:

"lora": {
"netID": "010203", /* netID for beacon packets */
"frequencyBand": "915", /* US="915", EU="868" */
"frequencySubBand": 7, /* Sub-band for US operation, 1-8 */
"rx1DatarateOffset": 0, /* Datarate offset for mote rx window 1 sent in join response (0-3) */
"rx2Datarate": 12, /* Datarate for mote rx window 2 sent in join response (7-12) */
"maxTxPower": 14, /* Max Tx power (dBm), -6 to 26 default 14 */
"frequencyEU": 867500000 /* center freq for extra EU channels (Hz) */
"udp": {
"appPortUp": 1784, /* port for user-developed application use */
"appPortDown": 1786 /* port for user-developed application use */
"addressRange": {
"start": "00:00:00:01", /* address range used for mDots */
"end": "FF:FF:FF:FE"
"network": {
"public": false, /* set to false for private LoRa network with mDots + Conduit */
"leasetime": 1440, /* time until mDot join expires (minutes) */
"name": "IoTHubLoRa", /* configure network security */
"passphrase": "LoRaR0cK$"
"log" : {
"console" : true,
"syslog" : false,
"level" : 30, /* error=10, warn=20, info=30, debug=50, trace=60, max=100 */
"path": "/var/log/lora-network-server.log"
"mqtt": {
"enabled": true

Where name and passphrase are at least 8 characters long, your frequency band is defined as 915 (915MHz North American band),  network defined as private (public : false) and frequency sub-band is defined as anything between 1-8 (needs to match configuration on mDot).

At this point you can either restart the box, or reinitialize eth0 and restart lora-network-server by executing the following:

ifconfig eth0 down
;ifconfig eth0 up
/etc/init.d/lora-network-server restart

Allright, we are ready to switch to mDote Development Board.
Connect your DB9 cable as a console and USB as a power source and debug interface.
If you want to setup the virtual USB COM port for debugging at this time, install STMicro’s ARM mbed serial port driver, but everything you really need is a serial port with the mDot’s default LoRa AT command app.

Configure your console application to 115k 8n1 and no hardware flow control and hopefully we are good to go. To confirm, type AT&V and you should see the current configuration of the module. In order to configure your mDot to match configuration of the Conduit you will need to change the Sub-Band and define Network Name and Network Passphrase. In this example, I will use the sample ones:

Set Network Name: IoTHubLoRa

Set Network Passphrase: LoRaR0cK$





Based on the following:
Check that the settings are correct
Save and restart

AT&V should return the following:
Device ID: 00:80:00:00:00:00:9e:be
Frequency Band: FB_915
Frequency Sub Band: 7
Public Network: off
Start Up Mode: COMMAND
Network Address: 00000000
Network ID: ea:97:c4:34:5d:25:fb:07
Network ID Passphrase: IoTHubLoRa
Network Key: 6c.f7.3a.96.96.3f.ec.f6.00.47.a2.80.18.3f.06.aa
Network Key Passphrase: LoRaR0cK$
Network Session Key:
Data Session Key:
Network Join Mode: OTA
Network Join Retries: 2
Join Byte Order: LSB
Link Check Threshold: off
Link Check Count: off
Error Correction: 1 bytes
ACK Retries: off
Encryption: on
CRC: on
Adaptive Data Rate: off
Command Echo: on
Verbose Response: off
Tx Frequency: 0
Tx Data Rate: SF_9
Tx Power: 11
Tx Wait: on
Tx Inverted Signal: off
Rx Frequency: 903700000
Rx Data Rate: SF_9
Rx Inverted Signal: on
Rx Output Style: HEXADECIMAL
Debug Baud Rate: 115200
Serial Baud Rate: 115200
Wake Interval: 10 s
Wake Delay: 100 ms
Wake Timeout: 20 ms
Log Level: 0

At this point, we will try to join our private LoRa network:


Hopfefully, you will see the following:

Successfully joined network


On the server side, run:

tail -f /var/log/lora-network-server.log
in a couple of seconds you should see something similar to:
17:29:47:145|INFO| Parsing 1 rx packets
17:29:47:145|WARNING| Recv'd frame failed CRC check
17:31:41:244|INFO| Parsing 1 rx packets
17:31:41:245|INFO| Received join request
17:31:41:248|INFO| Device found in DB, assigning address: 1
17:31:41:252|INFO| Queue join response 17 bytes
17:31:41:266|INFO| Send Join Accept - EUI: 00:80:00:00:00:00:9e:be ADDR: 00000001
17:31:41:266|INFO| Schedule TX Time on air: 150 ms
17:31:46:127|INFO| Frame transmitted to 00:00:00:01 via GW (00:80:00:00:00:00:9a:d3 Chan LC7 Seq# a
17:31:46:136|INFO| Transmit message 187 bytes

We can send across our first few bytes, for example “hello”
On mDot console just execute:
In the log we should observe:
17:35:39:926|INFO| Parsing 2 rx packets
17:35:39:927|INFO| SeqNo: 00000000 PrevSeqNo: 00000000 Duplicate: no

17:35:39:928|INFO| Addr: 00:00:00:01 MIC Check: passed
17:35:39:942|INFO| Packet accepted from Node 00:00:00:01 GW 00:80:00:00:00:00:9a:d3 ( Seq# 0 ADR disabled SF9BW125
17:35:39:943|INFO| Schedule TX Time on air: 150 ms
17:35:39:944|INFO| SeqNo: 00000000 PrevSeqNo: 00000000 Duplicate: no

17:35:39:945|INFO| Addr: 00:00:00:01 MIC Check: passed
17:35:39:958|INFO| Packet accepted from Node 00:00:00:01 GW 00:80:00:00:00:00:9a:d3 ( Seq# 0 ADR disabled SF9BW125
17:35:39:958|INFO| Schedule TX Time on air: 150 ms
17:35:39:958|INFO| Using RX window 2 : 00:00:00:01

But we can also subscribe to our local mosquito broker and see received events there:

mosquitto_sub -t lora/+/up
and you should see the following:
Where aGVsbG8= is base64 encoded hello

Now, we should try to send something back, but before we do that, allow me to clarify something.

There are 3 classes of devices in LoRaWan specification. At this point, only class A is supported, for reference please see the definition of all 3 from LoraWan specification:

Bi-directional end-devices (Class A): End-devices of Class A allow for bi- directional communications whereby each end-device‘s uplink transmission is followed by two short downlink receive windows. The transmission slot scheduled by the end-device is based on its own communication needs with a small variation based on a random time basis (ALOHA-type of protocol). This Class A operation is the lowest power end-device system for applications that only require downlink communication from the server shortly after the end-device has sent an uplink transmission. Downlink communications from the server at any other time will have to wait until the next scheduled uplink.

Bi-directional end-devices with scheduled receive slots (Class B): End-devices of Class B allow for more receive slots. In addition to the Class A random receive windows, Class B devices open extra receive windows at scheduled times. In order for the End-device to open it receive window at the scheduled time it receives a time synchronized Beacon from the gateway. This allows the server to know when the end-device is listening.

Bi-directional end-devices with maximal receive slots (Class C): End-devices of Class C have nearly continuously open receive windows, only closed when transmitting. Class C end-device will use more power to operate than Class A or Class B but they offer the lowest latency for server to end-device communication.

Since we operate as class A, we can only send packets back to a node AFTER receiving uplink transmission from that specific node.

So in practice, we will first send a packet from our Conduit (it will wait in a queue). Before we do that, we need to know the unique id of our node.

On the mDot execute:

In return, we get:

and then we execute the following on our server:
mosquitto_pub -t lora/0:80:00:00:00:00:9e:be/down -m '{ "data":"aGVsbG8=" }'
but we will not see anything on the mDot until we send something to the server, so lets send “blah” and look for a message from the Conduit

Here we go, 68656c6c6f is a HEX representation of hello
I believe that by now, you have a brief understanding and some limited hands-on experience with LoRa. In the next post (Hands on with LoRa in North America. #2), I will discuss Public LoRaWan configuration followed by testing with HopeRF LoRa radio module with Teensy MCU.

PART 2->

7 Comments Hands on with LoRa in North America. #1

  1. Yuqian

    Hi, IotMan,

    could you please add some instruction for how to upgrade the firmware of Multitech Conduit, that will be easy for newbie to get start with Multitech Conduit 🙂

    Thank you

  2. Mehrad

    Hi IoT Man,

    Some great bunch of information here 🙂 Wish I have read this couple of months ago. Learned the stuff the hard way. haha…

    I gotta come back with some good questions as I am in quite the same stage of testing as you are. 🙂

  3. Francisco

    Hi im having some problem to join the network. I did the same as you, but i have a public network, so i don’t have a ttn name or password. I want to join OTA , however will end up with join error. Any clue? Thanks

    1. IotMan

      Can you provide more details? I am assuming that you are using Conduit and Multitech node, correct? Both are configured, to use public network, so your timeout is longer than in case of private network. You also need to provide App and Net IDs instead of Session key values;..

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.