Hands On with RM7201 & RM7601 LoRa modules by Dapu Telecom

During the last LoRa Alliance meeting in Rotterdam we discovered a new LoRa modules  made by Shenzhen (China) based company, Dapu Telecom.

There are 4 options available, 2 radio only modules based on SX1272 and SX1276 Semtech chips and two complete modules with MCUs also based on SX1272 and SX1276 called respectively RM7201 and RM7601.

For this exercise, we obtained radios with MCUs. One important note, there is no specific part number for EU, Asia or North America. According to Dapu, the software stack will set the radio into the respective ISM band for your region. This requires further investigation, as small hardware changes between EU and North America (RF part) are present in Semtech’s reference designs.

Here is the RM7601 with MCU and SX1276 radio chip

Screen Shot 2015-12-21 at 2.49.54 PM

This is theRM7201 with MCU and SX1272 radio chip

Screen Shot 2015-12-21 at 8.51.07 PM

Both of them use the same MCU – STM32L151C8U6, only the radio is different as mentioned above.

If you go to the official Semtech git repository and look at their demo code, you will find out that Semtech uses the STM32L151 MCU series as well, just using a different variant of this MCU. This will most likely allow us to port the Semtech LoraWan stack to DAPU hardware with minimal effort.

First, let’s try the “big one” – RM7601.

Get the latest source code for the Semtech LoRaWan stack from https://github.com/Lora-net/LoRaMac-node  or just download the latest zip file from https://github.com/Lora-net/LoRaMac-node/archive/master.zip.

Store the source code onto your local hard drive, let’s say C:\LORA\ and unzip it, then go to C:\LORA\LoRaMac-node-master\Keil\SensorNode\LoRaMac\classA, use Keil5 (i used Keil5.17 lasted one) to open the project. Why “SensorNode” demo code? because that code uses the same MCU as one used in RM7601 module.

As Semtech used Keil4 to create the LoRaWAN demo code, Keil will first migrate the project to Keil5 when you first open it, just allow it do to so.

In the RM7601 data sheet for the SX1276 radio chip we see the following pin definitions:

Screen Shot 2015-12-21 at 8.57.44 PM

following this table, we can quickly change the Semtech source code and update pin definitions in C:\LORA\LoRaMac-node-master\src\boards\SensorNode\board.h to the following pins as follows:

/*
* Board MCU pins definitions
*/
#define RADIO_RESET PB_10
#define RADIO_MOSI PA_7
#define RADIO_MISO PA_6
#define RADIO_SCLK PA_5
#define RADIO_NSS PA_4
#define RADIO_DIO_0 PB_11
#define RADIO_DIO_1 PC_13
#define RADIO_DIO_2 PB_9
#define RADIO_DIO_3 PB_4
#define RADIO_DIO_4 PB_3
#define RADIO_DIO_5 PA_15

#define RADIO_ANT_SWITCH_HF PA_0
#define RADIO_ANT_SWITCH_LF PA_1

#define OSC_LSE_IN PC_14
#define OSC_LSE_OUT PC_15
#define OSC_HSE_IN PH_0
#define OSC_HSE_OUT PH_1

The most important ones are the SPI bus 4 wires and radio DIO_0 to DIO_5 definitions, just make sure that you have correct pin definition in your code.

Screen Shot 2015-12-21 at 3.41.47 PM

Change the main.c file to join the gateway using OTA mode:

#define OVER_THE_AIR_ACTIVATION 1

add the AppEUI, DevEUI and AppKey based on your gateway settings, here is what I did:

#define LORAWAN_DEVICE_EUI { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }
#define LORAWAN_APPLICATION_EUI { 0xc0, 0xff,0xee, 0x00, 0x00, 0x00,0x00,0x02 }
#define LORAWAN_APPLICATION_KEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }

Please pay attention, the AppEUI is reversed (LSB ENDIANNESS).

As my LoRa Gateway is running at 915Mhz frequency, I changed the compiler option to “Loramac-915”. It is important and don’t forget to set this for properly your region.

Here are my gateway settings:

root@mtcdt:~# cat /var/config/lora/lora-network-server.conf
{
  "lora": {
    "netID": "010203", /* netID for beacon packets */
    "frequencyBand": "915", /* US="915", EU="868" */
    "frequencySubBand": 1, /* 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": 26, /* Max Tx power (dBm), -6 to 26 */
    "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" : 100, /* error=10, warn=20, info=30, debug=50, trace=60, max=100 */
    "path": "/var/log/lora-network-server.log"
  },
  "mqtt": {
    "enabled": true
  }
}

Compile the code and flash it to the RM7601, then login via ssh into your gateway and watch for our updated module to join the gateway. For help on how to set up the Multi-tech gateway, please follow our blog posts:

LoRa Hands On Part 1

LoRa Hands On Part 2

LoRa Hands On Part 3

$ ssh -l root 192.168.1.181
root@mtcdt:~# tail -f /var/log/lora-network-server.log
8:19:36:716|DEBUG| Received packet
================================
000 00 c0 ff ee 00 00 00 00
008 02 01 23 45 67 89 ab cd
010 ef 27 9b 5f f0 dd d1

8:19:36:717|DEBUG| Rx on 903700000, rssi: -27 snr: 98
8:19:36:717|DEBUG| Received frame: type: Join Request
8:19:36:717|INFO| Received join request
8:19:36:718|DEBUG| BUFFER: 00c0ffee00000000020123456789abcdef279b
8:19:36:718|DEBUG| App EUI: 02.00.00.00.00.ee.ff.c0
8:19:36:718|DEBUG| Dev EUI: ef.cd.ab.89.67.45.23.01
8:19:36:719|DEBUG| Nonce: 00009b27
8:19:36:719|DEBUG| MIC is valid
8:19:36:720|DEBUG| Got appkey: 2b.7e.15.16.28.ae.d2.a6.ab.f7.15.88.09.cf.4f.3c
8:19:36:720|DEBUG| DEV NONCE: 9b27
8:19:36:720|DEBUG| APP NONCE: 3be317
8:19:36:721|DEBUG| session keys: bac1a83854b7545eec7e3df4f305991d 9839190af648989e6d344ac5078cc4ce
8:19:36:721|TRACE| SQL query = SELECT address FROM nodes WHERE deveui = "efcdab8967452301"
8:19:36:723|INFO| Device found in DB, assigning address: 7
8:19:36:723|DEBUG| Update session keys
8:19:36:724|TRACE| SQL query = UPDATE nodes SET authenticationkey = "bac1a83854b7545eec7e3df4f305991d", encryptionkey = "9839190af648989e6d344ac5078cc4ce" WHERE address = "00000007"
8:19:36:727|DEBUG| Set node active: 1
8:19:36:727|INFO| Queue join response 17 bytes
8:19:36:728|DEBUG| Set node active: 1
8:19:36:728|DEBUG| update bestGateway
8:19:36:728|DEBUG| Time: 39995444
8:19:36:728|DEBUG| App Queue Length: 1
8:19:36:729|DEBUG| Rx Frame seq 0 snr 98
8:19:36:729|DEBUG| SpreadingFactorStore::Add
8:19:36:729|DEBUG| FindSF : snr : 98 100 -2
8:19:36:731|TRACE| SQL query = UPDATE nodes SET jointime = "2015-12-21T08:19:36Z" WHERE address = "00000007"
8:19:36:734|TRACE| SQL query = UPDATE packets SET port = 2, seqno = 0, gateway = "0080000000009f6c", time = "2015-12-21T08:19:36Z", microseconds = 713268000, rssi = -27, channel = 7, lsnr_cB = 98, spread = 10, modulationbandwidth = 125, data = "0123456789abcdef279b" WHERE node = "00000007"
8:19:36:738|TRACE| SQL query = UPDATE nodes SET lastuppacketid = 1, lastmessagems = 51204 WHERE address = "00000007"
8:19:36:740|TRACE| SQL query = UPDATE gateways SET lastuppacketid = 1 WHERE address = "0080000000009f6c"
8:19:36:743|DEBUG| getTimeOnAirMs dr: 10 bw: 2 pl: 8 sz: 16 toa: 82
8:19:36:744|INFO| Send Join Accept - EUI: ef:cd:ab:89:67:45:23:01 ADDR: 00000007
8:19:36:744|INFO| Schedule TX Time on air: 150 ms
8:19:36:752|DEBUG| Send MQTT message
8:19:36:753|DEBUG| UDP message: lora/ef:cd:ab:89:67:45:23:01/joined
8:19:36:753|DEBUG| UDP port: 1784
8:19:36:756|TRACE| Published message: 2
8:19:37:266|TRACE| Parse downstream message 12 bytes
8:19:37:267|TRACE| Gateway 00:80:00:00:00:00:9f:6c seen IP address 127.0.0.1:33742
8:19:41:597|DEBUG| is frame ready?
8:19:41:597|DEBUG| App Queue Length: 1
8:19:41:597|DEBUG| BestGateway: 80000000009f6c
8:19:41:598|DEBUG| Start
8:19:41:598|INFO| Frame transmitted to 00:00:00:07 via GW (00:80:00:00:00:00:9f:6c Chan FC1 127.0.0.1:33742) Seq# 2
8:19:41:599|TRACE| SQL query = UPDATE nodes SET lastdownmsgseqno = 2 WHERE address = "00000007"
8:19:41:602|DEBUG| App Data Queue: 1 front size: 17 available: 242
8:19:41:602|DEBUG| check if front is join request 17 bytes
8:19:41:602|DEBUG| Start
8:19:41:603|TRACE| App Data Queue - Join Popped
8:19:41:603|DEBUG| Transmitted Frame data
================================
000 20 9f aa ac 1f ac d7 bc
008 e5 aa 44 0d 7e ca 24 8a
010 dd

8:19:41:603|DEBUG| rx1Offset: 0 rx1Datarate: 10
8:19:41:604|DEBUG| Use JoinResponse Window Time
8:19:41:606|DEBUG| JSON tx: {
"txpk" : {
  "codr" : "4/5",
  "data" : "IJ+qrB+s17zlqkQNfsokit0",
  "datr" : "SF10BW500",
  "freq" : 927.5,
  "ipol" : true,
  "modu" : "LORA",
  "ncrc" : false,
  "powe" : 26,
  "rfch" : 0,
  "size" : 17,
  "tmst" : 44995444
}
}

Seems that everything worked right away and we’ve joined the gateway!

There are a few parameters we can verify in the gateway log above, which are marked in bold.

Next, let’s try the “small one” – RM7201.

The RM7201 uses same MCU as the RM7601, just the RF radio is  different, SX1272 instead of SX1276. For both the SX1276 and SX1272 data sheets, check the Semtech website: http://www.semtech.com/apps/product.php?pn=sx1272&x=0&y=0 http://www.semtech.com/wireless-rf/rf-transceivers/sx1276/ and http://www.semtech.com/apps/product.php?pn=sx1272&x=0&y=0.

As with RM7601, I expected simply changes in the config files, but unfortunately, it was not that easy . At the beginning, I’ve tried to use the same project – NodeSensor, but I quickly found out that I would have to port the SX1272 driver as this project does not include support for the SX1272. Porting the SX1272 driver should be easy as most likely it would involve just changing some header definitions. However, after looking deeper into Semtech code, I found another project which does have support for the SX1272, the Loramote project.

As the RM7201 uses a smaller header, my connector would not fit, so i soldered 4 wires (SWCLK, SWIO, VDD and GND) to the RM7201 module directly:

 Screen Shot 2015-12-21 at 4.22.42 PM

Change the board.h definition as follows:

/*!
* Board MCU pins definitions
*/

#define RADIO_RESET PB_10

#define RADIO_MOSI PA_7
#define RADIO_MISO PA_6
#define RADIO_SCLK PA_5
#define RADIO_NSS PA_4

#define RADIO_DIO_0 PB_11
#define RADIO_DIO_1 PC_13
#define RADIO_DIO_2 PB_9
#define RADIO_DIO_3 PB_4
#define RADIO_DIO_4 PB_3
#define RADIO_DIO_5 PA_15

#define RADIO_ANT_SWITCH_RX PA_0
#define RADIO_ANT_SWITCH_TX PA_1

#define OSC_LSE_IN PC_14
#define OSC_LSE_OUT PC_15

#define OSC_HSE_IN PH_0
#define OSC_HSE_OUT PH_1

#define USB_DM PA_11
#define USB_DP PA_12

Now use ssh to login to the gateway again and watch the log output:

root@mtcdt:~# tail -f /var/log/lora-network-server.log 

9:12:53:3|DEBUG| Received packet
================================
000 00 c0 ff ee 00 00 00 00
008 02 01 63 34 73 38 31 38
010 32 23 3c 52 a9 11 90

9:12:53:3|DEBUG| Rx on 902300000, rssi: -61 snr: 58
9:12:53:4|DEBUG| Received frame: type: Join Request
9:12:53:4|INFO| Received join request
9:12:53:4|DEBUG| BUFFER: 00c0ffee00000000020163347338313832233c
9:12:53:5|DEBUG| App EUI: 02.00.00.00.00.ee.ff.c0
9:12:53:5|DEBUG| Dev EUI: 32.38.31.38.73.34.63.01
9:12:53:5|DEBUG| Nonce: 00003c23
9:12:53:6|DEBUG| MIC is valid
9:12:53:6|DEBUG| Got appkey: 2b.7e.15.16.28.ae.d2.a6.ab.f7.15.88.09.cf.4f.3c
9:12:53:7|DEBUG| DEV NONCE: 3c23
9:12:53:7|DEBUG| APP NONCE: 2f529e
9:12:53:7|DEBUG| session keys: 99e47e148873a6e32ceff9a3eccd2233 96f44cb0d5c2a3900aaf20e9ef8f931b
9:12:53:8|TRACE| SQL query = SELECT address FROM nodes WHERE deveui = "3238313873346301"
9:12:53:9|INFO| Device found in DB, assigning address: 5
9:12:53:10|DEBUG| Update session keys
9:12:53:10|TRACE| SQL query = UPDATE nodes SET authenticationkey = "99e47e148873a6e32ceff9a3eccd2233", encryptionkey = "96f44cb0d5c2a3900aaf20e9ef8f931b" WHERE address = "00000005"
9:12:53:13|DEBUG| Set node active: 1
9:12:53:13|INFO| Queue join response 17 bytes
9:12:53:13|DEBUG| Set node active: 1
9:12:53:14|DEBUG| update bestGateway
9:12:53:14|DEBUG| Time: 3236312956
9:12:53:14|DEBUG| App Queue Length: 1
9:12:53:14|DEBUG| Rx Frame seq 0 snr 58
9:12:53:15|DEBUG| SpreadingFactorStore::Add
9:12:53:15|DEBUG| FindSF : snr : 58 100 -42
9:12:53:15|TRACE| SQL query = UPDATE nodes SET jointime = "2015-12-21T09:12:53Z" WHERE address = "00000005"
9:12:53:19|TRACE| SQL query = UPDATE packets SET port = 2, seqno = 0, gateway = "0080000000009f6c", time = "2015-12-21T09:12:53Z", microseconds = 308000, rssi = -61, channel = 0, lsnr_cB = 58, spread = 10, modulationbandwidth = 125, data = "0163347338313832233c" WHERE node = "00000005"
9:12:53:22|TRACE| SQL query = UPDATE nodes SET lastuppacketid = 1, lastmessagems = 35856598 WHERE address = "00000005"
9:12:53:25|TRACE| SQL query = UPDATE gateways SET lastuppacketid = 1 WHERE address = "0080000000009f6c"
9:12:53:28|DEBUG| getTimeOnAirMs dr: 10 bw: 2 pl: 8 sz: 16 toa: 82
9:12:53:28|INFO| Send Join Accept - EUI: 32:38:31:38:73:34:63:01 ADDR: 00000005
9:12:53:28|INFO| Schedule TX Time on air: 150 ms
9:12:53:36|DEBUG| Send MQTT message
9:12:53:37|DEBUG| UDP message: lora/32:38:31:38:73:34:63:01/joined
9:12:53:37|DEBUG| UDP port: 1784
9:12:53:39|TRACE| Published message: 6
9:12:53:446|TRACE| Parse downstream message 12 bytes
9:12:53:447|TRACE| Gateway 00:80:00:00:00:00:9f:6c seen IP address 127.0.0.1:33742
9:12:57:885|DEBUG| is frame ready?
9:12:57:886|DEBUG| App Queue Length: 1
9:12:57:888|DEBUG| BestGateway: 80000000009f6c
9:12:57:889|DEBUG| Start
9:12:57:891|INFO| Frame transmitted to 00:00:00:05 via GW (00:80:00:00:00:00:9f:6c Chan LC1 127.0.0.1:33742) Seq# 40
9:12:57:891|TRACE| SQL query = UPDATE nodes SET lastdownmsgseqno = 64 WHERE address = "00000005"
9:12:57:894|DEBUG| App Data Queue: 1 front size: 17 available: 242
9:12:57:894|DEBUG| check if front is join request 17 bytes
9:12:57:894|DEBUG| Start
9:12:57:895|TRACE| App Data Queue - Join Popped
9:12:57:895|DEBUG| Transmitted Frame data
================================
000 20 68 6f ed 76 ea 07 12
008 bd 79 15 dc 99 53 b3 4c
010 cf

9:12:57:896|DEBUG| rx1Offset: 0 rx1Datarate: 10
9:12:57:896|DEBUG| Use JoinResponse Window Time
9:12:57:898|DEBUG| JSON tx: {
"txpk" : {
  "codr" : "4/5",
  "data" : "IGhv7XbqBxK9eRXcmVOzTM8",
  "datr" : "SF10BW500",
  "freq" : 923.29999999999995,
  "ipol" : true,
  "modu" : "LORA",
  "ncrc" : false,
  "powe" : 26,
  "rfch" : 0,
  "size" : 17,
  "tmst" : 3241312956
}
}

and….I can confirm that RM7201 is also operational and registered with my LoRa Gateway.

Again, I have some reservations due to luck of any usable sample code from Dapu as well as a single hardware design for all regions.

You, should also confirm if all necessary approvals are actually available for your region.

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…

LoRa Hybrid Mode and FCC regulations

As indicated in my previous post, LoRa implementation in North America presents itself with several challenges imposed by FCC regulations. However, hybrid mode deployed by Multitech and Kerlink and probably also by Link Labs provide clever solution to this problem:
As per Semtech: There is an FCC OET publication [5] that details a possible hybrid mode scenario:

It is possible for a device to be designed to operate as a DTS, as a FHSS system, or using a combination of these two modulation types.
A hybrid system uses both digital modulation and frequency hopping techniques at the same time on the same carrier. As shown in Section 15.247(f), a hybrid system must comply with the power density standard of 8 dBm in any 3 kHz band when the frequency hopping function is turned off. The transmission also must comply with a 0.4 second / channel maximum dwell time when the hopping function is turned on. There is no requirement for this type of hybrid system to comply with the 500 kHz minimum bandwidth normally associated with a DTS transmission; and, there is no minimum number of hopping channels associated with this type of hybrid system.
As a possible application scenario, consider a system operating with eight 200 kHz channels.
To comply with the requirements for hybrid operation the channel dwell time in frequency hopping mode must not exceed 400 ms in any (400 ms * 8 channels) 3.2 seconds. In addition, the power spectral density shall not exceed +8 dBm in any 3 kHz bandwidth.

It is a good alternative and perhaps, soon we will see plenty of choices for LoRa gateways operating within North American spectrum. The power needs to be limited and capacity is also limited, but still it is an inexpensive way to deploy LoRa network in North America.