RAK3172 connect to lorawan network at any time

Hello,
I’m making an MBus LoraWan converter. The products will be activated within 60 days. Every hour it tries to connect to the network 3 times (api.lorawan.join()). Other times he sleeps. After a total of 12 connection attempts (4 hours later), Restricted_Wait_3482136_ms occurs and does not go into sleep mode again and consumes a lot of current. Actually, restricted mode takes about 1 hour, but in this process, the mcu does not go to sleep mode. How can I overcome this problem? Is there any other way you can suggest (with battery installed)?

Hi @Lcd ,

The Restricted_Wait_3482136_ms you see is caused by the Retransmission back-off. If your device will keep trying to join for multiple times a day, it will start to hit some limits.

Probably some work around:

  • Lessen then the join attempt and/or make the interval longer.
  • Only activate the device once deployed.
  • Restart the device once detected to be not sleeping (I think this is not a recommended solution but could work).

Hi @carlrowan
If I want to connect once a day, after 12 connection attempts, will I get the Restricted_Wait warning if it cannot connect? This buys me 12 days. I have to send the products with the batteries installed, you say to do the activation process later, how can I do this?

#define OTAA_PERIOD   (65500)

#define LED1          0
#define MCU_VCC_CS    1          


#define OTAA_BAND     (RAK_REGION_EU868)
#define OTAA_DEVEUI   {0x1C, 0x70, 0x19, 0xF1, 0xFE, 0x07, 0x5A, 0x96}
#define OTAA_APPEUI   {0x1C, 0x70, 0x19, 0xF1, 0x00, 0x00, 0x00, 0x00}
#define OTAA_APPKEY   {0xB7,0xF2,0x34,0x0A,0x00,0xFB,0x8E,0x94,0x3D,0x05,0x1B,0x54,0x32,0xB8,0x2A,0x18}
uint8_t DEV_SN[10] =  {0x02, 0x00, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
/** Packet buffer for sending */
uint8_t collected_data[64] = { 0 };
uint8_t mbusData[64] = { 0 };

uint8_t analogPin = WB_A0;

bool joinn = false;       
  

void recvCallback(SERVICE_LORA_RECEIVE_T * data)
{
  if (data->BufferSize > 0) {
    Serial.println("Something received!");
    for (int i = 0; i < data->BufferSize; i++) {
      Serial.printf("%x", data->Buffer[i]);
    }
    Serial.print("\r\n");
  }
}

void joinCallback(int32_t status) {
  
  Serial.printf("Join status: %d\r\n", status);
  
}

void sendCallback(int32_t status)
{
  if (status == 0) {
    Serial.println("Successfully sent");
  } else {
    Serial.println("Sending failed");
  }
}


void LoRaWan_Join(){

  int sy=0;

  // OTAA Device EUI MSB first
  uint8_t node_device_eui[8] = OTAA_DEVEUI;
  // OTAA Application EUI MSB first
  uint8_t node_app_eui[8] = OTAA_APPEUI;
  // OTAA Application Key MSB first
  uint8_t node_app_key[16] = OTAA_APPKEY;

  if (!api.lorawan.appeui.set(node_app_eui, 8)) {
    Serial.printf("LoRaWan OTAA - set application EUI is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.appkey.set(node_app_key, 16)) {
    Serial.printf("LoRaWan OTAA - set application key is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deui.set(node_device_eui, 8)) {
    Serial.printf("LoRaWan OTAA - set device EUI is incorrect! \r\n");
    return;
  }

  if (!api.lorawan.band.set(OTAA_BAND)) {
    Serial.printf("LoRaWan OTAA - set band is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
    Serial.printf("LoRaWan OTAA - set device class is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.njm.set(RAK_LORA_OTAA))  // Set the network join mode to OTAA
  {
    Serial.printf
  ("LoRaWan OTAA - set network join mode is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.join())  // Join to Gateway
  {
    Serial.printf("LoRaWan OTAA - join fail! \r\n");
    return;
  }

//if(api.lorawan.njs.get() == true){
  if (!api.lorawan.adr.set(true)) {
    Serial.printf
  ("LoRaWan OTAA - set adaptive data rate is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.rety.set(1)) {
    Serial.printf("LoRaWan OTAA - set retry times is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.cfm.set(1)) {
    Serial.printf("LoRaWan OTAA - set confirm mode is incorrect! \r\n");
    return;
  }

  /** Check LoRaWan Status*/
  Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get()? "ON" : "OFF"); // Check Duty Cycle status
  Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get()? "CONFIRMED" : "UNCONFIRMED");  // Check Confirm status
  uint8_t assigned_dev_addr[4] = { 0 };
  api.lorawan.daddr.get(assigned_dev_addr, 4);
  Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]);  // Check Device Address
  Serial.printf("Uplink period is %ums\r\n", OTAA_PERIOD);
  Serial.println("");
//}
  
  api.lorawan.registerRecvCallback(recvCallback);
  api.lorawan.registerJoinCallback(joinCallback);
  api.lorawan.registerSendCallback(sendCallback);  
  
}

void mbus(){

 uint8_t cn=0,i=0;
 const long interval = 1500;
 unsigned long previousMillis = millis(); 
 digitalWrite(MCU_VCC_CS, HIGH);
 delay(50);    
  
  Serial1.print("D");
  //Serial.println("-----SORGULAMA YAPILDI-----");  
  
 while(1){  
    
 //Serial.printf("0x%02X ",inByte);
   if (Serial1.available() > 0) { 
     uint8_t inByte = Serial1.read();
     mbusData[cn] = inByte;
     cn++;
     if(inByte==0x16){ 
      //Serial.println("-----NORMALLL CIKISSSS-----");
      break;
     }
   } 

   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval) {
     //Serial.println("-----BEKLENEN DATA GELMEDi-----");      
     break;    
   }   
 }

  digitalWrite(MCU_VCC_CS, LOW);
}


void uplink_routine() {
  
  uint8_t data_len = 0;

  uint16_t batt = (uint16_t)(api.system.bat.get() / 10);
  Serial.printf("Battery Level: %f\r\n", api.system.bat.get());
  /** Payload of Uplink */
  
  collected_data[data_len++] = 0x01;
  collected_data[data_len++] = 0x67;
  collected_data[data_len++] = (batt >> 8);
  collected_data[data_len++] = batt;

  collected_data[data_len++] = 0x02;
  collected_data[data_len++] = 0x68;
  collected_data[data_len++] = mbusData[18];
  collected_data[data_len++] = mbusData[19];
  collected_data[data_len++] = mbusData[20];

  collected_data[data_len++] = 0x03;
  collected_data[data_len++] = 0x69;
  collected_data[data_len++] = mbusData[23];
  collected_data[data_len++] = mbusData[24];
  collected_data[data_len++] = mbusData[25];  
  collected_data[data_len++] = mbusData[26];

  collected_data[data_len++] = 0x04;
  collected_data[data_len++] = 0x70;
  collected_data[data_len++] = mbusData[29];
  collected_data[data_len++] = mbusData[30];
  collected_data[data_len++] = mbusData[31];  
  collected_data[data_len++] = mbusData[32]; 

  collected_data[data_len++] = 0x05;
  collected_data[data_len++] = 0x71;
  collected_data[data_len++] = mbusData[35];
  collected_data[data_len++] = mbusData[36];
  collected_data[data_len++] = mbusData[37];  
  collected_data[data_len++] = mbusData[38];   
 

  Serial.println("Data Packet:");
  for (int i = 0; i < data_len; i++) {
    Serial.printf("0x%02X ", collected_data[i]);
  }
  Serial.println("");

  /** Send the data package */
  if (api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1)) {
    Serial.println("Sending is requested");
  } else {
    Serial.println("Sending failed");
  }
}


void setup(){
  
  Serial.begin(115200, RAK_AT_MODE);
  Serial1.begin(9600, RAK_CUSTOM_MODE);
  
  pinMode(LED1, OUTPUT);
  pinMode(MCU_VCC_CS, OUTPUT);
  digitalWrite(MCU_VCC_CS, LOW);

  Serial.println(" LoRaWan OTAA Start ");
  Serial.println("--------------------");
//mbus();

  LoRaWan_Join();  
}

 int say = 0; 
 int cnt = 0; 

void loop() {
  
  static uint64_t last = 0;
  static uint64_t elapsed;  
 
  api.system.sleep.all(OTAA_PERIOD);                // 65,5 SANİYE UYUYOR.
  Serial.println("Wakeup..");

  say++;
  cnt++;

  if (say >=700){
    mbus();
    uplink_routine();     

   say=0;    
  } 

  if (cnt >= 1320){   //  1320 yaklaşık 24 saat yapıyor 65,5 sn de bir 
    if(api.lorawan.njs.get() == 0)
     LoRaWan_Join();    
   cnt = 0;
  }

}

Hi @Lcd ,

In theory, if you will attempt to join once a day, you should be fine. I haven’t tested it myself though.

Regarding activation process later:

  1. It is common to some electronic products that there’s a thin insulator sheet between the battery and battery terminal/holder. It is removed once the customer received the product then powered it on.
  2. Some uses reed switch and activated via magnet. I’ve personally seen this in some LoRaWAN water meters.
  3. If you have a way to reset the module, that can also work.

Btw the way, it is good to see you are using the RUI3 firmware development framework. How is the experience so far?

Another way is to make sure that the device already joined and activated in the network server so it will not need to do join attempts anymore and just do the normal uplinks.

Thanks Carlrowan. you give good ideas. I think I will do good work with RAK modules and RUI3. Also, I can’t read DevEUIs written on rak3172 from api. (api.lorawan.deui.get(buf, len):wink: returns zero. We learn this command (api.lorawan.njs.get()) that we join the network server?