To check if a TTN gateway fails, send confirmed

A Node makes OTAA in the beginning. Thus directly at the beginning also ADR and takes the smallest SF. In the best case, a gateway is nearby. SF7 will probably be chosen. But what happens if this gateway goes offline? A node that is supposed to run for several years will not notice and does not restart.

Send confirmed every x times to check!

For example, we can do a software reset every day, but that’s not necessary. That’s why we have to have a downlink, which is triggered regularly to check if everything is okay. Through ADR, every 64 sends a downlink to adapt the SF. But the node never knows when exactly this downlink will happen.
As a result, the node itself must set the time. There is the possibility to set the confirmed-bit in the LoRaWAN. The gateway sends an answer that he has received the packet.
I changed the code to send a message every 64 times with Confirmed. If we get a confirmation, everything goes on as before. If we do not get an answer, we execute a software reset so that OTAA + ABP will be executed again and we will reach a more distant gateway through a higher SF.

If you have not read my article on ABP yet, I recommend it: https://mariozwiers.de/2019/01/04/adaptive-data-rate-the-things-uno-rn2483/

We need a few extra lines outside the functions:

// Confirmed every X to check if Gateway is available
#define checkConfirmed 64
int unconfirmedCounter = checkConfirmed/2;
void(* resetFunc) (void) = 0; // declare reset function at address 0

The normal sendBytes(…) function is replaced with the following:

if (unconfirmedCounter >= checkConfirmed) {
    debugSerial.println("### SEND CONFIRMED ###");
    if (ttn.sendBytes(payload, sizeof(payload), 1 , true) == TTN_ERROR_UNEXPECTED_RESPONSE) {
      debugSerial.println("ERROR! Restart...");
      delay(1000);
      resetFunc();
    } else {
      debugSerial.println("Everything works Fine... :)");
      unconfirmedCounter = 0;
    }
  } else {
    // Send it off
    ttn.sendBytes(payload, sizeof(payload));
    debugSerial.print("Unconfirmed Message Count: ");
    debugSerial.print(unconfirmedCounter);
    debugSerial.print("/");
    debugSerial.println(checkConfirmed);
    unconfirmedCounter++;
  }

So that we can perform a manual reset without having to contact the Arduino, I have also adjusted the message(…) function:

if (port == 2 && payload[0] == 1) {
    debugSerial.println("### REMOTE RESET ###");
    delay(1000);
    resetFunc();
}

If we now send “01” to FPort 2, we will reset:

In the test I set the value to 20 instead of 64 so I did not have to wait that long. See there, it works:

In the next case I switched off the gateway after 5. The Node did not notice anything at this time and kept sending until no confirmed came back.

If the gateway remains offline for a long time and no one else is nearby, the node will remain in OTAA mode and will go online again once a gateway is within range.
Now we are prepared to install a node in other places where we will not have access without further ado.
I wish you success!

2 thoughts on “To check if a TTN gateway fails, send confirmed”

  1. “Through ADR, every 64 sends a downlink to adapt the SF. But the node never knows when exactly this downlink will happen.”

    I think it does know. After setting the ADRAckReq bit, the server should respond within ADR_ACK_DELAY uplinks, which is 32 for EU868. So, if it did not receive a response within ADR_ACK_DELAY, it should lower its data rate.

    1. That sounds right! But nothing happened in my test, unfortunately. In theory it should go like this. Thanks 😉

Comments are closed.