Hands on with LoRa in North America. #3

HopeRF RFM95, Teensy and Multitech LoRa Conduit working together.

<-PART 2

In order to test HopeRF radio, I decided to use the existing code running on Teensy MCU (v: 3.2) in public LoRa mode.
You will need the following:

Keep in mind that my goal here is to focus on HopeRF’s radio testing as Teensy MCU is way too expensive and consumes too much power to even be consider it for production usage.

To start, you will need to solder few wires together:

Teensy LC/3.1/3.2 — RFM92/95

GND — GND

3.3V — 3.3V

RFM95 & Teensy LoRa Solution

RFM95 & Teensy

2 — DIO0

5 — DIO1

6 — DIO2

9 — RESET

10 — NSS

11 — MOSI

12 — MISO

13 — SCK

Since Teensy is basically yet another Arduino Development Platform, we will use Arduino SDK with Teensyduino add-on to program Teensy with IBM’s LoraMac.

You can just follow this set of instructions to get Teensyduino running on your platform.

Once installed, try compiling one of the demo programs for Teensy, just to make sure that everything went ok.

Now, we are ready to proceed with actual LoRaMac code. First, Clone the whole package to your system, then add it as new library to your Arduino SDK.

LoRa LoRaMac Installation

You are almost done ;), just few modifications left…

I will be using defaults with the exception of the DevAddr below.

In the main file, we need to change DevAddr to something unique globally.

static const u4_t DEVADDR = 0x03FF0001 ;

//In this example I used 0x03FFEBB2, you will see it below in the section when we define node manually in gateway's db. 

This is equivalent of MAC address associated with your Ethernet port. In production, you will have your own prefix, obtained from IEEE, but for now we can just use anything, as long as it’s not duplicated on your network.

Then, we will adjust Spreading Factor from 11 to 9 to match gateway configuration (as per FCC in North America, Spreading Factor could be between 7 and 10).
// Set data rate and transmit power (note: txpow seems to be ignored by the library)
LMIC_setDrTxpow(DR_SF9,14);

Now, you need to use your favoured editor to change the config.h located under arduino libraries (in case of MacOS: /Users/<Your User Name>/Documents/Arduino/libraries/arduino-lmic-v1.5-master/src/lmic to support 915MHz as North American ISM frequency and SX1276 chip for RFM95 HopeRF radio module.
#ifndef _lmic_config_h_
#define _lmic_config_h_

// In the original LMIC code, these config values were defined on the
// gcc commandline. Since Arduino does not allow easily modifying the
// compiler commandline, use this file instead. (MK)

//#define CFG_eu868 1
#define CFG_us915 1
//#define CFG_sx1272_radio 1
#define CFG_sx1276_radio 1

// 50 μs per tick
#define US_PER_OSTICK 50
#define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK)

#endif // _lmic_config_h_

You can connect your Teensy, compile your code and program your board.

Go back to your gateway and manually add the node:
# nc -u localhost 6677
node add 03FFEBB2 0200000000EEFFC0 4242456789ABCDEF 2B7E151628AED2A6ABF7158809CF4F3C 2B7E151628AED2A6ABF7158809CF4F3C

Using the following syntax: node add [DevAddr] [APPEUI] [DEVEUI] [NwkSKey] [AppSKey]

Depending if you run gateway or packet forwarder, go to you logs or run mosquitto_sub -t lora/+/up to see incoming packets.

As soon as you run your demo code, you should see something like that:
{"chan":7,"cls":0,"codr":"4/5","data":"d29ybGQ=","datr":"SF9BW125","freq":"913.3","lsnr":"-12.8","modu":"LORA","rfch":1,"rssi":-113,"seqn":5,"size":8,"timestamp":"2015-11-18T16:08:51Z","tmst":2397020652}

where “d29ybGQ=” is base64 representation of the word “hi”.

Almost forgot about last cosmetic modification… in order to avoid an extra character at the end of the string, modify
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata), 0);

to // Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(my data)-1, 0);

Enjoy and stay tuned…

Soon, I will share my experience with modules from one of the new LoRa node makers from China.

I will also experiment with LoRa range, explaining ways to get the most from your node…

Stay tuned…

Hands on with LoRa in North America. #2

Public LoRa Configuration

In the previous post, I have explained how to configure Multitech Conduit and mDot module to communicate with each other, using private LoRa network mode. Today, we will change it to use public LoRa mode, however we still use just one device to observe incoming packets. We will be running Network Server together with a Gateway on our Conduit.

Let’s change configuration of the LoRa-network-server by editing /var/config/lora/lora-network-server.conf like 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": true, /* set to false for private LoRa network with mDots + Conduit */
"leasetime": 1440, /* time until mDot join expires (minutes) */
"eui": "02:00:00:00:00:ee:ff:c0", /* configure network security */
"key": "2b:7e:15:16:28:ae:d2:a6:ab:f7:15:88:09:cf:4f:3c"
},
"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
}
}

We can then restart the server by executing the following command:

/etc/init.d/lora-network-server restart

Now, we will connect to our mDot module, and using AT commands we will change it’s network mode to be a public mode plus we will provide network related information to match our Conduit system. Actually, we will be using the same network information which one would use to connect to The Things Network, in a future post we will show how to use the Packet Forwarder and connect to their Network Server.

Lets execute the following:

AT+PN=1      //set the public network mode

AT+NI=0,0200000000eeffc0     //set network id
AT+NK=0,2b7e151628aed2a6abf7158809cf4f3c //set network key

Run AT&V, and you should see something like that:

Device ID: 00:80:00:00:00:00:9e:be
Frequency Band: FB_915
Frequency Sub Band: 7
Public Network: on
Start Up Mode: COMMAND
Network Address: 00000001
Network ID: 02:00:00:00:00:ee:ff:c0
Network ID Passphrase:
Network Key: 2b.7e.15.16.28.ae.d2.a6.ab.f7.15.88.09.cf.4f.3c
Network Key Passphrase:
Network Session Key: cb.75.96.1a.ae.fa.d1.23.ca.86.f1.dc.97.6f.28.10
Data Session Key: 0c.5c.3c.ff.d9.16.9b.fe.a6.0c.6c.29.b8.b6.34.59
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 Mode: INTERVAL

Wake Interval: 10 s
Wake Delay: 100 ms
Wake Timeout: 20 ms
Log Level: 0

Public LoRa
At this point you are ready to go, connect to your mDot and send something to your conduit looking either at logs or subscribing to mqtt topic as per instructions from the previous post

AT+JOIN

AT+SEND=hello world

In the next post, we will connect 3rd party, HopeRF LoRa radio with Teensy 3.2 MCU and then test it with our Conduit Public LoRa gateway

LoRa FAQ

PART 3->

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 192.168.2.1 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 192.168.2.1 (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:
address 192.168.2.99
netmask 255.255.255.0
gateway 192.168.2.1
post-up echo "nameserver 192.168.2.5" > /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:
at+fsb=7

OK
at+ni=1,IoTHubLoRa
Set Network Name: IoTHubLoRa

OK
at+nk=1,LoRaR0cK$
Set Network Passphrase: LoRaR0cK$

OK
at&w

OK
atz

OK

 

Based on the following:
AT+FSB=
AT+NI=1,
AT+NK=1,
Check that the settings are correct
AT&V
Save and restart
AT&W
ATZ

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: 00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00
Data Session Key: 00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00
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 Mode: INTERVAL
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:

AT+JOIN

Hopfefully, you will see the following:

at+join
Successfully joined network

OK

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 127.0.0.1:33064) 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:
AT+SEND=hello
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 (127.0.0.1) 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 (127.0.0.1) 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:

Execute:
mosquitto_sub -t lora/+/up
and you should see the following:
{"chan":6,"cls":0,"codr":"4/5","data":"aGVsbG8=","datr":"SF9BW125","freq":"913.1","lsnr":"11.5","modu":"LORA","rfch":1,"rssi":-28,"seqn":2,"size":8,"timestamp":"2015-11-19T17:38:54Z","tmst":4263474652}
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:

AT+DI
In return, we get:
0:80:00:00:00:00:9e:be
OK

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
AT+SEND="blah"
68656c6c6f

OK
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->