Links

Software

The Waspmote device communicates with the LoRaWAN module via UART. So different commands are sent from the microcontroller unit to the module so as to perform different tasks.

Waspmote libraries

Waspmote LoRaWAN files

The files related to the LoRaWAN libraries for these modules are:
  • WaspLoRaWAN.h
  • WaspLoRaWAN.cpp
It is mandatory to include the LoRaWAN library when using these modules. So the following line must be added at the beginning of the code:
#include <WaspLoRaWAN.h> or #include <WaspLoRaWAN_Global.h>
The include above will depend on the LoRaWAN module in use.

Class constructor

To start using the Waspmote LoRaWAN library, an object from the WaspLoRaWAN class must be created. This object, called LoRaWAN, is already created by default inside Waspmote LoRaWAN library. It will be usedthrough this guide to show how Waspmote works.
When using the class constructor, all variables are initialized to a default value.

API constants (common)

The API constants used in functions are:
Constant
Description
LORAWAN_ANSWER_OK
Successful response to a function
LORAWAN_ANSWER_ERROR
Erratic response to a function
LORAWAN_NO_ANSWER
No response to a function
LORAWAN_INIT_ERROR
Required keys to join to a network were not initialized
LORAWAN_LENGTH_ERROR
Data to be sent length limit exceeded
LORAWAN_SENDING_ERROR
Server did not response
LORAWAN_NOT_JOINED
Module has not joined a network
LORAWAN_INPUT_ERROR
Invalid input parameter
LORAWAN_VERSION_ERROR
The module does not support this function

API constants LoRaWAN

Constant
Description
RN2483_MODULE
LoRaWAN module plugged is LoRaWAN EU
RN2903_MODULE
LoRaWAN module plugged is LoRaWAN US
RN2903_IN_MODULE
LoRaWAN module plugged is LoRaWAN IN
RN2903_AS_MODULE
LoRaWAN module plugged is LoRaWAN ASIA-PAC / LATAM

API constants LoRaWAN Global

Constant
Description
AS923
LoRaWAN module is configured for AS923
AU915
LoRaWAN module is configured for AU915
EU868
LoRaWAN module is configured for EU868
KR920
LoRaWAN module is configured for KR920
IN865
LoRaWAN module is configured for IN865
US915
LoRaWAN module is configured for US915
SUB_BAND_0 to SUB_BAND_7
LoRaWAN subband for AU915 and US915 modules configuration

API variables

The variables used inside functions and Waspmote codes are:
Variable
Description
_buffer
The buffer of memory used for storing the responses from the module
_length
The useful length of the buffer
_def_delay
The time to wait after sending every command until listen for a response
_baudrate
The baudrate to be used when the module is switched on
_uart
The selected UART (regarding the socket used: SOCKET0 or SOCKET1)
_adr
The adaptive data rate state (on or off)
_ar
The automatic reply state (on or off)
_eui
The buffer used for storing the preprogrammed globally unique identifier from the module's hardware
_devEUI
The buffer used for storing the globally unique identifier for the module (software programmable)
_appEUI
The buffer used for storing the application identifier for the module
_nwkSKey
The buffer used for storing the network session key for the module
_appSKey
The buffer used for storing the application session key for the module
_appKey
The buffer used for storing the application key for the module
_devAddr
The buffer used for storing network device address for module
_band
The buffer used for storing the frequency band
_margin
The demodulation margin received in the last Link Check Answer frame
_gwNumber
The number of gateways successfully received the last Link Check Answer frame
_freq
The buffer used for storing the operating frequency for every channel
_radioFreq
The transceiver operating frequency
_radioFreqDev
The transceiver frequency deviation
_preambleLength
The preamble length for transceiver
_dCycle
The buffer used for storing the operating duty cycle for every channel
_drrMin
The minimum operating data rate range for every channel
_drrMax
The maximum operating data rate range for every channel
_dCyclePS
The duty cycle prescaler (which can only be configured by the server)
_crcStatus
The CRC status to determine if it is to be included during operation
_powerIndex
The output power to be used on LoRaWAN transmissions
_dataRate
The data rate to be used on LoRaWAN transmissions
_retries
The number of retransmissions for an uplink
_upCounter
The value of the uplink frame counter
_downCounter
The value of the downlink frame counter
_radioPower
The output power level used by the transceiver
_radioSF
The spreading factor to be used by the transceiver
_radioRxBW
The receiving bandwidth used by the transceiver
_radioCR
The coding rate used by the transceiver
_radioWDT
The time to be used by the transceiver watchdog timer
_radioBW
The value used for the transceiver bandwidth
_radioSNR
The SNR value for the last received packet by the transceiver
_radioMode
The buffer to save the operative radio mode
_radioBitRate
The operative radio bit rate
_supplyPower
The voltage level read by the module
_rx2DataRate
The second receiving window data rate
_rx2Frequency
The second receiving window frequency
_rx1Delay
The first receiving window delay
_macStatus
The MAC status register from the module
_status
The status of every LoRaWAN channel
_data
The buffer of memory used for storing data received from the back-end
_port
The port where data was received
_dataReceived
The flag used to inform if any data was received
_version
The version of the module plugged into Waspmote
_bandABZ
Band used for the LoRaWAN JP / KR type module

API functions

Through this guide there are lots of examples of using functions. In these examples, API functions are called to execute the commands, storing in their related variables the parameter value in each case. The functions are called using the predefined object LoRaWAN.
All public functions return one of these possible values:
  • LORAWAN_ANSWER_OK = 0
  • LORAWAN_ANSWER_ERROR = 1
  • LORAWAN_NO_ANSWER = 2
  • LORAWAN_INIT_ERROR = 3
  • LORAWAN_LENGTH_ERROR = 4
  • LORAWAN_SENDING_ERROR = 5
  • LORAWAN_NOT_JOINED = 6
  • LORAWAN_INPUT_ERROR = 7
  • LORAWAN_VERSION_ERROR = 8

Module system management features

Switch on

The ON() function allows to switch on the LoRaWAN module, it opens the MCU UART for communicating with the module and it automatically enters into command mode.
In addition, when the module has been powered and communication is opened, this function checks whethera module is plugged to the socket and which type of module has been plugged. This check is done within every function that reboots the module such as “ON”, “reset” or “factoryReset”.
After this step the module will be able to receive commands to configure it or send packets. It is necessary toindicate the socket that it is being used: SOCKET0 or SOCKET1.
Example of use for SOCKET0:
{
LoRaWAN.ON(SOCKET0);
}
Related variable:
LoRaWAN._version → Stores the module's version
Figure: LoRaWAN module in SOCKET0

Switch off

The OFF() function allows the user to switch off the LoRaWAN module and close the UART. This function must be called in order to keep battery level when the module is not going to be managed. It is necessary to indicate the socket that it is being used: SOCKET0 or SOCKET1.
Example of use for SOCKET0:
{
LoRaWAN.OFF(SOCKET0);
}

Module software reset

The reset() function allows the user to reset and restart the LoRaWAN module. The stored internal configurations will be loaded automatically upon reboot.
Example of use:
{
LoRaWAN.reset();
}
Related variable:
LoRaWAN._version → Stores the module's version

Module factory reset

The factoryReset() function allows the user to reset the module's configuration data and user EEPROM to factory default values and restart the module.
Example of use:
{
LoRaWAN.factoryReset();
}
Related variable:
LoRaWAN._version → Stores the module's version

Preprogrammed unique identifier (EUI)

The getEUI() function allows the user to query the preprogrammed EUI node address from the module. The preprogrammed EUI node address is a read-only value and cannot be changed or erased. It is a global unique 64-bit identifier.
Example of use:
{
LoRaWAN.getEUI();
}
Related variable:
LoRaWAN._eui → Stores the module's EUI

LoRaWAN parameters

Device EUI

The setDeviceEUI() function allows the user to set the 64-bit hexadecimal number representing the device EUI. There are two function prototypes which are explained below:
  • No input device EUI is specified, then the preprogrammed EUI is used as the device EUI.
  • A user-provided device EUI is specified as input.
The getDeviceEUI() function allows the user to query the device EUI which was previously set by the user. The attribute _devEUI permits to access to the settings of the module. The default value is 0000000000000000.
Depending on the network to join, it is needed to configure a random device EUI or a fixed device EUI provided by the back-end. This matter relies on the registering process for new devices in each back-end. For further information please go to “LoRaWAN back-ends” chapter.
Example for preprogrammed EUI:
{
LoRaWAN.setDeviceEUI();
LoRaWAN.getDeviceEUI();
}
Example for user-provided device EUI:
{
LoRaWAN.setDeviceEUI(0102030405060708);
LoRaWAN.getDeviceEUI();
}
Related variable:
LoRaWAN._devEUI → Stores the previously set device EUI

Device address

The setDeviceAddr() function allows the user to set the 32-bit hexadecimal number representing the device address. This address must be unique to the current network. There are two function prototypes which are explained below:
  • No input device address is specified, then the last 4 bytes of the preprogrammed EUI are set as device address.
  • A user-provided device address is specified as input.
The getDeviceAddr() function allows the user to query the device address which was previously set by the user. The attribute _devAddr permits to access to the settings of the module. The range goes from 00000000 to FFFFFFFF. The default value is 00000000.
Depending on the network to join, it is possible configure a random device address or a fixed device address.This matter depends on the back-end and the registering process for new devices. For further information please go to “LoRaWAN back-ends” chapter.
Example for using the preprogrammed EUI:
{
LoRaWAN.setDeviceAddr();
LoRaWAN.getDeviceAddr();
}
Example for user-provided device address:
{
LoRaWAN.setDeviceAddr(01020304);
LoRaWAN.getDeviceAddr();
}
Related variable:
LoRaWAN._devAddr → Stores the previously set device address

Application Session Key

The setAppSessionKey() function allows the user to set the 128-bit hexadecimal number representing the application session key.
All payloads are encrypted using an AES algorithm with a 128-bit secret key, the Application Session Key. Each end-device has its own unique Application Session Key only known by the end-device and the application server.
Figure: Use of application session key
The attribute _appSKeystores the application session key previously set by the user. The range goes from 00000000000000000000000000000000 to FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.
Example of use:
{
LoRaWAN.setAppSessionKey(00102030405060708090A0B0C0D0E0F”);
}
Related variable:
LoRaWAN._appSKey → Stores the previously set application session key

Network session key

The setNwkSessionKey() function allows the user to set the 128-bit hexadecimal number representing the network session key.
All frames contain a 32-bit cryptographic Message Integrity Check (MIC) signature computed using the AES algorithm with a 128-bit secret key, the Network Session Key. Each end-device has its own Network Session Key only known by the end-device and the network server.
Figure: Use of network session key
The attribute _nwkSKey stores the network session key previously set by the user. The range goes from 00000000000000000000000000000000 to FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.
Example of use:
{
LoRaWAN.setNwkSessionKey(00102030405060708090A0B0C0D0E0F”);
}
Related variable:
LoRaWAN._nwkSKey → Stores the previously set network session key

Application EUI

The setAppEUI() function allows the user to set the 64-bit hexadecimal number representing the application identifier. This parameters is a global application identifier that uniquely identifies the application provider (i.e., owner) of the module.
Example of use:
{
LoRaWAN.setAppEUI(1112131415161718);
}
Related variable:
LoRaWAN._appEUI → Stores the previously set application EUI

Application key

The setAppKey() function allows the user to set the 128-bit hexadecimal number representing the application key. Whenever an end-device joins a network via OTAA, the Application Key is used to derive thesession keys, Network Session Key and Application Session Key, which are specific for that end-device to encrypt and verify network communication and application data.
The attribute _appKeystores the application session key previously set by the user. The range goes from 00000000000000000000000000000000 to FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.
Example of use:
{
LoRaWAN.setAppKey(00102030405060708090A0B0C0D0E0F”);
}
Related variable:
LoRaWAN._appKey → Stores the previously set application key

LoRaWAN module activation

To participate in a LoRaWAN network, each module has to be personalized and activated.
Activation of a module can be achieved in two ways, either via Over-The-Air Activation (OTAA) when an end-device is deployed or reset, or via Activation By Personalization (ABP) in which the two steps of end-device personalization and activation are done as one step.

Over-The-Air Activation (OTAA)

For OTAA, modules must follow a join procedure prior to participating in data exchanges with the network server. A module has to go through a new join procedure every time it has lost the session context information.
The OTAA join procedure requires the module to be personalized with the following information before its starts the join procedure:
  • Device EUI (64-bit)
  • Application EUI (64-bit)
  • Application Key (128-bit)
After joining through OTAA, the module and the network exchanged the Network Session Key and the Application Session Key which are needed to perform communications.

Activation By Personalization (ABP)

Activating a module by ABP means that the device address and the two session keys are directly stored into the module instead of the Device EUI, Application EUI and the Application Key. The module is equipped with the required information for participating in a specific LoRa network when started.
Each module should have a unique set of Network Session Key and Application Session Key. Compromising the keys of one module shouldn‘t compromise the security of the communications of other devices. The process to build those keys should be such that the keys cannot be derived in any way from publicly available information.
The ABP join procedure requires the module to be personalized with the following information before its starts the join procedure:
  • Device address (32-bit)
  • Network Session Key (128-bit key) ensures security on network level
  • Application Session Key (128-bit key) ensures end-to-end security on application level

Join a network

Before sending packets to a gateway, the node must join a network first. The joinABP() function allows theuser to attempt joining the network using thNon-Globalon By Personalization mode (ABP). The joinOTAA()function allows the user to attempt joining the network using the Over the Air Activation mode (OTAA). Beforejoining the network, the specific parameters for activation should be configured depending on the joining procedure.
  • Join ABP
Before joining the network, the specific parameters for activation should be configured: device EUI, device address, network session key and application session key.
Example of use:
{
LoRaWAN.joinABP();
}
  • Join OTAA
Before joining the network, the specific parameters for activation should be configured: device EUI, application EUI and application key.
Example of use:
{
LoRaWAN.joinOTAA();
}
After joining via OTAA successfully, the module will be able to join the network in ABP mode in future joining procedures. The session keys are stored in module's memory, so it is possible to power down the module and restart it using ABP for joining the network with the previously stored keys.

LoRaWAN mode features

Operational ISM bands

Non Global modules

The resetMacConfig() function allows the user to reset the software LoRaWAN stack and initialize it with the parameters for the selected band: 433 MHz, 868 MHz or 900 MHz.
The getBand() function allows the user to query the current frequency band of operation. This function is not available for the LoRaWAN US and AU modules since they can only work in the 902-928 MHz ISM band for the US version and 915-928 MHz ISM band for the AU version. The attribute _band permits to access to the settings of the module. The default value is 868. This value can be saved into the module's memory with the saveConfig() function due to keep the band configuration after a reboot. Value can be either 433 or 868.
Example of use:
{
LoRaWAN.resetMacConfig(433);
LoRaWAN.getBand();
}
Related variable:
LoRaWAN._band → Stores the current frequency band of operation

LoRaWAN Global module

The setBand() function allows the user to configure the module for the selected band: AS923, AU915, EU868, KR920, IN865 or US915.
The getBand() function allows the user to query the current frequency band of operation. The attribute _band permits to access to the settings of the module. The default value is EU868.
Example of use:
{
LoRaWAN.setBand(AU915);
LoRaWAN.getBand();
}
Related variable:
LoRaWAN._band → Stores the current frequency band of operation
The setChannelMask() function allows the user to configure the sub-band in certain regions, such as AU915 and US915.
Example of use:
{
LoRaWAN.setChannelMask(SUB_BAND_0); // Configures channels from 0 to 7 and 64
}
The showChannelConfig() function allows the user to query the current channel frequency configuration. The channel configuration is printed through the serial port and it is available for all the band configurations.
Example of use:
{
LoRaWAN.showChannelConfig();
//Output
// Channel number 0 Frequency: 915200000 DRR Min: 0 DRR Max: 5
// Channel number 1 Frequency: 915400000 DRR Min: 0 DRR Max: l
// Channel number 2 Frequency: 915600000 DRR Min: 0 DRR Max: 5
// Channel number 3 Frequency: 915800000 DRR Min: 0 DRR Max: 5
// Channel number 4 Frequency: 916000000 DRR Min: 0 DRR Max: 5
// Channel number 5 Frequency: 916200000 DRR Min: 0 DRR Max: 5
// Channel number 6 Frequency: 916400000 DRR Min: 0 DRR Max: 5
// Channel number 7 Frequency: 916600000 DRR Min: 0 DRR Max: 5
// Channel number64 Frequency: 915900000 DRR Min: 6 DRR Max: 6
}

Send data to a LoRaWAN gateway

  • Sending unconfirmed packets
The sendUnconfirmed() function allows the user to transmit data on a specified port number. This function will not expect any acknowledgement back from the server. It is necessary to indicate the port to use. The range is from 1 to 223. The second input of the sending function is the payload of the packet to send. The payload must be specified in hexadecimal format as a string.
Example of use:
{
uint8_t port = 1;
char data[] =010203040506070809;
LoRaWAN.sendUnconfirmed( port, data);
}
There is a second sendUnconfirmed() function prototype which permits to send a packet defined as an array of bytes. So the function expects three inputs: port, pointer to the data and length of the data.
Example of use:
{
uint8_t port = 1;
uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
LoRaWAN.sendUnconfirmed( port, data, 6);
}
The length of the payload capable of being transmitted is dependent upon the set data rate. Please refer to the “Data rate” section for the payload length values.
Figure: Sending confirmed packets with ACK
The sendConfirmed() function allows the user to transmit data on a specified port number. This function will expect an acknowledgement from the server. If no ACK is received, the message will be retransmitted automatically up to a maximum of times specified by the setRetries() function. It is necessary to indicate the port to use. The range is from 1 to 223. The second input of the sending function is the payload of the packet to send. The payload must be specified in hexadecimal format as a string.
Example of use:
{
uint8_t port = 1;
char data[] =010203040506070809;
LoRaWAN.sendConfirmed( port, data);
}
The length of the payload capable of being transmitted is dependent upon the set data rate. Please refer to the “Data rate” section for the payload length values.

Receiving data from a LoRaWAN gateway

Note that not every back-end is able to send data to end devices. The back-ends which are able to perform data downlink use the ACK process to send a special ACK frame containing data. So once the user programs a downlink process, this downlink data will be received by the target module the next time it performs a transmission.
There is no specific function to receive data from back-ends in this library. The sendUnconfirmed() and the sendConfirmed() functions check if any special ACK is received and store data if any has been received. In case data has been received, _dataReceived flag will be set to true.
Related variables:
LoRaWAN._port → Stores the port used by the back-ends to send data LoRaWAN._data → Stores the received data LoRaWAN._dataReceived → Data received flag

Save configuration

The saveConfig() function allows the user to save LoRaWAN Class A protocol configuration parameters to the module’s non-volatile memory. This function must be issued after the configuration parameters have been appropriately set.
The LoRaWAN Class A protocol configuration savable parameters are:
  • Band
  • Uplink Frame Counter
  • Downlink Frame Counter
  • Data Rate
  • Adaptive Data Rate state
  • Device EUI
  • Application EUI
  • Application Key
  • Network Session Key
  • Application Session Key
  • Device Address
  • Second receiving window parameters
  • All Channel Parameter
    • Frequency
    • Duty Cycle
    • Data Rate Range
    • Status
There are some exceptions for the LoRaWAN US module, it does not save:
  • Band, since it does not use this parameter
  • Data rate
  • Channel frequency, preset according to specification
  • Duty cycle, since it does not use this parameter
Example of use:
{
LoRaWAN.saveConfig();
}
The macResume() function allows the user to enable LoRaWAN mode. After switching on the module it is not mandatory to call this function because the default mode upon reboot is LoRaWAN mode. However, if P2P mode was previously set and the user needs to switch back to LoRaWAN mode, then this function must be called. This function is not available for the LoRaWAN JP / KR module.
Example of use:
{
LoRaWAN.macResume();
}

Power level

The setPower() function allows the user to set the output power to be used on the next transmissions.
The getPower() function allows the user to query the device power index which was previously set by the user. The attribute _powerIndex permits to access to the settings of the module. The range goes from 0 to 5 for the 433 MHz frequency band and from 1 to 5 for the 868 MHz frequency band. LoRaWAN US and LoRaWAN AU power index values can be: 5, 7, 8, 9 or 10. LoRaWAN IN power index values go from 0 to 5. LoRaWAN ASIA-PAC / LATAM power index values go from 0 to 5. LoRaWAN JP / KR power index values go from 0 to 7.
Power Index
Power level(868 MHz)
Power level(433 MHz)
0
N / A
10 dBm
1
14 dBm
7 dBm
2
11 dBm
4 dBm
3
8 dBm
1 dBm
4
5 dBm
-2 dBm
5
2 dBm
-5 dBm
Table: Power levels table (LoRaWAN EU /433 module)
Power Index
Power level (900 MHz)
5
20 dBm
7
16 dBm
8
14 dBm
9
12 dBm
10
10 dBm
Table: Power levels table (LoRaWAN US and LoRaWAN AU modules)
Power Index
Power level (865-867 MHz)
0
MaxEIRP = 18.5 dBm
1
MaxEIRP – 2 dB
2
MaxEIRP – 4 dB
3
MaxEIRP – 6 dB
4
MaxEIRP – 8 dB
5
MaxEIRP – 10 dB
Table: Power levels table (LoRaWAN IN module MaxEIRP is 18.5 dBm)
Power Index
Power level (923 MHz)
0
MaxEIRP = 18.5 dBm
1
MaxEIRP – 2 dB
2
MaxEIRP – 4 dB
3
MaxEIRP – 6 dB
4
MaxEIRP – 8 dB
5
MaxEIRP – 10 dB
Table: Power levels table (LoRaWAN ASIA-PAC / LATAM module MaxEIRP is 18.5 dBm)
Power Index
Power level (923 MHz Japan)
0
MaxEIRP = 16 dBm
1
MaxEIRP – 2 dB
2
MaxEIRP – 4 dB
3
MaxEIRP – 6 dB
4
MaxEIRP – 8 dB
5
MaxEIRP – 10 dB
6
MaxEIRP – 14 dB
7
MaxEIRP – 14 dB
Table: Power levels table (LoRaWAN JP / KR (band AS923MHZ Japan) module MaxEIRP is 16 dBm)
Power Index
Power level (920 MHz Korea)
0
MaxEIRP = 14 dBm
1
MaxEIRP – 2 dB
2
MaxEIRP – 4 dB
3
MaxEIRP – 6 dB
4
MaxEIRP – 8 dB
5
MaxEIRP – 10 dB
6
MaxEIRP – 12 dB
7
MaxEIRP – 14 dB
Table: Power levels table (LoRaWAN JP / KR (band KR920-923MHz) module MaxEIRP is 14 dBm)
Example of use:
{
LoRaWAN.setPower(1);
LoRaWAN.getPower();
}
Related variable:
LoRaWAN._powerIndex → Stores the previously set power

Adaptive data rate (ADR)

The setADR() function allows the user to enable or disable the adaptive data rate (ADR). The server is informed about the status of the module's ADR. In every uplink frame it receives from ADR field in uplink datapacket. If ADR is enabled, the server will optimize the data rate and the transmission power based on the information collected from the network: the RSSI / SNR of the last received packets.
The getADR() function allows the user to query the device adaptive data rate status. The attribute _adrpermits to access to the settings of the module. This attribute is set to 'true' if ADR is enabled or 'false' if ADRis disabled.
Example of use:
{
LoRaWAN.setADR(“on”);
LoRaWAN.setADR(“off”);
LoRaWAN.getADR();
}
Related variable:
LoRaWAN._adr → Stores the previously set ADR status

Data rate

The setDataRate() function allows the user to set the data rate to be used for the next transmission. The following encoding is used for Data Rate (DR):
Data Rate
Configuration
Indicative physicalbit rate [bits/s]
Maximum payload[bytes]
0
LoRa: SF12 / 125 kHz
250
51
1
LoRa: SF11 / 125 kHz
980
51
2
LoRa: SF10 / 125 kHz
980
51
3
LoRa: SF9 / 125 kHz
1760
115
4
LoRa: SF8 / 125 kHz
5470
222
5
LoRa: SF7 / 125 kHz
5470
222
Table: Data rates table for the LoRaWAN EU, IN, ASIA-PAC / LATAM and JP / KR modules
Data Rate
Configuration
Indicative physicalbit rate [bits/s]
Maximum payload[bytes]
0
LoRa: SF10 / 125 kHz
980
11
1
LoRa: SF9 / 125 kHz
1760
53
2
LoRa: SF8 / 125 kHz