My Cart

Extreme Range Links: LoRa 868 / 900MHz SX1272 LoRa module for Arduino Waspmote and Raspberry Pi

 

Difficulty Level: Intermediate -


LoRa is a new, private and spread-spectrum modulation technique which allows sending data at extremely low data-rates to extremely long ranges. The low data-rate (down to few bytes per second) and LoRa modulation lead to very low receiver sensitivity (down to -134 dBm), which combined to an output power of +14 dBm means extremely large link budgets: up to 148 dB., what means more than 22km (13.6 miles) in LOS links and up to 2km (1.2miles) in NLOS links in urban environment (going through buildings).

Libelium's LoRa module works in both 868 and 900 MHz ISM bands, which makes it suitable for virtually any country. Those frequency bands are lower than the popular 2.4 GHz band, so path loss attenuation is better in LoRa. In addition, 868 and 900 MHz are bands with much fewer interference than the highly populated 2.4 GHz band. Besides, these low frequencies provide great penetration in possible materials (brick walls, trees, concrete), so these bands get less loss in the presence of obstacles than higher bands.

The great performance of LoRa in all these 3 features (good sensitivity, low path loss, good obstacle penetration) makes LoRa a disruptive technology enabling really long range links. This is specially important in urban scenarios, with very difficult transmission conditions. To sum up, LoRa can get long ranges in Smart Cities deployments, so it reduces dramatically the size of the backbone network (repeaters, gateways or concentrators).

As shown in the section 7, Libelium performed long range tests, getting the awesome distance of 22 km (13.6 miles) in LOS configurations and +2km (1.2 miles) in urban scenarios (going through buildings). The margin in those conditions would allow even more distance (x2, x3), the only problem was to keep the line-of-sight condition.

LoRa
Module SX1272
Dual Frequency Band 863-870 MHz (Europe)
902-928 MHz (US)
Transmission Power 25 mW
Sensitivity -134 dBm
Channels 8 (868MHz)
13 (900MHz)
Range LOS = 21km (13.4miles)
NLOS = +2km (1.2miles)

The SX1272 LoRa module has to be connected along with the Multiprotocol Radio Shield to your Arduino or Intel Galileo, enabling transmissions with another SX1272 LoRa module. This wireless communication module is also compatible with Raspberry Pi through the connection bridge. It works at 868 MHz and 900 MHz frequency band. Depending on the location of the radio link, the unlicensed band is one or the other.



LoRa VS LoRaWAN

Libelium currently offers two options of this type of radio technology: LoRa and LoRaWAN

  • LoRa contains only the link layer protocol and is perfect to be used in P2P communications between nodes. LoRa modules are a little cheaper that the LoRaWAN ones. It works in the 868 and 900MHz bands. Go to the LoRa Tutorial.
  • LoRaWAN includes the network layer too so it is possible to send the information to any Base Station already connected to a Cloud platform. LoRaWAN modules may work in the 868/900/433MHz bands. Go to the LoRaWAN Tutorial.

Market Ready Technology

Libelium offers two types of sensor platforms: OEM lines (Waspmote , Arduino, Raspberry Pi) and Plug & Sense!.

In accordance with the 1999/5/EC (R&TTE) and the EU Directive 2011/65/EU (RoHS2), Libelium Comunicaciones Distribuidas S.L. declares that the "Plug & Sense! LoRaWAN 868" device conforms to the following regulations:

  • EN 301 489-1(1.9.2)- (1.6.1)
  • EN 55022:2010
  • EN 60950-1: 2006
  • A11: 2009 + A1: 2010 + A12: 2011 + Ac: 2011 +A2: 2013

1. Features

The SX1272 LoRa module main advantage is the reach increasing but also the cost saving respect other similar modules like XBee 868 or XBee 900.The pack we are going to use in this tutorial includes the SX1272 LoRa module and the Multiprotocol Radio Shield. The Multiprotocol Radio Shield can be used to connect two modules in order to combine the existing cooking-hacks modules and make connections between platforms. The SX1272 LoRa module uses the SPI bus. The SPI port allows more speed communication and frees up the UART for other purposes like debugging or to connect communication modules.

NOTE:
  • It is important to remark that the SX1272 communications module is incompatible with eHealth, OpenGarden and OpenAquarium, since there are not available pins to multiplex the SPI port. With these platforms Cooking Hacks offers another kind of wireless technology.
  • Also it is important to notice that this library is pretty big, so be careful with the available memory if you invoke many libraries. For example, if you want to use the DF Robot SD or microSD offered by Cooking Hacks, the packet's length must be reduced due to the limited Arduino's RAM memory size.

2. LoRa VS XBee 868/900 MHz

Tests demonstrate that the LoRa module has much better long-range performance than any other communication module, including XBee 868 or 900. Dozens of km are easily achievable in good conditions thanks to the extremely low sensitivity that the disruptive LoRa technology offers. Even in urban environment, LoRa can reach some km in range. Both things are impossible for XBee.

However, XBee 868 or 900 win in terms of time of transmission. Basically, they complete a transmission cycle, including ACK reception, in less than 200 ms. The LoRa module takes more time (even in mode 10, which is the fastest mode).

Time of transmission is directly related to battery consumption, so XBees 868 and 900 need less energy to work (60-80% less than LoRa). In other words, a battery will live longer with XBee.

3. The board

3.1 SX1272 LoRa module

The SX1272 LoRa module uses the SPI pins for communication. The SPI port allows more speed communication. The Multiprotocol Radio Shield allows to connect two communication modules at the same time to Arduino or Intel Galileo. This means a lot of different combinations are possible using any of the radios available for Arduino or Intel Galileo.

NOTE:
  • The SX1272 LoRa module is provided with a 4.5 dBi antenna, which enables maximum range.

  • It is not recommended to work without an antenna screwed to the module. The module could be damaged due to RF reflections.

3.2 SX1272 LoRa module over Arduino

The Multiprotocol Radio Shield has two sockets. The SX1272 LoRa module must be connected as shown in the next figures. Please, see the Multiprotocol Radio Shield Tutorial for more information.

Get Arduino

Get the SX1272 LoRa module

Get the Multiprotocol Radio Shield

WARNING:
  • The SX1272 LoRa module must be connected in the corresponding socket as shown in this tutorial.
  • The SX1272 LoRa module is not compatible with the XBee shield. You have to use the Multiprotocol Radio Shield as shown in this tutorial.

3.3 SX1272 LoRa module over Raspberry Pi

Connect the SX1272 LoRa module to Raspberry Pi using the Raspberry Pi to Arduino shields connection bridge as shown in the pictures.

Get Raspberry Pi

Get the Raspberry Pi to Arduino shields connection bridge

Get the SX1272 LoRa module for Raspberry Pi

3.4 SX1272 LoRa module over Waspmote

Waspmote is an open source wireless sensor platform specially focused on the implementation of low consumption modes to allow the sensor nodes ("motes") to be completely autonomous and battery powered, offering a variable lifetime between 1 and 5 years depending on the duty cycle and the radio used. The platform counts with more than 100 sensors already integrated and ready to use.

Know more at:


Are Waspmote and Arduino platforms compatible?

Waspmote uses the same IDE (compiler and core libraries) than Arduino. For this reason the same code is compatible in both platforms just adjusting small things like the pinout and the I/O scheme. We love the fast learning curve of Arduino and for this reason we tried to make a platform compatible with it. The idea is an Arduino user may work with Waspmote in a transparent and easy way (as the source code will be the same the learning curve does not exists).

Then, are Waspmote and Arduino competence?

Definitely no. Arduino is a really nice platform to learn how to use electronics and intended to make cheap "home projects" while Waspmote is a device specially designed to create wireless sensor networks which need long lifetime and are meant to be deployed in a real scenario like a city.

I just want to "play" with Waspmote, isn't it cheaper using Arduino?

The answer is, what do you want to do exactly? Waspmote is a very compact board including all needed for creating wireless sensor networks: wireless communications, RTC clock to allow scheduling interruptions, uSD to store data from sensors, 3-axis accelerometer (very useful for detecting falling nodes and as a sensor by itself) and of course, a battery and solar socket with charger regulator for making the node completely autonomous. You can find below a chart comparing Arduino and Waspmote features according to Cooking Hacks prices, so you can see how much does it cost adding those features separately to Arduino. We just want you to get the most appropriate device for your project!

Is Waspmote open source?

Yes. All the source code libraries are released under the LGPL license so developers may choose if the programs they do are released as open source or not.

The Expansion Board allows the user to connect two communication modules at the same time in the Waspmote sensor platform. This means a lot of different combinations are possible using any of the wireless radios available for Waspmote: 802.15.4, ZigBee, DigiMesh, 868 MHz, 900 MHz, LoRa, LoRaWAN, Sigfox, Bluetooth Pro, Bluetooth Low Energy, RFID/NFC, WiFi, GPRS Pro, GPRS+GPS and 3G/GPRS. Besides, the following Industrial Protocols modules are available: RS-485/Modbus, RS-232 Serial/Modbus and CAN Bus.

Some of the possible combinations are:

  • LoRa – GPRS
  • 802.15.4 – Bluetooth
  • 868 MHz – RS-485
  • RS-232 – WiFi
  • DigiMesh – 3G/GPRS
  • RS-232 – RFID/NFC
  • WiFi – 3G/GPRS
  • CAN bus – Bluetooth
  • etc.
NOTE: GPRS Pro, GPRS+GPS and 3G/GPRS modules do not need the Expansion Board to be connected to Waspmote. They can be plugged directly in the SOCKET1.

In the next photo you can see the sockets available along with the UART assigned. On one hand, SOCKET0 allows the user to plug any kind of radio module through the UART0. On the other hand, SOCKET1 permits to connect a radio module through the UART1.

The SX1272 module can be used only in the socket 0. If the user wants to use a wireless radio, they must use the socket 1.

  • WARNING:
    • Avoid to use DIGITAL7 pin when working with Expansion Board. This pin is used for setting the XBee into sleep.
    • Avoid to use DIGITAL6 pin when working with Expansion Board. This pin is used as power supply for the Expansion Board.
    • Incompatibility with Sensor Boards:
      • - Gases Board: Incompatible with SOCKET3B and NO2 sensor.

        - Agriculture Board: Incompatible with Sensirion and the atmospheric pressure sensor.

        - Smart Metering Board: Incompatible with SOCKET2, SOCKET3, SOCKET4 and SOCKET5

        - Smart Cities Board: Incompatible with microphone and the CLK of the interruption shift register.

        - Events Board: Incompatible with interruption shift register.

Get Waspmote

Get the SX1272 LoRa module

4. The library

The SX1272 LoRa module counts with a C++ library that lets you manage the SX1272 LoRa module in a simple way. This library offers a simple-to-use open source system. In order to ensure the same code is compatible in both platforms (Arduino and Raspberry Pi) we use the ArduPi libraries which allows developers to use the same code. Detailed info can be found here:

4.1 Using the library with Arduino

The SX1272 LoRa module includes a high level library functions for an easy manage. Before start using this functions you should download the library. The next zip includes all the files needed in a folder.

Download the SX1272 Libraries for Arduino.

Libraries are often distributed as a ZIP file or folder. The name of the folder is the name of the library. Inside the folder will be the .cpp files, .h files and a examples folder.

To install the library, first quit the Arduino application. Then uncompress the ZIP file containing the library. For installing libraries, uncompress zip file. It should contain a folder called SX1272. Drag this folder into your libraries folder. Under Windows, it will likely be called "My Documents\Arduino\libraries". For Mac users, it will likely be called "Documents/Arduino/libraries". On Linux, it will be the "libraries" folder in your sketchbook.

The library won't work if you put the .cpp and .h files directly into the libraries folder or if they're tested in an extra folder. Restart the Arduino application. Make sure the new library appears in the Sketch->Import Library menu item of the software.

4.2 Using the library with Raspberry Pi

The SX1272 library for Raspberry Pi requires the ArduPi library and both libraries should be in the same path.

Download the SX1272 Libraries for Raspberry Pi.

wget http://www.cooking-hacks.com/media/cooking/images/documentation/tutorial_SX1272/arduPi-api_LoRa_v1_4.zip && unzip -u arduPi-api_LoRa_v1_4.zip && cd cooking/examples/LoRa && chmod +x cook.sh && cd ../../..  

Creating a program that uses the library is as simple as putting your code in this template where it says "your Arduino code here"

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272: 
#include "SX1272.h"

/*********************************************************
 *  IF YOUR ARDUINO CODE HAS OTHER FUNCTIONS APART FROM  *
 *  setup() AND loop() YOU MUST DECLARE THEM HERE        *
 * *******************************************************/

/**************************
 * YOUR ARDUINO CODE HERE *
 * ************************/

void setup()
{
}

void loop(void)
{    
}

int main (){
  setup();
  while(1){
    loop();
  }
  return (0);
}}
                

Follow the next steps to compile a sketch:

  • First, install ArduPi and SX1272 libraries.
    • ArduPi For Raspberry Pi:

      wget http://www.cooking-hacks.com/media/cooking/images/documentation/raspberry_arduino_shield/raspberrypi.zip && unzip raspberrypi.zip && cd cooking/arduPi && chmod +x install_arduPi && ./install_arduPi && rm install_arduPi && cd ../..
      

      ArduPi For Raspberry Pi 2:

      wget http://www.cooking-hacks.com/media/cooking/images/documentation/raspberry_arduino_shield/raspberrypi2.zip && unzip raspberrypi2.zip && cd cooking/arduPi && chmod +x install_arduPi && ./install_arduPi && rm install_arduPi && cd ../..
      		

      SX1272 Library:

      wget http://www.cooking-hacks.com/media/cooking/images/documentation/tutorial_SX1272/arduPi-api_LoRa_v1_4.zip && unzip -u arduPi-api_LoRa_v1_4.zip && cd cooking/examples/LoRa && chmod +x cook.sh && cd ../../..  
      
  • Go to examples:
    • cd cooking/examples/LoRa/ 
      
  • Compile the example:
    • ./cook.sh my_example.cpp 
      
  • Run the sketch:
    • ./my_example.cpp_exe 
      

The script "cook.sh" compiles everything in their folders and the link in the examples foldes with the "_exe" executable.

  • Help: ./cook.sh
  • Clean: ./cook.sh -clean (It deletes all the "*.o" files. This is only necessary if you make changes in the libraries)

4.3 Using the library with Waspmote

The files related to the SX1272 libraries are:

    WaspSX1272.h
    WaspSX1272.cpp

It is mandatory to include the SX1272 library when using this module. So the following line must be added at the beginning of the code:

    #include <WaspSX1272.h>

4.4 General SX1272 functions

The main functions are listed here:

Initialization and basic functions

ON();           //Opens the SPI and switches the SX1272 LoRa module ON.
OFF();          //Closes the SPI and switches the SX1272 LoRa module OFF.
readRegister();     //Reads the indicated internal register.
writeRegister();    //Writes the indicated internal register.
clearFlags();       //Clears the interruption flags.
            

Configuration functions

setLORA();      //Sets the module in LoRa transmission mode.
setMode();      //Sets the BW, CR and SF of the LoRa modulation.
setHeaderON();      //Sets the module in explicit header mode (header is sent).
setHeaderOFF();     //Sets the module in implicit header mode (header is not sent).
setCRC_ON();        //Sets the module with CRC on.
setCRC_OFF();       //Sets the module with CRC off.
setChannel();       //Sets the indicated frequency channel in the module.
setPower();     //Sets the signal power indicated in the module.
setPowerNum();      //Sets the signal power indicated in the module.
setPreambleLength();    //Sets the preamble length in the module.
setPacketLength();  //Sets the packet length in the module.
setNodeAddress();   //Sets the node address in the module.
setRetries();       //Sets the maximum number of retries.
setMaxCurrent();    //Limits the current supply of the internal power amplifier.
getTemp();      //Gets the temperature from the measurement block module.
getRegs();      //Gets the content of different registers.
            

Link information functions

getSNR();       //Gets the SNR value in LoRa mode.
getRSSI();      //Gets the current value of RSSI from the channel.
getRSSIpacket();    //Gets the RSSI of the last packet received in LoRa mode.
            

Sending and receiving functions

sendPacketTimeout();//Sends a packet to the specified destination before a timeout expires.
sendPacketMaxTimeout();//Same as previous function with maximum timeout.
sendPacketTimeoutACK();//Sends a packet to a destination before a timeout and wait for an ACK response.
sendPacketMaxTimeoutACK();//Same as previous function with maximum timeout.
sendPacketTimeoutACKRetries();//Sends a packet to a destination before a timeout, wait for an ACK response and retry to send the packet if ACK is lost.
sendPacketMaxTimeoutACKRetries();//Same as previous function with maximum timeout.
receivePacketTimeout();//Receives information before a timeout expires.     
receivePacketMAXTimeout();//Same as previous function with maximum timeout.
receivePacketTimeoutACK();//Receives information before a timeout expires and responds with ACK.
receivePacketMAXTimeoutACK();//Same as previous function with maximum timeout.
receiveAll();//Receives all the information on air with maximum timeout.
            
NOTE: More functions are included in the SX1272 library. For complete information and description of SX1272 functions view the library files.

5. Transmission Modes

The module has two different modulations, LoRa modulation, owned by Semtech, and standard FSK modulation. Libelium has decided to only use the LoRa modulation due to the range improvement it provides.

When setting the SX1272 module ON, the module is prepared to use LoRa mode.

About the operation states, it is not necessary to control them manually. It is done automatically by the library functions.

5.1 LoRa mode

The innovative LoRa mode is the most interesting included in this module. It is an advanced and private modulation that increases the range comparing to classic modulations. The LoRa long range mode provides ultra-long range spread spectrum communication and high interference immunity whilst minimizing current consumption. It combines digital spread spectrum, digital signal processing, and forward error correction coding to achieve unprecedented performance. LoRa also provides significant advantages in both blocking and selectivity over conventional modulation techniques.

LoRa has three configurable parameters: the bandwidth (BW), the coding rate (CR) and the spreading factor (SF). The combination of these values defines the transmission mode. It is possible to set a predefined mode or to set these three parameters manually.

There are ten predefined modes in the API, including the largest distance mode, the fastest mode, and eight other intermediate modes that Libelium has found interesting. All of them can be modified or deleted, and also it is possible to attach new modes in the appropriate function. The predefined modes and its properties are shown in the next table.

ModeBWCRSFSensitivity (dB)Comments
1 125 4/5 12 -134 max range, slow data rate
2 250 4/5 12 -131  
3 125 4/5 10 -129  
4 500 4/5 12 -128  
5 250 4/5 10 -126  
6 500 4/5 11 -125.5  
7 250 4/5 9 -123  
8 500 4/5 9 -120  
9 500 4/5 8 -117  
10 500 4/5 7 -114 min range, fast data rate, minimum battery impact

The library implements a special structure packet, reserving 5 bytes to concrete fields that ables several features. So the maximum payload in LoRa mode is 250 bytes.

6. Connecting devices

6.1 Sending and receiving data through SX1272 in LoRa mode

Materials:

1. Connect the Multiprotocol Radio Shield over the Arduino UNO and the SX1272 LoRa module as shown in the figure. Don't forget to plug the antennas, without them the module could not run properly.

2. The SX1272 LoRa module can send data between devices to create a communications network. Each node is able to send and receive messages and the identification of the node must be done in the code. The address of each node must be unique in the network and constrained to values between 1 and 255 (0 is the broadcast reserved address). Every message will include the direction of the device, all the devices will receive all messages and will keep in the ones to themselves, throwing out the other ones. To do that, it has been created a special structure packet which includes the destination address node, the source address node, the packet length, the packet number, the payload and the retry number, in that order.

To communicate nodes, the user must assign the node address value to each module besides configure the same channel and the same mode in all the network modules. The SX1272 LoRa module must be configured after power it ON. So the user has to do the next steps:

  • Power ON the modules.
  • Configure (at least) the channel, mode and address value in each board.
  • Establish the message or mesagges to send with the protocol chosen.

Only configuration code:

Arduino
Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"
#include <SPI.h>

int e;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  // Print a start message
  Serial.println(F("SX1272 module configuration in Arduino"));
  
  // Power ON the module
  e = sx1272.ON();
  Serial.print(F("Setting power ON: state "));
  Serial.println(e, DEC);
  
  // Set transmission mode and print the result
  e = sx1272.setMode(4);
  Serial.print(F("Setting Mode: state "));
  Serial.println(e, DEC);
  
  // Set header
  e = sx1272.setHeaderON();
  Serial.print(F("Setting Header ON: state "));
  Serial.println(e, DEC);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  Serial.print(F("Setting Channel: state "));
  Serial.println(e, DEC);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  Serial.print(F("Setting CRC ON: state "));
  Serial.println(e, DEC);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  Serial.print(F("Setting Power: state "));
  Serial.println(e, DEC);
  
  // Set the node address and print the result
  e = sx1272.setNodeAddress(3);
  Serial.print(F("Setting node address: state "));
  Serial.println(e, DEC);
  
  // Print a success message
  Serial.println(F("SX1272 successfully configured"));
}
  
void loop(void)
{
}
        
Raspberry Pi
Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"

int e;

void setup()
{
  // Print a start message
  printf("SX1272 module configuration in Raspberry Pi\n");
  
  // Power ON the module
  e = sx1272.ON();
  printf("Setting power ON: state %d\n", e);
  
  // Set transmission mode
  e = sx1272.setMode(4);
  printf("Setting Mode: state %d\n", e);
  
  // Set header
  e = sx1272.setHeaderON();
  printf("Setting Header ON: state %d\n", e);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  printf("Setting Channel: state %d\n", e);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  printf("Setting CRC ON: state %d\n", e);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  printf("Setting Power: state %d\n", e);
  
  // Set the node address
  e = sx1272.setNodeAddress(3);
  printf("Setting Node address: state %d\n", e);
  
  // Print a success message
  printf("SX1272 successfully configured\n");
  delay(1000);
}

void loop(void)
{    
}

int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}

        
Waspmote
Code:
	http://www.libelium.com/development/waspmote/examples/sx-01-configure-lora-parameters/

3. There are three protocols to send packets: without ACK, with ACK and with ACK and retries. The ACK is a short acknowledge message that confirms the packet reception at the receiver. The library implements the protocol automatically by indicating the correct function.

Transmission without ACK

The transmitter executes the function sendPacketTimeout() and the receiver executes the function receivePacketTimeout().

Arduino

Transmitter code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"
#include <SPI.h>

int e;

char message1 [] = "Packet 1, wanting to see if received packet is the same as sent packet";
char message2 [] = "Packet 2, broadcast test";

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  // Print a start message
  Serial.println(F("SX1272 module and Arduino: send packets without ACK"));
  
  // Power ON the module
  e = sx1272.ON();
  Serial.print(F("Setting power ON: state "));
  Serial.println(e, DEC);
  
  // Set transmission mode and print the result
  e = sx1272.setMode(4);
  Serial.print(F("Setting Mode: state "));
  Serial.println(e, DEC);
  
  // Set header
  e = sx1272.setHeaderON();
  Serial.print(F("Setting Header ON: state "));
  Serial.println(e, DEC);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  Serial.print(F("Setting Channel: state "));
  Serial.println(e, DEC);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  Serial.print(F("Setting CRC ON: state "));
  Serial.println(e, DEC);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  Serial.print(F("Setting Power: state "));
  Serial.println(e, DEC);
  
  // Set the node address and print the result
  e = sx1272.setNodeAddress(3);
  Serial.print(F("Setting node address: state "));
  Serial.println(e, DEC);
  
  // Print a success message
  Serial.println(F("SX1272 successfully configured"));
  Serial.println();
}

void loop(void)
{
  // Send message1 and print the result
  e = sx1272.sendPacketTimeout(8, message1);
  Serial.print(F("Packet sent, state "));
  Serial.println(e, DEC);

  delay(4000);  

  // Send message2 broadcast and print the result
  e = sx1272.sendPacketTimeout(0, message2);
  Serial.print(F("Packet sent, state "));
  Serial.println(e, DEC);

  delay(4000);  
}

        

Receiver code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */

// Include the SX1272 and SPI library:
#include "SX1272.h"
#include <SPI.h>

int e;
char my_packet[100];

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  // Print a start message
  Serial.println(F("SX1272 module and Arduino: receive packets without ACK"));

  // Power ON the module
  e = sx1272.ON();
  Serial.print(F("Setting power ON: state "));
  Serial.println(e, DEC);
  
  // Set transmission mode and print the result
  e = sx1272.setMode(4);
  Serial.print(F("Setting Mode: state "));
  Serial.println(e, DEC);
  
  // Set header
  e = sx1272.setHeaderON();
  Serial.print(F("Setting Header ON: state "));
  Serial.println(e, DEC);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  Serial.print(F("Setting Channel: state "));
  Serial.println(e, DEC);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  Serial.print(F("Setting CRC ON: state "));
  Serial.println(e, DEC);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  Serial.print(F("Setting Power: state "));
  Serial.println(e, DEC);
  
  // Set the node address and print the result
  e = sx1272.setNodeAddress(8);
  Serial.print(F("Setting node address: state "));
  Serial.println(e, DEC);
  
  // Print a success message
  Serial.println(F("SX1272 successfully configured"));
  Serial.println();
}

void loop(void)
{
  // Receive message
  e = sx1272.receivePacketTimeout(10000);
  if ( e == 0 )
  {
    Serial.print(F("Receive packet, state "));
    Serial.println(e, DEC);

    for (unsigned int i = 0; i < sx1272.packet_received.length; i++)
    {
      my_packet[i] = (char)sx1272.packet_received.data[i];
    }
    Serial.print(F("Message: "));
    Serial.println(my_packet);
  }
  else {
    Serial.print(F("Receive packet, state "));
    Serial.println(e, DEC);
  }
}
        
Raspberry Pi

Transmitter code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"

int e;

char message1 [] = "Packet 1, wanting to see if received packet is the same as sent packet";
char message2 [] = "Packet 2, broadcast test";

void setup()
{
  // Print a start message
  printf("SX1272 module and Raspberry Pi: send packets without ACK\n");
  
  // Power ON the module
  e = sx1272.ON();
  printf("Setting power ON: state %d\n", e);
  
  // Set transmission mode
  e = sx1272.setMode(4);
  printf("Setting Mode: state %d\n", e);
  
  // Set header
  e = sx1272.setHeaderON();
  printf("Setting Header ON: state %d\n", e);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  printf("Setting Channel: state %d\n", e);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  printf("Setting CRC ON: state %d\n", e);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  printf("Setting Power: state %d\n", e);
  
  // Set the node address
  e = sx1272.setNodeAddress(3);
  printf("Setting Node address: state %d\n", e);
  
  // Print a success message
  printf("SX1272 successfully configured\n\n");
  delay(1000);
}

void loop(void)
{
	// Send message1 and print the result
    e = sx1272.sendPacketTimeout(8, message1);
    printf("Packet sent, state %d\n",e);
    
    delay(4000);
 
 	// Send message2 broadcast and print the result
    e = sx1272.sendPacketTimeout(0, message2);
    printf("Packet sent, state %d\n",e);
    
    delay(4000);
}

int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}

        

Receiver code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"

int e;
char my_packet[100];

void setup()
{
  // Print a start message
  printf("SX1272 module and Raspberry Pi: receive packets without ACK\n");
  
  // Power ON the module
  e = sx1272.ON();
  printf("Setting power ON: state %d\n", e);
  
  // Set transmission mode
  e = sx1272.setMode(4);
  printf("Setting Mode: state %d\n", e);
  
  // Set header
  e = sx1272.setHeaderON();
  printf("Setting Header ON: state %d\n", e);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  printf("Setting Channel: state %d\n", e);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  printf("Setting CRC ON: state %d\n", e);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  printf("Setting Power: state %d\n", e);
  
  // Set the node address
  e = sx1272.setNodeAddress(8);
  printf("Setting Node address: state %d\n", e);
  
  // Print a success message
  printf("SX1272 successfully configured\n\n");
  delay(1000);
}

void loop(void)
{
  // Receive message
  e = sx1272.receivePacketTimeout(10000);
  if ( e == 0 )
  {
    printf("Receive packet, state %d\n",e);

    for (unsigned int i = 0; i < sx1272.packet_received.length; i++)
    {
      my_packet[i] = (char)sx1272.packet_received.data[i];
    }
    printf("Message: %s\n", my_packet);
  }
  else {
    printf("Receive packet, state %d\n",e);
  }
}

int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}

        
Waspmote

Transmitter code

Code:
	http://www.libelium.com/development/waspmote/examples/sx-02a-tx-lora/

Receiver code

Code:
	http://www.libelium.com/development/waspmote/examples/sx-02b-rx-lora/

Transmission with ACK

The transmitter executes the function sendPacketTimeoutACK() and the receiver executes the function receivePacketTimeoutACK().

Arduino

Transmitter code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"
#include <SPI.h>

int e;

char message1 [] = "Packet 1, wanting to see if received packet is the same as sent packet";
char message2 [] = "Packet 2, broadcast test";

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  // Print a start message
  Serial.println(F("SX1272 module and Arduino: send packets with ACK"));
  
  // Power ON the module
  e = sx1272.ON();
  Serial.print(F("Setting power ON: state "));
  Serial.println(e, DEC);
  
  // Set transmission mode and print the result
  e = sx1272.setMode(4);
  Serial.print(F("Setting Mode: state "));
  Serial.println(e, DEC);
  
  // Set header
  e = sx1272.setHeaderON();
  Serial.print(F("Setting Header ON: state "));
  Serial.println(e, DEC);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  Serial.print(F("Setting Channel: state "));
  Serial.println(e, DEC);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  Serial.print(F("Setting CRC ON: state "));
  Serial.println(e, DEC);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  Serial.print(F("Setting Power: state "));
  Serial.println(e, DEC);
  
  // Set the node address and print the result
  e = sx1272.setNodeAddress(3);
  Serial.print(F("Setting node address: state "));
  Serial.println(e, DEC);
  
  // Print a success message
  Serial.println(F("SX1272 successfully configured"));
  Serial.println();
}

void loop(void)
{
  // Send message1 and print the result
  e = sx1272.sendPacketTimeoutACK(8, message1);
  Serial.print(F("Packet sent, state "));
  Serial.println(e, DEC);

  delay(4000);  

  // Send message2 broadcast and print the result
  e = sx1272.sendPacketTimeoutACK(0, message2);
  Serial.print(F("Packet sent, state "));
  Serial.println(e, DEC);

  delay(4000);  
}

        

Receiver code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library:  
#include 
#include <SPI.h>

int e;
char my_packet[100];

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  // Print a start message
  Serial.println(F("SX1272 module and Arduino: receive packets with ACK"));
  
  // Power ON the module
  e = sx1272.ON();
  Serial.print(F("Setting power ON: state "));
  Serial.println(e, DEC);
  
  // Set transmission mode and print the result
  e = sx1272.setMode(4);
  Serial.print(F("Setting Mode: state "));
  Serial.println(e, DEC);
  
  // Set header
  e = sx1272.setHeaderON();
  Serial.print(F("Setting Header ON: state "));
  Serial.println(e, DEC);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  Serial.print(F("Setting Channel: state "));
  Serial.println(e, DEC);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  Serial.print(F("Setting CRC ON: state "));
  Serial.println(e, DEC);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  Serial.print(F("Setting Power: state "));
  Serial.println(e, DEC);
  
  // Set the node address and print the result
  e = sx1272.setNodeAddress(8);
  Serial.print(F("Setting node address: state "));
  Serial.println(e, DEC);
  
  // Print a success message
  Serial.println(F("SX1272 successfully configured"));
  Serial.println();
}

void loop(void)
{  
  // Receive message
  e = sx1272.receivePacketTimeoutACK(10000);
  if ( e == 0 )
  {
    Serial.print(F("Receive packet with ACK, state "));
    Serial.println(e, DEC);

    for (unsigned int i = 0; i < sx1272.packet_received.length; i++)
    {
      my_packet[i] = (char)sx1272.packet_received.data[i];
    }
    Serial.print(F("Message: "));
    Serial.println(my_packet);
  }
  else {
    Serial.print(F("Receive packet with ACK, state "));
    Serial.println(e, DEC);
  }
}

        
Raspberry Pi

Transmitter code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"

int e;

char message1 [] = "Packet 1, wanting to see if received packet is the same as sent packet";
char message2 [] = "Packet 2, broadcast test";

void setup()
{
  // Print a start message
  printf("SX1272 module and Raspberry Pi: send packets with ACK\n");
  
  // Power ON the module
  e = sx1272.ON();
  printf("Setting power ON: state %d\n", e);
  
  // Set transmission mode
  e = sx1272.setMode(4);
  printf("Setting Mode: state %d\n", e);
  
  // Set header
  e = sx1272.setHeaderON();
  printf("Setting Header ON: state %d\n", e);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  printf("Setting Channel: state %d\n", e);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  printf("Setting CRC ON: state %d\n", e);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  printf("Setting Power: state %d\n", e);
  
  // Set the node address
  e = sx1272.setNodeAddress(3);
  printf("Setting Node address: state %d\n", e);
  
  // Print a success message
  printf("SX1272 successfully configured\n\n");
  delay(1000);
}

void loop(void)
{
	// Send message1 and print the result
    e = sx1272.sendPacketTimeoutACK(8, message1);
    printf("Packet sent, state %d\n",e);
    
    delay(4000);
 
 	// Send message2 broadcast and print the result
    e = sx1272.sendPacketTimeoutACK(0, message2);
    printf("Packet sent, state %d\n",e);
    
    delay(4000);
}

int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}
 

Receiver code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"

int e;
char my_packet[100];

void setup()
{
  // Print a start message
  printf("SX1272 module and Raspberry Pi: receive packets with ACK\n");
  
  // Power ON the module
  e = sx1272.ON();
  printf("Setting power ON: state %d\n", e);
  
  // Set transmission mode
  e = sx1272.setMode(4);
  printf("Setting Mode: state %d\n", e);
  
  // Set header
  e = sx1272.setHeaderON();
  printf("Setting Header ON: state %d\n", e);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  printf("Setting Channel: state %d\n", e);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  printf("Setting CRC ON: state %d\n", e);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  printf("Setting Power: state %d\n", e);
  
  // Set the node address
  e = sx1272.setNodeAddress(8);
  printf("Setting Node address: state %d\n", e);
  
  // Print a success message
  printf("SX1272 successfully configured\n\n");
  delay(1000);
}

void loop(void)
{
  // Receive message
  e = sx1272.receivePacketTimeoutACK(10000);
  if ( e == 0 )
  {
    printf("Receive packet with ACK, state %d\n",e);

    for (unsigned int i = 0; i < sx1272.packet_received.length; i++)
    {
      my_packet[i] = (char)sx1272.packet_received.data[i];
    }
    printf("Message: %s\n", my_packet);
  }
  else {
    printf("Receive packet with ACK, state %d\n",e);
  }
}

int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}

        
Waspmote

Transmitter code

Code:
	http://www.libelium.com/development/waspmote/examples/sx-03a-tx-lora-ack/

Receiver code

Code:
	http://www.libelium.com/development/waspmote/examples/sx-03b-rx-lora-ack/

Transmission with ACK and retries

The transmitter executes the function sendPacketTimeoutACKRetries() and the receiver executes the function receivePacketTimeoutACK().

Arduino

Transmitter code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library:  
#include "SX1272.h"
#include <SPI.h>

int e;

char message1 [] = "Packet 1, wanting to see if received packet is the same as sent packet";
char message2 [] = "Packet 2, broadcast test";

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  // Print a start message
  Serial.println(F("SX1272 module and Arduino: send packets with ACK and retries"));
  
  // Power ON the module
  e = sx1272.ON();
  Serial.print(F("Setting power ON: state "));
  Serial.println(e, DEC);
  
  // Set transmission mode and print the result
  e = sx1272.setMode(4);
  Serial.print(F("Setting Mode: state "));
  Serial.println(e, DEC);
  
  // Set header
  e = sx1272.setHeaderON();
  Serial.print(F("Setting Header ON: state "));
  Serial.println(e, DEC);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  Serial.print(F("Setting Channel: state "));
  Serial.println(e, DEC);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  Serial.print(F("Setting CRC ON: state "));
  Serial.println(e, DEC);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  Serial.print(F("Setting Power: state "));
  Serial.println(e, DEC);
  
  // Set the node address and print the result
  e = sx1272.setNodeAddress(3);
  Serial.print(F("Setting node address: state "));
  Serial.println(e, DEC);
  
  // Print a success message
  Serial.println(F("SX1272 successfully configured"));
  Serial.println();
}

void loop(void)
{
  // Send message1 and print the result
  e = sx1272.sendPacketTimeoutACKRetries(8, message1);
  Serial.print(F("Packet sent, state "));
  Serial.println(e, DEC);

  delay(4000);  

  // Send message2 broadcast and print the result
  e = sx1272.sendPacketTimeoutACKRetries(0, message2);
  Serial.print(F("Packet sent, state "));
  Serial.println(e, DEC);

  delay(4000);  
}

        

Receiver code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"
#include <SPI.h>

int e;
char my_packet[100];

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  // Print a start message
  Serial.println(F("SX1272 module and Arduino: receive packets with ACK and retries"));
  
  // Power ON the module
  e = sx1272.ON();
  Serial.print(F("Setting power ON: state "));
  Serial.println(e, DEC);
  
  // Set transmission mode and print the result
  e = sx1272.setMode(4);
  Serial.print(F("Setting Mode: state "));
  Serial.println(e, DEC);
  
  // Set header
  e = sx1272.setHeaderON();
  Serial.print(F("Setting Header ON: state "));
  Serial.println(e, DEC);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  Serial.print(F("Setting Channel: state "));
  Serial.println(e, DEC);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  Serial.print(F("Setting CRC ON: state "));
  Serial.println(e, DEC);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  Serial.print(F("Setting Power: state "));
  Serial.println(e, DEC);
  
  // Set the node address and print the result
  e = sx1272.setNodeAddress(8);
  Serial.print(F("Setting node address: state "));
  Serial.println(e, DEC);
  
  // Print a success message
  Serial.println(F("SX1272 successfully configured"));
  Serial.println();
}

void loop(void)
{
  // Receive message
  e = sx1272.receivePacketTimeoutACK(10000);
  if ( e == 0 )
  {
    Serial.print(F("Receive packet with ACK and retries, state "));
    Serial.println(e, DEC);

    for (unsigned int i = 0; i < sx1272.packet_received.length; i++)
    {
      my_packet[i] = (char)sx1272.packet_received.data[i];
    }
    Serial.print(F("Message: "));
    Serial.println(my_packet);
  }
  else {
    Serial.print(F("Receive packet with ACK and retries, state "));
    Serial.println(e, DEC);
  }
}

        
Raspberry Pi

Transmitter code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"

int e;

char message1 [] = "Packet 1, wanting to see if received packet is the same as sent packet";
char message2 [] = "Packet 2, broadcast test";

void setup()
{
  // Print a start message
  printf("SX1272 module and Raspberry Pi: send packets with ACK and retries\n");
  
  // Power ON the module
  e = sx1272.ON();
  printf("Setting power ON: state %d\n", e);
  
  // Set transmission mode
  e = sx1272.setMode(4);
  printf("Setting Mode: state %d\n", e);
  
  // Set header
  e = sx1272.setHeaderON();
  printf("Setting Header ON: state %d\n", e);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  printf("Setting Channel: state %d\n", e);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  printf("Setting CRC ON: state %d\n", e);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  printf("Setting Power: state %d\n", e);
  
  // Set the node address
  e = sx1272.setNodeAddress(3);
  printf("Setting Node address: state %d\n", e);
  
  // Print a success message
  printf("SX1272 successfully configured\n\n");
  delay(1000);
}

void loop(void)
{
    // Send message1 and print the result
    e = sx1272.sendPacketTimeoutACKRetries(8, message1);
    printf("Packet sent, state %d\n",e);
    
    delay(4000);
 
 	// Send message2 broadcast and print the result
    e = sx1272.sendPacketTimeoutACKRetries(0, message2);
    printf("Packet sent, state %d\n",e);
    
    delay(4000);
}

int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}

        

Receiver code

Code:
/*  
 *  LoRa 868 / 915MHz SX1272 LoRa module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.1
 *  Design:            David Gascón 
 *  Implementation:    Covadonga Albiñana & Victor Boria
 */
 
// Include the SX1272 and SPI library: 
#include "SX1272.h"

int e;
char my_packet[100];

void setup()
{
  // Print a start message
  printf("SX1272 module and Raspberry Pi: receive packets with ACK and retries\n");
  
  // Power ON the module
  e = sx1272.ON();
  printf("Setting power ON: state %d\n", e);
  
  // Set transmission mode
  e = sx1272.setMode(4);
  printf("Setting Mode: state %d\n", e);
  
  // Set header
  e = sx1272.setHeaderON();
  printf("Setting Header ON: state %d\n", e);
  
  // Select frequency channel
  e = sx1272.setChannel(CH_10_868);
  printf("Setting Channel: state %d\n", e);
  
  // Set CRC
  e = sx1272.setCRC_ON();
  printf("Setting CRC ON: state %d\n", e);
  
  // Select output power (Max, High or Low)
  e = sx1272.setPower('H');
  printf("Setting Power: state %d\n", e);
  
  // Set the node address
  e = sx1272.setNodeAddress(8);
  printf("Setting Node address: state %d\n", e);
  
  // Print a success message
  printf("SX1272 successfully configured\n\n");
  delay(1000);
}

void loop(void)
{
  // Receive message
  e = sx1272.receivePacketTimeoutACK(10000);
  if ( e == 0 )
  {
    printf("Receive packet with ACK and retries, state %d\n",e);

    for (unsigned int i = 0; i < sx1272.packet_received.length; i++)
    {
      my_packet[i] = (char)sx1272.packet_received.data[i];
    }
    printf("Message: %s\n", my_packet);
  }
  else {
    printf("Receive packet with ACK and retries, state %d\n",e);
  }
}

int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}
        
Waspmote

Transmitter code

Code:
	http://www.libelium.com/development/waspmote/examples/sx-04a-tx-lora-ackwretries/

Receiver code

Code:
	http://www.libelium.com/development/waspmote/examples/sx-04b-rx-lora-ackwretries/

6.2 Power gain and sensibility

When configuring a node and a network, one important parameter is related with power gain and sensibility.

Power level

Power level (dBm) at which the module transmits conducted power.

Its possible values are:

ParameterSX1272 power level
'L' 0 dBm
'H' 7 dBm
'M' 14 dBm

It is also possible to set the conducted power indicating the quantity as a parameter in the function setPower.

RSSI of one packet and RSSI of the channel

It reports the Received Signal Strength of the last received packet and the current value of the Received Signal Strength in the selected channel. The RSSI of the packet is the meaningful one: if its value is greater than the sensitivity the packet sent is going to be successfully detected, otherwise the packet will be lost. The RSSI of the channel reports the signal level detected in every moment, even if it is not signal being transmitted, so it provides also noise level information. In the case the user develops a multi-hop network, this parameters only indicate the signal strength of the last hop, so it does not provide an accurate quality measurement of a multihop link.

SNR

It reports the Signal-to-Noise Ratio of the last received packet. The SX1272 LoRa module is capable to demodulate received signals with SNR values as low as -20 dB. Getting the SNR, it is possible to have an idea about the link's quality or health, and thus the additional distance we could get in a communication link.

7. Long Range Tests

7.1 Line of Sight test

The Line of Sight (LOS) tests were taken between two different points next to the surrounding area of Zaragoza (Spain). The emitter was set in the point A : viewpoint of 'La Plana de Cadrete'. The receiver was set in the point B: viewpoint of the village of Alfocea. These points are 21.6 km (13.4 miles) apart.

The following picture represents the profile of the link. The blue line indicates the line of sight conditions taken in the test. Besides, the purple ellipse indicates the Fresnel zone clearance achieved in this path.

Test features:

  • Several LoRa modes, frequency channels and output-power modes were tested in order to know the performance of the SX1272 LoRa module depending on great distances.
  • All packets were set to a fixed 90-byte payload.
  • More than one hundred attempts were performed in every trial.

Results:

LoRa ModeRangePowerChannelSuccess (%)Mean SNR (dB)Mean RSSI (dBm)Mean RSSI packet (dBm)Sensitivity (dB)Margin (dB)
Mode 1 21.6 km (13.4 miles) High CH_12_868 100 -9.79 -113.72 -126.79 -134 7.21
Max 100 -4.33 -113.76 -121.76 -134 12.24
High CH_16_868 100 -10.06 -114.28 -127.06 -134 6.94
Max 100 -3.20 -113.97 -120.21 -134 13.79
Mode 3 21.6 km (13.4 miles) High CH_12_868 95 -10.29 -114.16 -127.29 -129 1.71
Max 95 -3.73 -114.08 -120.73 -129 8.27
Mode 6 21.6 km (13.4 miles) High CH_12_868 99 -14.77 -107.22 -125.77 -125.5 -0.27
Max 100 -8.42 -106.60 -119.43 -125.5 6.07
Mode 9 21.6 km (13.4 miles) High CH_12_868 0 - - - -117 -
Max 49 -9.95 -107.68 -120.95 -117 -3.95

7.2 Non Line of Sight tests

Tests in Zaragoza

The Non Line of Sight (NLOS) tests were taken between several points in the surrounding areas of the Libelium's headquarters in Zaragoza (Spain).

The receiver is a Meshlium device, installed on the roof of the Libelium's headquarters. The emitter was set in several points in order to know the performance of this module in NLOS conditions within a city area.

Test features:

  • Lora Mode 1: maximum range.
  • Maximum output power: 14dBm.
  • Frequency channel: CH_12_868 in the 868mHz band.
  • Packets were set to a Waspmote Frame reaching around a 80-byte payload.
  • Fifty attempts were performed for every point.

Results:

PointRange (m)Number of Buildings (signal going through)Success (%)Mean SNR (dB)Mean RSSI (dBm)Mean RSSI packet (dBm)Margin (dB)
Point 1 830 4 96 -7.89 -112.95 -124.89 9.11
Point 2 960 14 92 -14.26 -111.26 -131.26 2.74
Point 3 1070 6 98 -3.22 -114.14 -120.24 13.76
Point 4 1530 14 98 -13.16 -112.24 -130.16 3.84
Point 5 863 6 100 -3.42 -113.48 -120.42 13.58

Paths description:

  • Point 1: The signal goes through four buildings. Three high-rise housing buildings and a low building do not permit to have line of sight in this path. Then, an open space is found in the way to the receiver.
  • Point 2: The signal goes through fourteen buildings. In this case, a large group of low residential houses are close to the point 2. Also, a residential block is found in the way to the receiver.
  • Point 3: The signal goes through six buildings. This point is placed at the side of a big square of the neighborhood. The path finds out a big residential building and after this, some industrial buildings too.
  • Point 4: The signal goes through fourteen buildings. This is the largest path. This point comes across four high residential buildings. Then there is an open space with no obstacles before reaching another group of high housing buildings again. Finally, several industrial buildings are found before ending the path to the receiver.
  • Point 5: The signal goes through six buildings. This point is separated from the receiver by several industrial buildings with no open spaces between them.

Tests in Paris

These tests were developed in an office area into Paris city. The transmitter is outside the first floor of an office building, at a height of about 3 meters. The receiver is at street except in one of them that is situated bellow ground floor, in a garage. There is no line of sight between the points.

8. LoRa VS LoRaWAN

Libelium currently offers two options of this type of radio technology: LoRa and LoRaWAN

  • LoRa contains only the link layer protocol and is perfect to be used in P2P communications between nodes. LoRa modules are a little cheaper that the LoRaWAN ones. It works in the 868 and 900MHz bands. Go to the LoRa Tutorial.
  • LoRaWAN includes the network layer too so it is possible to send the information to any Base Station already connected to a Cloud platform. LoRaWAN modules may work in the 868/900/433MHz bands. Go to the LoRaWAN Tutorial.

9. FAQ

9.1 For what applications is LoRa a good option?

LoRa is a very good choice for solar or mains-powered nodes transmitting every 10 or 15 minutes in networks with low or medium number of nodes.

LoRa is also the best option for very wide networks, with long-range links. Other communication modules just cannot get more than few km.

9.2 For what applications is NOT LoRa a good option?

Definitely, LoRa is not suitable for projects which require high data-rate and/or very frequent transmissions (e.g., each 10 seconds).

Also, LoRa is probably not suitable for highly populated networks. Anyway, it depends on the number of nodes, and on the number of packets per hour that each node sends.

Power consumption is a major challenge, so probably any LoRa node should be powered by a solar panel, or even better, connected to mains electricity. Last, we must note that due to the low bandwidth LoRa by itself does not support Over the Air Programming (OTA), however many of our clients use as a second radio the 3G, GPRS or WiFi modules that allow to perform OTA easily retrieving the binary image from a FTP server in just a couple of seconds.

10. Certifications

CE

Libelium offers two types of sensor platforms: OEM lines (Waspmote , Arduino, Raspberry Pi) and Plug & Sense!.

    • OEM lines like Waspmote , Arduino and Raspberry Pi are intended to be used for research purposes or as part of a major product so it needs final certification on the client side. More info at:

http://www.libelium.com/products/waspmote/

    • Plug & Sense! is the line ready to be used out of the box. It includes market certifications. See below the specific list of regulations passed.

http://www.libelium.com/products/plug-sense/

In accordance with the 1999/5/EC (R&TTE) and the EU Directive 2011/65/EU (RoHS2), Libelium Comunicaciones Distribuidas S.L. declares that the "Plug & Sense! LoRa 868" device conforms to the following regulations:

  • EN 301 489-1(1.9.2)- (1.6.1)
  • EN 55022:2010
  • EN 60950-1: 2006
  • A11: 2009 + A1: 2010 + A12: 2011 + Ac: 2011 +A2: 2013.

If desired, the Declaration of Conformity document can be requested using the Contact section at:

http://www.libelium.com/contact

FCC

Libelium is currently certifying the model "Plug & Sense! LoRaWAN 900 / 915" for US. Specifically under the Part 15 Spread Spectrum Transmitter (FCC Rule Part 15 C).

Complete process will be finished by 2016. If you want to know more contact the Libelium Sales Department.

IC

Libelium is currently certifying the model "Plug & Sense! LoRaWAN 900 / 915" for Canada. Specifically under the Industry Canada Regulation (IC) - (RSS-210).

Complete process will be finished by 2016. If you want to know more contact the Libelium Sales Department.

Device Compatibility

This shield is tested and fully compatible with the following boards:

Arduino Boards

  • Arduino Uno

Raspberry Pi Boards

  • Raspberry Pi
  • Raspberry Pi (Model B+)
  • Raspberry Pi 2
  • Raspberry Pi 3

12. Get the shields and kits

Kits

SX1272 LoRa module

Multiprotocol Radio Shield





If you are interested in Internet of Things (IoT) or M2M projects check our open source sensor platform Waspmote which counts with more than 100 sensors available to use 'off the shelf', a complete API with hundreds of ready to use codes and a low consumption mode of just 0.7µA to ensure years of battery life.

Know more at:

Get the Starter Kits at: