Confirmation of Data Reception via LoRaWAN

I am writing to inquire about confirming whether the gateway successfully received the data I sent via LoRaWAN.

I have set the confirm status of my function to true, but I am unsure if the data has been received under the following conditions:

if (api.lorawan.send(data_len, (uint8_t*)receivedData.c_str(), 2, true)) {
    Serial1.println("Sending ble_data");
} else {
    Serial1.println("Sending failed ble data");
}

Could you please provide guidance on how to verify the successful reception of data in this context?

Thank you for your assistance.

RUI3 Best Practice => Low Power Example => RUI3 LoRaWAN callback for TX

status == 0 ==> confirmation ACK received.

from the log:

17:13:31.972 --> [UPLINK] Start
17:13:32.083 --> [UPLINK] Sending packet # 1
17:13:32.191 --> [UPLINK] Packet enqueued, size 4
17:13:33.966 --> [TX-CB] TX status 0
17:13:33.966 --> [RX-CB] RX, port 0, DR 2, RSSI -59, SNR 9
17:13:34.372 --> 
17:13:34.372 --> +EVT:SEND_CONFIRMED_OK

status != 0 ==> no ACK received.

from the log:

17:15:02.174 --> [UPLINK] Packet enqueued, size 4
17:15:05.333 --> [TX-CB] TX status 4
17:15:05.444 --> +EVT:SEND_CONFIRMED_FAILED(4)

I want to check the following conditions in service_lora.c on arduino.

if( mcpsConfirm->McpsRequest == MCPS_CONFIRMED)
    {
        if(mcpsConfirm->AckReceived)
            udrv_serial_log_printf("+EVT:SEND_CONFIRMED_OK\r\n");
        else
            udrv_serial_log_printf("+EVT:SEND_CONFIRMED_FAILED(%d)\r\n", mcpsConfirm->Status);
    }
    else {
        udrv_serial_log_printf("+EVT:TX_DONE\r\n");
    }

I have tried the following on arduino.

void sendCallback(int32_t status)
{
    if (status == MCPS_CONFIRMED) {
        Serial1.println("SEND_CONFIRMED_OK");
    } else {
        Serial1.println("SEND_CONFIRMED_FAILED");
    }
}
if (api.ble.uart.available()) {
        String receivedData = "";
        char receivedChar;
        while (api.ble.uart.available()) {
            receivedChar = api.ble.uart.read();
            if (receivedChar == '\n') {
                break; 
            }
            receivedData += receivedChar; 
        }
        int data_len = receivedData.length(); 
        if (api.lorawan.send(data_len, (uint8_t*)receivedData.c_str(), 2, true)) { 
            api.lorawan.registerSendCallback(sendCallback);
            Serial1.println("Sending ble_data");
        } else {
            Serial1.println("Sending failed ble data");
        }
    } 
}

(1) DON’T do while loops in a callback. You are disturbing the LORaWAN stack handling

        while (api.ble.uart.available()) {
            receivedChar = api.ble.uart.read();
            if (receivedChar == '\n') {
                break; 
            }
            receivedData += receivedChar; 
        }

(2) status can have the following information:

    RAK_LORAMAC_STATUS_OK = 0,                          ///Service performed successfully
    RAK_LORAMAC_STATUS_ERROR,                           ///An error occurred during the execution of the service
    RAK_LORAMAC_STATUS_TX_TIMEOUT,                      ///A Tx timeout occurred
    RAK_LORAMAC_STATUS_RX1_TIMEOUT,                     ///An Rx timeout occurred on receive window 1
    RAK_LORAMAC_STATUS_RX2_TIMEOUT,                     ///An Rx timeout occurred on receive window 2
    RAK_LORAMAC_STATUS_RX1_ERROR,                       ///An Rx error occurred on receive window 1
    RAK_LORAMAC_STATUS_RX2_ERROR,                       ///An Rx error occurred on receive window 2
    RAK_LORAMAC_STATUS_JOIN_FAIL,                       ///An error occurred in the join procedure
    RAK_LORAMAC_STATUS_DOWNLINK_REPEATED,               ///A frame with an invalid downlink counter was received. The downlink counter of the frame was equal to the local copy of the downlink counter of the node.
    RAK_LORAMAC_STATUS_TX_DR_PAYLOAD_SIZE_ERROR,        ///The MAC could not retransmit a frame since the MAC decreased the datarate. The payload size is not applicable for the datarate.
    RAK_LORAMAC_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS,   ///The node has lost MAX_FCNT_GAP or more frames.
    RAK_LORAMAC_STATUS_ADDRESS_FAIL,                    ///An address error occurred
    RAK_LORAMAC_STATUS_MIC_FAIL,                        ///Message integrity check failure
    RAK_LORAMAC_STATUS_MULTICAST_FAIL,                  ///Multicast error occurred
    RAK_LORAMAC_STATUS_BEACON_LOCKED,                   ///Beacon locked
    RAK_LORAMAC_STATUS_BEACON_LOST,                     ///Beacon lost
    RAK_LORAMAC_STATUS_BEACON_NOT_FOUND,                ///Beacon not found

On API level you will get RAK_LORAMAC_STATUS_RX2_TIMEOUT if no ACK was received.

Never used it, but you there is an API call to get the latest send status api.lorawan.cfs.get()

I solved my problem by using this API api.lorawan.cfs.get() . but now I have one more question.
I tried to use interrupt to read the data that is being read serially, but it doesn’t work.
Does RAK11720 support void serialEvent() function? or is there another way?



String inputString = "";        
bool stringComplete = false;  

void setup() {
  // initialize serial:
  Serial.begin(9600, RAK_CUSTOM_MODE);
  Serial.println("RAKwireless LoRaWan OTAA Example");
  Serial.println("------------------------------------------------------");
  inputString.reserve(200);
}

void loop() {
  if (stringComplete) {
    Serial.println(inputString);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

RUI3 does not support an callback on Serial data received on API level.
You can only poll with Serial.available();

The reason is that AT commands are sent over Serial and the AT command handler is using the callback already.

If you are trying to send commands over Serial to the device, an option is to use custom AT commands.

I want to use interrupt to read the data coming serially from another microcontroller every 5 seconds.
Is it possible to use UART1 and receive data via interrupts?
UART1 without AT Command

RUI3 does not have that function on API level. You can try to dig into the BSP and hijack the callback. But I would not know how to do it.

Board Support Package
Common name used in Arduino world.

Hi ? Beegee
For the RUI3 API, is there an API that can tell if the bluetooth connection is disconnected or connected?

api.ble.registerCallback(Event event,BLE_HANDLER callback)
Callback function is type void ble_connect(void)
You need to register callbacks for the two events separate, one with event BLE_CONNECTED and one with event BLE_DISCONNECTED

But I have no example code.