Now it’s about time to get the Challenger RP2040 LoRa board configured and flashed with some firmware so that we can start seeing some data coming through.
Step 3 – Installing the Arduino LoRa library
To be able to send data up to our newly created end device in the TTN network we need a library that can handle both the LoRa radio module (RFM95W) on the board as well as taking high level data and packaging it in a format that TTN will understand.
Arduino LMIC is such a library and this is what we’ve selected to use here at iLabs. Unfortunately although being a well functioning and supported library it does not work right out of the box together with our LoRa boards. It has a hard coded reference to the SPI bus used which makes it incompatible with any boards that use any spi bus other than the basic one.
To overcome this we have created a fork of the library and added functionality that supports using any available spi port on your board. This is good not only for our board but for any board that uses an spi port other than SPI. The fork is of course fully compatible with the upstream version so anyone can use it.
To use this fork you need to clone our github repo into the libraries folder, this can be done in the following way:

This example was done on a Ubuntu linux machine but should be similar on Windows and Mac machines.
If you already had the MCCI_LoRaWAN_LMIC_library installed you will get an error message that the destination path already exists. In that case you can either delete this directory or if you don’t want to do that rename it to something else.
We hope that our suggested changes can be included in the official version of the library soon but for now we have to keep these changes on our own fork.
Step 4 – Preparing the example applications for the Challenger RP2040 LoRa board.
There are a number of things to keep in mind when writing a LoRa application based on the library we just installed:
- Before running os_init() of the library you need to call hal_set_spi() to set the new SPI port to be used.
The simplest way of doing this is simply hal_set_spi(&RFM95W_SPI); This will tell the library to use the supplied SPI port instead of the default port SPI. - The hal need to be told what pins are used to connect the CS and RST signals as well as the DIO0-DIO2 pins
Here’s an example of what we mean:
// Short section of the setup code
void setup() {
while (!Serial)
delay(10);
Serial.begin(115200);
delay(100);
Serial.println(F("Starting"));
// Use new SPI interface
hal_set_spi(&RFM95W_SPI);
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
And this is an example on how to setup the pinmap:
// Example on how to configure the pinmap for the Challenger RP2040 LoRa boards
const lmic_pinmap lmic_pins = {
.nss = RFM95W_SS,
.rxtx = LMIC_UNUSED_PIN,
.rst = RFM95W_RST,
.dio = {RFM95W_DIO0, RFM95W_DIO1, RFM95W_DIO2},
.rxtx_rx_active = 0,
.rssi_cal = 5, // cal for the Challenger RP2040 LoRa, in dB
.spi_freq = 8000000,
};
Step 5 – Filling in the authentication keys from TTN
As this is an ABP (Activation By Personalization) example we also need to fill in the authentication keys that we previously generated in the TTN console. In the examples provided by the library this is done in the following way:
// LoRaWAN NwkSKey, network session key
static const PROGMEM u1_t NWKSKEY[16] = { 0x71, 0x83, 0xCA, 0x3A, 0x8C, 0xB7, 0xA8, 0x9C, 0x6B, 0xAF, 0xFF, 0x83, 0x1D, 0x12, 0xC2, 0x8C };
// LoRaWAN AppSKey, application session key
static const u1_t PROGMEM APPSKEY[16] = { 0x39, 0x0D, 0x39, 0x10, 0xDC, 0x64, 0xFF, 0x69, 0x88, 0x2C, 0x24, 0xEE, 0xE4, 0xC9, 0x3F, 0x71 };
// LoRaWAN end-device address (DevAddr)
// See http://thethingsnetwork.org/wiki/AddressSpace
// The library converts the address to network byte order as needed.
static const u4_t DEVADDR = 0x260BD125;
Step 6 – Setting the appropriate region
In order for the entire system to work together the appropriate region must be configured in the library.
Unfortunately due to how the Arduino build system is designed this configuration needs to be done in the library itself. Here’s a shortlist of the actions needed:
- Navigate to your MCCI_LoRaWAN_LMIC_library folder. It is found in your Arduino/libraries folder.
- Now enter the project_config folder and open the lmic_project_config.h file.
It is a very short file containing a few library global macros the specifies the region used. Make sure it looks like this:
// project-specific definitions
#define CFG_eu868 1
//#define CFG_us915 1
//#define CFG_au915 1
//#define CFG_as923 1
// #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP /* for as923-JP; also define CFG_as923 */
//#define CFG_kr920 1
//#define CFG_in866 1
#define CFG_sx1276_radio 1
//#define LMIC_USE_INTERRUPTS
Of course, if you are targeting another region you should select the appropriate region. But for EU it should look like this.
Now what !?
At this point you should be able to simply compile the example you have selected and it will connect and start sending data to TTN. Of course, it is rarely that easy and our example is based on our own internal LoRa infrastructure. But don’t give up and do get in touch with us if you start feeling disheartened.

If you find any errors or have suggestions to this guide please let us know and we will update it.
For online support please join our Discord server at https://discord.gg/6VftEwmtRe
0 Comments for “Getting the Challenger LoRa up on The Things Network – #2”