Example for LoRaWAN Communication-OTAA Network Joining
Last revision 2026/01/24
This article demonstrates how to set up and join a LoRaWAN network using the OTAA method, featuring hardware preparation with FireBeetle 2 ESP32-E and Gravity LoRaWAN Node Module. It provides comprehensive wiring diagrams and sample Arduino code for sending and receiving data within the network.
Hardware Preparation
- FireBeetle 2 ESP32-E (SKU: DFR0654) ×1
- Gravity: LoRaWAN Node Module(EU868)(DFR1115-868) ×1
- PH2.0-4P Cable ×1
- USB Data Cable ×1
Software Preparation
- Download Arduino IDE: Click to Download Arduino IDE
- Install SDK: Visit the FireBeetle 2 ESP32-E WIKI page for SDK installation instructions
- Download Arduino Library: Click to download DFRobot_LWNode Library and refer to the guide: How to Install a Library?
Wiring Diagram
I2C Wiring Diagram (This connection method is used in all the following examples)

Pin Connection Description:
- Node Module: SDA Pin --- (Connects to) --- Main Controller: 21/SDA
- Node Module: SCL Pin --- (Connects to) --- Main Controller: 22/SCL
- Node Module: - Pin --- (Connects to) --- Main Controller: GND
- Node Module: + Pin --- (Connects to) --- Main Controller: 3V3
UART Wiring Diagram

Pin Connection Description:
- Node Module: TX Pin --- (Connects to) --- Main Controller: 14/D6
- Node Module: RX Pin --- (Connects to) --- Main Controller: 13/D7
- Node Module: - Pin --- (Connects to) --- Main Controller: GND
- Node Module: + Pin --- (Connects to) --- Main Controller: 3V3
Sample Code 1
Before using this example, ensure that the gateway is set to manual device addition mode and configured to allow OTAA for device registration.
OTAA Network Joining and Sending Data to the Gateway.
#include "DFRobot_LWNode.h"
#define REGION EU868
#define DATARATE DR5
// OTAA credentials (replace these with your actual values)
const char _APPEUI[]={"DFDFDFDF00000000"} ;
const char _APPKEY[]={"0102030405060708090A0B0C0D0E0F10"};
DFRobot_LWNode_IIC node(_APPEUI,_APPKEY);
void setup(void){
Serial.begin(115200);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
while(!node.setRegion(REGION)){
delay(2000);
Serial.println("REGION set fail");
}
if(!node.setAppEUI(_APPEUI)){
Serial.println("AppEUI set fail");
}
if(!node.setAppKEY(_APPKEY)){
Serial.println("AppKEY set fail");
}
if(!node.setDevType(CLASS_C)){
Serial.println("DevType set fail");
}
while (!node.setDataRate(DATARATE)) {
delay(2000);
Serial.println("DataRate set fail");
}
while (!node.setEIRP(DBM16)) {
delay(2000);
Serial.println("EIRP set fail");
}
while(!node.enableADR(false)){
delay(2000);
Serial.println("ADR set fail");
}
while(!node.setPacketType(UNCONFIRMED_PACKET)){
delay(2000);
Serial.println("Packet type set fail");
}
String deveui = node.getDevEUI();
Serial.print("DEVEUI: ");
Serial.println(deveui);
Serial.print("DATARATE: ");
Serial.println(node.getDataRate());
Serial.print("EIRP: ");
Serial.println(node.getEIRP());
// Attempt to join the LoRaWAN network
if(node.join()){
Serial.println("JOIN......");
}
while(!node.isJoined()){
delay(5000);
}
}
void loop(){
node.sendPacket("hello"); // Send a text message "hello" to the LoRaWAN gateway
node.sleep(10 * 1000);
uint8_t buf[3]={1,2,3}; // Send a binary message {1, 2, 3} to the LoRaWAN gateway
node.sendPacket(buf,3);
node.sleep(10 * 1000);
}
Result
On the node side: The serial monitor prints a message indicating successful network joining, and the node sends data to the gateway every 10 seconds.

Sample Code 2
Receiving Data from the Gateway via Polling after OTAA Network Joining.
#include "DFRobot_LWNode.h"
#define REGION EU868
#define DATARATE DR5
// OTAA credentials (replace these with your actual values)
const char _APPEUI[]={"DFDFDFDF00000000"} ;
const char _APPKEY[]={"0102030405060708090A0B0C0D0E0F10"};
uint8_t buf[256]={0x0}; // Buffer to store received data
DFRobot_LWNode_IIC node(_APPEUI,_APPKEY);
void setup(void){
Serial.begin(115200);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
while(!node.setRegion(REGION)){
delay(2000);
Serial.println("REGION set fail");
}
while(!node.setDevType(CLASS_C)){
delay(2000);
Serial.println("DevType set fail");
}
String deveui = node.getDevEUI();
Serial.print("DEVEUI: ");
Serial.println(deveui);
// Attempt to join the LoRaWAN network
if(node.join()){
Serial.println("JOIN......");
}
while(!node.isJoined()){
delay(5000);
}
Serial.println("join success");
}
void loop(){
uint8_t len = node.readData(buf); // Read data from the LoRaWAN downlink buffer
// If data is received, print it in both hexadecimal and text formats
if(len > 0){
Serial.print("\nreceive ");
Serial.print(len,HEX);
Serial.println(" bytes \nHEX:");
for(uint8_t i = 0;i<len;i++){
Serial.print(buf[i],HEX);
}
Serial.println();
Serial.println("Text:");
Serial.println((char *)buf);
}
delay(500);
}
Result
On the node side: The serial monitor prints "join success", and the node enters a polling state to check whether data is received in the buffer.

Was this article helpful?
