The Arduino MKR WAN 1310 is an excellent entry point to get started with low-powered, wide-area networks (LPWAN). In this tutorial, we will go through some of the core concepts such as long range (LoRa®) and the LoRaWAN® protocol.
We will create a basic sketch that will allow communication between two MKR WAN 1310 boards. The communication will be established firstly through the radio module on the board, where we will also attach an antenna to each board.
There are many different terms to be familiar with in the world of LoRa® technology, so let's go through some of them!
LoRa® is short for long range modulation technique based on a technology called chirp spread spectrum (CSS). It is designed to carry out long-range transmissions with minimal power consumption. LoRa® defines as the "lower layer" or "physical layer", according to the OSI model. The physical layer is defined by hardware, signals and frequencies.
LoRa® uses different radio frequencies depending on where you are located in the world. The most common are Europe (868 MHz) and North America & Australia (915 MHz), but it differs from country to country. You can also read more about a country's unique radio frequency.
LoRa® is also often used to describe hardware devices supported by LoRa®, e.g. modules or gateways. The Arduino MKR WAN 1310 has a LoRa® module called Murata CMWX1ZZABZ.
LoRaWAN® can be defined as the networking protocol used in an Low-Power, Wide-Area networks (LPWAN). The architecture of the network consists of different gateways that relay messages from low-power devices over long ranges, to central network servers. The protocol is defined as the upper networking layers.
There are three distinct benefits of using LoRa® technology.
1. Price: LoRa® chips are quite inexpensive for its performance levels. The MKR WAN 1310 is one of the cheapest long-range connectivity boards produced. Also, operating under free licenses means, that's right, not paying for licenses!
2. Low power: Both hardware and software is designed to run on minimal energy, which boosts its value significantly. In present day and future, energy consumption is a large problem to tackle.
3. Long range: To transmit data over long distances brings more accessibility to more remote regions, and is ideal for agricultural, forestry and weather applications.
Follow the wiring diagram below to connect the antennas to the MKR WAN 1310 boards.
This is the schematic of our circuit.
We are going to create two sketches: one for the sender, and one for the receiver. In this tutorial, we will simply focus on sending a simple message that can be read in the Serial Monitor. The sender will have a counter that increases each time the loop has run, and a delay of 5 seconds. Each time the loop runs, we will send a "packet" containing the message "hello" and the number of the counter variable. This is to ensure that we receive messages continuously.
To create the sender sketch, we will have to do the following steps:
To create the receiver sketch, we will have to do the following steps:
We are going to program two separate MKR WAN 1310's in this tutorial. We will start with the sender device and later on, we will create a sketch for the receiver device.
1. First, let's make sure we have the drivers installed. If we are using the Web Editor, we do not need to install anything. If we are using an offline editor, we need to install it manually. This can be done by navigating to Tools > Board > Board Manager.... Here we need to look for the Arduino SAMD boards (32-bits ARM Cortex M0+) and install it.
2. Now we need to download the LoRa library from this repository, where you can install it by navigating to Sketch > Include Library > Add .ZIP Library... in the offline IDE.
The initialization is quick and easy: we will only include the SPI and LoRa libraries, and create a counter variable.
1#include <SPI.h>2#include <LoRa.h>3
4int counter = 0;
In the
setup()
we will first begin serial communication, where we will use the command while(!Serial);
to prevent the program from running until we open the Serial Monitor.We will then initialize the LoRa library, where we will set the radio frequency to 868E6, which is used in Europe for LoRa® communication. If we are located in North America, we need to change this to 915E6.
1void setup() {2 Serial.begin(9600);3 while (!Serial);4
5 Serial.println("LoRa Sender");6
7 if (!LoRa.begin(868E6)) {8 Serial.println("Starting LoRa failed!");9 while (1);10 }11}
In the
loop()
we start by printing "Sending packet" in the Serial Monitor + the value of counter
. We then begin a packet by using the command, LoRa.beginPacket()
, and print "hello" and the value of counter
. This is done using the LoRa.print()
function, then we broadcast it by using LoRa.endPacket()
. Finally, we add increase counter by 1 each time the loop has run, and a delay of 5 seconds, to limit the message rate.
1void loop() {2 Serial.print("Sending packet: ");3 Serial.println(counter);4
5 // send packet6 LoRa.beginPacket();7 LoRa.print("hello ");8 LoRa.print(counter);9 LoRa.endPacket();10
11 counter++;12
13 delay(5000);14}
The initialization and setup of the receiver is more or less identical to the sender sketch.
But inside the loop, we will not be creating any packets. Instead, we will listen to incoming ones. This is done by first using the command
int packetSize = LoRa.parsePacket();
, and then check for an incoming packet. If we receive one, it is parsed and printed in the Serial Monitor. 1#include <SPI.h>2#include <LoRa.h>3
4void setup() {5 Serial.begin(9600);6 while (!Serial);7
8 Serial.println("LoRa Receiver");9
10 if (!LoRa.begin(868E6)) {11 Serial.println("Starting LoRa failed!");12 while (1);13 }14}15
16void loop() {17 // try to parse packet18 int packetSize = LoRa.parsePacket();19 if (packetSize) {20 // received a packet21 Serial.print("Received packet '");22
23 // read packet24 while (LoRa.available()) {25 Serial.print((char)LoRa.read());26 }27
28 // print RSSI of packet29 Serial.print("' with RSSI ");30 Serial.println(LoRa.packetRssi());31 }32}
If you choose to skip the code building section, the complete code can be found below:
1#include <SPI.h>2#include <LoRa.h>3
4int counter = 0;5
6void setup() {7 Serial.begin(9600);8 while (!Serial);9
10 Serial.println("LoRa Sender");11
12 if (!LoRa.begin(868E6)) {13 Serial.println("Starting LoRa failed!");14 while (1);15 }16}17
18void loop() {19 Serial.print("Sending packet: ");20 Serial.println(counter);21
22 // send packet23 LoRa.beginPacket();24 LoRa.print("hello ");25 LoRa.print(counter);26 LoRa.endPacket();27
28 counter++;29
30 delay(5000);31}
1#include <SPI.h>2#include <LoRa.h>3
4void setup() {5 Serial.begin(9600);6 while (!Serial);7
8 Serial.println("LoRa Receiver");9
10 if (!LoRa.begin(868E6)) {11 Serial.println("Starting LoRa failed!");12 while (1);13 }14}15
16void loop() {17 // try to parse packet18 int packetSize = LoRa.parsePacket();19 if (packetSize) {20 // received a packet21 Serial.print("Received packet '");22
23 // read packet24 while (LoRa.available()) {25 Serial.print((char)LoRa.read());26 }27
28 // print RSSI of packet29 Serial.print("' with RSSI ");30 Serial.println(LoRa.packetRssi());31 }32}
Once we are finished with the coding, we can upload the sketches to the different boards. Remember that we need to upload the sender sketch to the sender board and the receiver sketch to the receiver board. This will require us to switch between the ports listed in the board manager.
When we open the Serial Monitor, we start the program. Let's start with the sender device. First, choose the port for your board, and open the Serial Monitor. The output should now be:
1LoRa Sender2Hello 03Hello 14Hello 25Hello 3
Now let's change ports to the receiver device, and open the Serial Monitor. We should now see the following:
1LoRa Receiver2Hello 03Hello 14Hello 25Hello 3
If we are receiving
If the code is not working, there are some common issues we might need to troubleshoot:
In this tutorial, we have introduced some fundamental concepts around LoRa®, where we have setup a basic communication line between two boards using the LoRa® network. With this basic framework, you can go on to combine this tutorial with sensors and other software libraries, so that you can create your own long-range, low-powered devices!