Time request in join ABP mode

I have already managed to update the date and time of the rak3172 device in OTAA join mode, without much difficulty. Now I’m trying to do the same for the ABP join mode, but the problem is that it simply doesn’t recognize the downlink to update the date and time or to confirm the message. First I tried using the AT command and then with the Arduino IDE, the error happened in both. So I would like to know if it is possible to update the date and time in ABP mode, I used the latest version of the at command firmware (4.0.6) and the latest Arduino library.

/***
 *  This example shows LoRaWan protocol joining the network in ABP mode, class A, region US915.
 *  Device will send uplink every 5 seconds.
***/

#define ABP_PERIOD   (5000)
/*************************************

   LoRaWAN band setting:
     RAK_REGION_EU433
     RAK_REGION_CN470
     RAK_REGION_RU864
     RAK_REGION_IN865
     RAK_REGION_EU868
     RAK_REGION_US915
     RAK_REGION_AU915
     RAK_REGION_KR920
     RAK_REGION_AS923

 *************************************/
#define ABP_BAND     (RAK_REGION_AU915)

/** Packet buffer for sending */
uint8_t collected_data[64] = { 0 };

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");
    }
}

/*************************************
 * enum type for LoRa Event
    RAK_LORAMAC_STATUS_OK = 0,
    RAK_LORAMAC_STATUS_ERROR,
    RAK_LORAMAC_STATUS_TX_TIMEOUT,
    RAK_LORAMAC_STATUS_RX1_TIMEOUT,
    RAK_LORAMAC_STATUS_RX2_TIMEOUT,
    RAK_LORAMAC_STATUS_RX1_ERROR,
    RAK_LORAMAC_STATUS_RX2_ERROR,
    RAK_LORAMAC_STATUS_JOIN_FAIL,
    RAK_LORAMAC_STATUS_DOWNLINK_REPEATED,
    RAK_LORAMAC_STATUS_TX_DR_PAYLOAD_SIZE_ERROR,
    RAK_LORAMAC_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS,
    RAK_LORAMAC_STATUS_ADDRESS_FAIL,
    RAK_LORAMAC_STATUS_MIC_FAIL,
    RAK_LORAMAC_STATUS_MULTICAST_FAIL,
    RAK_LORAMAC_STATUS_BEACON_LOCKED,
    RAK_LORAMAC_STATUS_BEACON_LOST,
    RAK_LORAMAC_STATUS_BEACON_NOT_FOUND,
 *************************************/

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

void setup()
{
    Serial.begin(115200, RAK_AT_MODE);
    delay(2000);
  
    Serial.println("RAKwireless LoRaWan ABP Example");
    Serial.println("------------------------------------------------------");

    if(api.lorawan.nwm.get() != 1)
    {
        Serial.printf("Set Node device work mode %s\r\n",
            api.lorawan.nwm.set(1) ? "Success" : "Fail");
        api.system.reboot();
    }

    // ABP Device Address MSB first
    uint8_t node_dev_addr[4] = ABP_DEVADDR;
    // ABP Application Session Key
    uint8_t node_app_skey[16] = ABP_APPSKEY;
    // ABP Network Session Key
    uint8_t node_nwk_skey[16] = ABP_NWKSKEY;


//adicionado
    uint16_t maskBuff = 0x0001;
    api.lorawan.mask.set(&maskBuff);
  
    if (!api.lorawan.njm.set(RAK_LORA_ABP))	// Set the network join mode to ABP
    {
        Serial.printf("LoRaWan ABP - set network join mode is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.daddr.set(node_dev_addr, 4)) {
        Serial.printf("LoRaWan ABP - set device addr is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.appskey.set(node_app_skey, 16)) {
        Serial.printf("LoRaWan ABP - set application session key is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.nwkskey.set(node_nwk_skey, 16)) {
        Serial.printf("LoRaWan ABP - set network session key is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.band.set(ABP_BAND)) {
        Serial.printf("LoRaWan ABP - set band is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
        Serial.printf("LoRaWan ABP - set device class is incorrect! \r\n");
        return;
    }
  
    if (!api.lorawan.adr.set(false)) {
        Serial.printf("LoRaWan ABP - set adaptive data rate is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.rety.set(0)) {
        Serial.printf("LoRaWan ABP - set retry times is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.cfm.set(0)) {
        Serial.printf("LoRaWan ABP - 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", ABP_PERIOD);
    Serial.println("");
    api.lorawan.registerRecvCallback(recvCallback);
    api.lorawan.registerSendCallback(sendCallback);
}

void uplink_routine()
{
    if (!service_lora_set_timereq(1)){
       Serial.printf("LoRaWan ABP - set time_req mode is incorrect! \r\n");
    }
    /** Payload of Uplink */
    uint8_t data_len = 0;
    collected_data[data_len++] = (uint8_t) 't';
    collected_data[data_len++] = (uint8_t) 'e';
    collected_data[data_len++] = (uint8_t) 's';
    collected_data[data_len++] = (uint8_t) 't';
  
    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 loop()
{
    static uint64_t last = 0;
    static uint64_t elapsed;
  
    if ((elapsed = millis() - last) > ABP_PERIOD) {
        uplink_routine();
  
        last = millis();
    }
    //Serial.printf("Try sleep %ums..", ABP_PERIOD);

    api.system.sleep.all(ABP_PERIOD);
    //Serial.println("Wakeup..");
}

//log serial arduino
08:28:35.763 → RAKwireless LoRaWan ABP Example
08:28:35.796 → ------------------------------------------------------
08:28:35.796 → Duty cycle is ON
08:28:35.796 → Packet is UNCONFIRMED
08:28:35.796 → Device Address is 8B****80
08:28:35.796 → Uplink period is 5000ms
08:28:35.796 →
08:28:35.796 → Current Work Mode: LoRaWAN.
08:28:40.794 → LoRaWan ABP - set time_req mode is incorrect!
08:28:40.794 → Data Packet:
08:28:40.794 → 0x74 0x65 0x73 0x74
08:28:40.828 → Sending is requested
08:28:44.592 → Sending failed
08:28:44.592 → +EVT:SEND_CONFIRMED_FAILED(4)
08:28:44.592 → +EVT:TIMEREQ_FAILED
08:28:49.623 → LoRaWan ABP - set time_req mode is incorrect!
08:28:49.623 → Data Packet:
08:28:49.623 → 0x74 0x65 0x73 0x74
08:28:49.623 → Sending is requested
08:28:53.220 → Sending failed
08:28:53.220 → +EVT:SEND_CONFIRMED_FAILED(4)
08:28:53.220 → +EVT:TIMEREQ_FAILED

//log server
{
“params”: {
“rx_time”: 1695731338.6179185,
“port”: 2,
“duplicate”: false,
“radio”: {
“gps_time”: 1379766556600,
“delay”: 0.05879998207092285,
“datarate”: 2,
“modulation”: {
“bandwidth”: 125000,
“type”: “LORA”,
“spreading”: 10,
“coderate”: “4/5”
},
“hardware”: {
“status”: 1,
“chain”: 1,
“tmst”: 3632774500,
“snr”: -0.5,
“rssi”: -110,
“channel”: 4,
“gps”: {
“lat”: -20.42013931274414,
“lng”: -54.56623840332031,
“alt”: 727
}
},
“time”: 1695731338.6179185,
“freq”: 916,
“size”: 18
},
“counter_up”: 3,
“lora”: {
“header”: {
“class_b”: false,
“confirmed”: true,
“adr”: false,
“ack”: false,
“adr_ack_req”: false,
“version”: 0,
“type”: 4
},
“mac_commands”: [
{
“DeviceTimeReq”: {}
}
]
},
“payload”: “dGVzdA==”,
“encrypted_payload”: “8IFprQ==”
},
“meta”: {
“network”: “358b679dd88d47948f6e108677b4b79a”,
“packet_hash”: “9fa42eb9e7dcfb1e2135d022cf1e2a72”,
“application”: “0000000000000000”,
“device_addr”: “8b **** 80”,
“time”: 1695731338.693,
“device”: “ac************a0”,
“packet_id”: “e5c2e1b6e95648a7d8a3bb6bb5bbb7bb”,
“gateway”: “b0fd0b70002a0000”
},
“type”: “uplink”
}

{
“params”: {
“payload”: “”,
“radio”: {
“gps_time”: 1379766556600,
“delay”: 0.05879998207092285,
“datarate”: 2,
“modulation”: {
“bandwidth”: 500000,
“type”: “LORA”,
“coderate”: “4/5”,
“spreading”: 10,
“inverted”: true
},
“datr”: “SF10BW500”,
“hardware”: {
“status”: 1,
“chain”: 0,
“power”: 26,
“tmst”: 1351250916,
“snr”: -0.5,
“rssi”: -110,
“channel”: 4,
“gps”: {
“lat”: -20.42013931274414,
“lng”: -54.56623840332031,
“alt”: 727
}
},
“time”: 1695731343.6179185,
“freq”: 925.7,
“size”: 18
},
“counter_down”: 100,
“lora”: {
“header”: {
“confirmed”: false,
“adr”: true,
“ack”: true,
“version”: 0,
“type”: 3,
“pending”: false
},
“mac_commands”: [
{
“DeviceTimeAns”: {
“seconds”: 1379766556,
“fractional_second”: 158
}
},
{
“DutyCycleReq”: {
“MaxDCycle”: 0
}
},
{
“RXParamSetupReq”: {
“Frequency”: 9233000,
“DLsettings”: {
“RX2DataRate”: 8,
“RX1DRoffset”: 0
}
}
}
]
},
“port”: null,
“encrypted_payload”: “”
},
“meta”: {
“network”: “358b679dd88d47948f6e108677b4b79a”,
“packet_hash”: “9fa42eb9e7dcfb1e2135d022cf1e2a72”,
“application”: “0000000000000000”,
“device_addr”: “8b* *** 80”,
“time”: 1695731341.144,
“device”: “ac************a0”,
“packet_id”: “e5c2e1b6e95648a7d8a3bb6bb5bbb7bb”,
“gateway”: “b0fd0b7000670000”
},
“type”: “downlink”
}

Welcome to RAK forum @douglas_nascimento ,

I tested TimeReq on ABP and it works on my side both via AT command and via Arduino code.

This is the Arduino sketch I used which is a modified version of the ABP example.

/***
    This example shows LoRaWan protocol joining the network in ABP mode, class A, region US915.
    Device will send uplink every 5 seconds.
***/

#define ABP_PERIOD   (10000)
/*************************************

   LoRaWAN band setting:
     RAK_REGION_EU433
     RAK_REGION_CN470
     RAK_REGION_RU864
     RAK_REGION_IN865
     RAK_REGION_EU868
     RAK_REGION_US915
     RAK_REGION_AU915
     RAK_REGION_KR920
     RAK_REGION_AS923

 *************************************/
#define ABP_BAND     (RAK_REGION_US915)
#define ABP_DEVADDR  {0x26, 0x0D, 0xD1, 0x44}
#define ABP_APPSKEY  {0x83, 0x22, 0xEB, 0x17, 0xBF, 0x3C, 0xF3, 0x65, 0x74, 0x7D, 0xA0, 0x92, 0xC2, 0xB3, 0x21, 0xA9}
#define ABP_NWKSKEY  {0x14, 0xB0, 0x14, 0x1E, 0x14, 0x48, 0xB0, 0x96, 0xD3, 0xD7, 0x81, 0x1A, 0xC8, 0xA7, 0x3C, 0x80}

/** Packet buffer for sending */
uint8_t collected_data[64] = { 0 };

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");
  }
}

/*************************************
   enum type for LoRa Event
    RAK_LORAMAC_STATUS_OK = 0,
    RAK_LORAMAC_STATUS_ERROR,
    RAK_LORAMAC_STATUS_TX_TIMEOUT,
    RAK_LORAMAC_STATUS_RX1_TIMEOUT,
    RAK_LORAMAC_STATUS_RX2_TIMEOUT,
    RAK_LORAMAC_STATUS_RX1_ERROR,
    RAK_LORAMAC_STATUS_RX2_ERROR,
    RAK_LORAMAC_STATUS_JOIN_FAIL,
    RAK_LORAMAC_STATUS_DOWNLINK_REPEATED,
    RAK_LORAMAC_STATUS_TX_DR_PAYLOAD_SIZE_ERROR,
    RAK_LORAMAC_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS,
    RAK_LORAMAC_STATUS_ADDRESS_FAIL,
    RAK_LORAMAC_STATUS_MIC_FAIL,
    RAK_LORAMAC_STATUS_MULTICAST_FAIL,
    RAK_LORAMAC_STATUS_BEACON_LOCKED,
    RAK_LORAMAC_STATUS_BEACON_LOST,
    RAK_LORAMAC_STATUS_BEACON_NOT_FOUND,
 *************************************/

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

void setup()
{
  Serial.begin(115200, RAK_AT_MODE);
  delay(2000);

  Serial.println("RAKwireless LoRaWan ABP Example");
  Serial.println("------------------------------------------------------");

  if (api.lorawan.nwm.get() != 1)
  {
    Serial.printf("Set Node device work mode %s\r\n",
                  api.lorawan.nwm.set(1) ? "Success" : "Fail");
    api.system.reboot();
  }

  // ABP Device Address MSB first
  uint8_t node_dev_addr[4] = ABP_DEVADDR;
  // ABP Application Session Key
  uint8_t node_app_skey[16] = ABP_APPSKEY;
  // ABP Network Session Key
  uint8_t node_nwk_skey[16] = ABP_NWKSKEY;

  if (!api.lorawan.njm.set(RAK_LORA_ABP))	// Set the network join mode to ABP
  {
    Serial.printf("LoRaWan ABP - set network join mode is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.daddr.set(node_dev_addr, 4)) {
    Serial.printf("LoRaWan ABP - set device addr is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.appskey.set(node_app_skey, 16)) {
    Serial.printf("LoRaWan ABP - set application session key is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.nwkskey.set(node_nwk_skey, 16)) {
    Serial.printf("LoRaWan ABP - set network session key is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.band.set(ABP_BAND)) {
    Serial.printf("LoRaWan ABP - set band is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
    Serial.printf("LoRaWan ABP - set device class is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.adr.set(0)) {
    Serial.printf("LoRaWan ABP - set adaptive data rate is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.rety.set(0)) {
    Serial.printf("LoRaWan ABP - set retry times is incorrect! \r\n");
    return;
  }

  uint16_t maskBuff = 0x0002;
  Serial.printf("Set channel mask %s\r\n", api.lorawan.mask.set(&maskBuff) ? "Success" : "Fail");

  service_lora_set_timereq(1);

  /** 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", ABP_PERIOD);
  Serial.println("");
  api.lorawan.registerRecvCallback(recvCallback);
  api.lorawan.registerSendCallback(sendCallback);
}

void uplink_routine()
{
  /** Payload of Uplink */
  uint8_t data_len = 0;
  collected_data[data_len++] = (uint8_t) 't';
  collected_data[data_len++] = (uint8_t) 'e';
  collected_data[data_len++] = (uint8_t) 's';
  collected_data[data_len++] = (uint8_t) 't';

  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, false, 1)) {
    Serial.println("Sending is requested");
  } else {
    Serial.println("Sending failed");
  }
}

void loop()
{
  static uint64_t last = 0;
  static uint64_t elapsed;

  if ((elapsed = millis() - last) > ABP_PERIOD)
  {
    uplink_routine();
    last = millis();
    Serial.printf("The local time(UTC) is %s\r\n", api.lorawan.ltime.get().c_str());
  }
  
  //Serial.printf("Try sleep %ums..", ABP_PERIOD);
  api.system.sleep.all(ABP_PERIOD);
  //Serial.println("Wakeup..");
}

It appears to me that you cannot get the time because your uplinks are failing. Failing uplinks means failed downlinks.

Few things:

  1. Disable the frame counter checks on your LNS. Though this is not recommended, there is no way at the moment to store frame counters on the device side. In OTAA, this is not an issue since frame counters reset every join. On ABP though, if your device resets, the frame counter will reset on the device. But on the LNS, it will not.
  2. Try to increase ABP_PERIOD. I used 10 seconds on the posted sketch above.
  3. Just use service_lora_set_timereq(1); to activate timereq. I am not sure if it returns any Boolean state.

Here’s the logs on my test:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.