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

Software Preparation

Wiring Diagram

I2C Wiring Diagram (This connection method is used in all the following examples)

DFR1115-868-I2C wiring diagram

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

DFR1115-868-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.

DFR1115-868-OTAA Network Joining and Sending Result

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.

DFR1115-868-Receiving Data from the Gateway Result

Was this article helpful?

TOP