I was recently asked to check if a newly installed LoRaWAN gateway was working properly. The goal was simple: I needed to make sure that devices could actually connect to it and use the LoRaWAN network. To solve this, I decided to build a simple and portable testing device that could prove the connection was alive and working.
I ended up building two small devices because I wasn't sure which network server the gateway was using. I made one for The Things Network and another for ResIoT, just to cover my bases. This approach let me test both possibilities without any hassle.
In this article, I will walk you through what I built, how I did the testing, and how you can do the same if you ever need to verify a LoRaWAN gateway.
The Tools for the Job
To build my tester, I used two do-it-yourself LoRa device kits that were kindly provided by Meshnology. These are their newest kits, and they are really handy for building portable gadgets that use the LoRa network. One kit is called the N33 and the other is the N35. They both came with big batteries, but since I just needed a temporary tester, I left the batteries out of the case for this project.
Inside both of these kits is the main brain of the operation, a Heltec ESP32 LoRa board. It is a small circuit board that can connect to Wi-Fi, but more importantly for this task, it has a LoRa radio built right in. This is what allows it to talk to the gateway over long distances without using much power.
The kits also include a nice 3D-printed enclosure that makes the whole thing feel like a finished, handheld product. For my test, I used the exact same program on both devices. The only thing I changed was the login information for the different network servers they needed to connect to.
Setting Up the Software
To make the devices work, I needed to upload a program, and for that I used Arduino IDE. I did not have to write this from scratch. I heavily relied on a ready-made example code provided by Heltec, the company that makes the boards. This example shows you exactly how to get their boards connected to a LoRaWAN network, which was perfect for my goal.
The most important part of the setup was updating the LoRaWAN parameters inside that code. This is like giving the device its unique username and password to join the specific network. I found these details, called the Device EUI and App Key, within the network server I was using.
I flashed this same sketch onto both of my devices, but I changed the parameters for each one. One device was set up with the credentials for The Things Network, and the other was set up for ResIoT. This way, no matter which server the gateway was talking to, I had a device ready to test it.
The full code I used is available below:
#include "LoRaWan_APP.h"
#include "Arduino.h"
#include "HT_SSD1306Wire.h"
#include "WiFi.h"
/* ---------- LoRaWAN OTAA parameters ---------- */
uint8_t devEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t appEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t appKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// Dummy ABP keys to satisfy linker (unused in OTAA mode)
uint32_t devAddr = 0;
uint8_t nwkSKey[16] = {0};
uint8_t appSKey[16] = {0};
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;
DeviceClass_t loraWanClass = CLASS_A;
bool overTheAirActivation = true;
bool loraWanAdr = true;
bool isTxConfirmed = true;
uint8_t appPort = 2;
uint8_t confirmedNbTrials = 4;
uint32_t appTxDutyCycle = 15000;
uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
/* ---------- OLED setup ---------- */
SSD1306Wire oledDisplay(0x3c, 500000, SDA_OLED, SCL_OLED, GEOMETRY_128_64, RST_OLED);
void VextON(void) {
pinMode(Vext, OUTPUT);
digitalWrite(Vext, LOW); // Vext ON
}
void VextOFF(void) {
pinMode(Vext, OUTPUT);
digitalWrite(Vext, HIGH); // Vext OFF
}
/* ---------- LoRaWAN App ---------- */
static void prepareTxFrame(uint8_t port) {
appDataSize = 4;
appData[0] = 0x00;
appData[1] = 0x01;
appData[2] = 0x02;
appData[3] = 0x03;
}
/* ---------- Display helper ---------- */
void showDisplay(String line1, String line2 = "", String line3 = "") {
oledDisplay.clear();
oledDisplay.drawString(0, 0, line1);
oledDisplay.drawString(0, 10, line2);
oledDisplay.drawString(0, 20, line3);
oledDisplay.display();
}
/* ---------- Main setup ---------- */
RTC_DATA_ATTR bool firstRun = true;
void setup() {
Serial.begin(115200);
VextON(); // Power on OLED
delay(100);
oledDisplay.init();
oledDisplay.clear();
oledDisplay.display();
showDisplay("Heltec ResIOT", "Initializing...");
Mcu.begin(HELTEC_BOARD, SLOW_CLK_TPYE);
if (firstRun) {
LoRaWAN.displayMcuInit();
firstRun = false;
}
Serial.println("Setup complete");
}
/* ---------- Main loop ---------- */
void loop() {
switch (deviceState) {
case DEVICE_STATE_INIT: {
#if (LORAWAN_DEVEUI_AUTO)
LoRaWAN.generateDeveuiByChipID();
#endif
LoRaWAN.init(loraWanClass, loraWanRegion);
LoRaWAN.setDefaultDR(3);
showDisplay("ResIOT Init", "Joining...");
deviceState = DEVICE_STATE_JOIN;
break;
}
case DEVICE_STATE_JOIN: {
showDisplay("ResIOT", "Joining...");
LoRaWAN.join();
break;
}
case DEVICE_STATE_SEND: {
showDisplay("ResIOT", "Sending data...");
prepareTxFrame(appPort);
LoRaWAN.send();
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE: {
uint32_t txDutyCycleTime = appTxDutyCycle + randr(-APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND);
showDisplay("ResIOT", "Sleeping...", "Next TX soon");
LoRaWAN.cycle(txDutyCycleTime);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP: {
LoRaWAN.sleep(loraWanClass);
break;
}
default: {
deviceState = DEVICE_STATE_INIT;
break;
}
}
}
A Closer Look at the Network Servers
To get my devices on the network, I first had to register them online. I created a free account on The Things Network and set up a new application there. Inside that application, I added a single device, which I named "test-traveler." This process generated the unique IDs and keys I needed to copy into my device's code.
I initially set up my first device for The Things Network because I have my own gateway on that server. This let me verify that my testing device and my code were working correctly before I went to test the target gateway. It was a good way to confirm my method worked.
Later, I found out the gateway I needed to test was actually using a different server called ResIoT. So, I repeated the exact same process there. I created another free account, made a new application, and registered my second device. Now I had two testers, each programmed to talk to a different network cloud.
The Live Test
With everything set up, it was time for the real test. I plugged in the device I had configured for The Things Network. Almost immediately, I saw a "joined" message on its small screen. This was the first sign of success, confirming my device had successfully connected to a gateway and registered with the network server.
To double-check, I looked at the web interface for The Things Network. I could see my device listed there, and the "last seen" timestamp was updating. This proved that data was actively traveling from my device, through the gateway, and all the way to the cloud server.
Then, I tested the second device set up for ResIoT. I plugged it in at my home, far from the target gateway. This time, the screen showed "joining" but never got a "joined" message. When I checked the ResIoT website, the device status was "unconnected."
This was expected and actually helpful, because it confirmed that the specific gateway I needed to test was not in sight so going at location, seeing it will confirm that it is working.
Understanding the LoRaWAN Ecosystem
To understand why my test worked, it helps to know the three main parts of a LoRaWAN system. First, you have the end node, which is the simple device I built. Its only job is to take a sensor reading and send a small bit of data wirelessly. It can't connect to the internet on its own.
That data is picked up by the second part, the gateway. Think of the gateway as a bridge. It receives the radio signal from my end node and then forwards that data to the internet. The gateway is the part that has a real internet connection, usually through Ethernet or a cellular SIM card.
The third part is the network server, which is an online platform like The Things Network or ResIoT. This server is in charge of managing all the devices and securely storing the data they send. For my device to work, all three of these parts—the end node, the gateway, and the network server, need to be online and talking to each other.
My test proved that this whole chain was functioning.
Why LoRaWAN is Useful
What makes LoRaWAN really useful is its incredible range and low power needs. The wireless signal between my little device and a gateway can travel for many kilometers, even through buildings. This is perfect for connecting sensors in remote fields, on water meters, or in other hard-to-reach spots where Wi-Fi or cellular service is weak or unavailable.
Because the devices send such small amounts of data and only do it occasionally, they use very little power. A device that just sends a "I'm alive" message once a day can run on a single battery for several years. This makes it a practical solution for long-term monitoring without anyone needing to constantly change batteries.
This combination of long range and long battery life opens up a lot of possibilities. You can use it for things like tracking soil moisture on a farm, monitoring parking spaces in a city, or getting an alert if a water pipe freezes, all without a complicated power or internet setup.
Conclusion and Future Projects
This simple tester served its purpose perfectly. It let me quickly verify that the installed LoRaWAN gateway was operational and that devices could successfully join the network and send data. By building a portable device, I was able to easily transport my test and get a clear answer on the spot.
I plan on exploring more LoRaWAN projects in the near future. If there are specific examples or applications you would like to see, like environmental monitoring or asset tracking, please let me know in the comments. Your feedback helps me decide what to build and share next.
If you want to see those upcoming projects, hitting the subscribe button is the best way to stay updated.
Thank you for following along with this build, and I look forward to sharing my next one with you.
Just a heads-up: the links below are affiliate links. This means if you click through and make a purchase, I may earn a small commission at no extra cost to you. This is a simple way to support my work and helps me continue creating free content for you. Thanks for your support!
LoRaWAN Gateways and Sensors:
- LoRaWAN Indoor Gateway - https://s.click.aliexpress.com/e/_c2w4qx6J
- SenseCAP Outdoor Gateway - https://s.click.aliexpress.com/e/_c4XdxMqb
- TTGO ESP32 LoRa development board - https://s.click.aliexpress.com/e/_c3ZUOen5
- Heltec Assset Tracking Board - https://s.click.aliexpress.com/e/_c30bUuIF
- LoRaWAN Temperature and Humidity Sensor - https://s.click.aliexpress.com/e/_c4SuizBv
- LoRaWAN Distance Sensor - https://s.click.aliexpress.com/e/_c3jYr7IB
- RAK4631 LoRa Module - https://s.click.aliexpress.com/e/_c3v247Fv
- LoRa32 V3 Boards - https://s.click.aliexpress.com/e/_c4tT9e1h
- LoRaWAN GPS Tracker - https://s.click.aliexpress.com/e/_c349Ic3V
- LoRaWAN Smart Water Meter - https://s.click.aliexpress.com/e/_c2ybfJOr
