Downlink messages not always received on device

hopefully somebody can give me a hint to move on, i’m struggling for days now to get downlink messages properly working.
Uplink works fine.
Downlink does not work for 90% of the messages.

I have a TTN Gateway and several “BSFrance LoRa32u4 II v1.2” devices.

I use the downlink section in the console to be sure that the message is queued.

I use the well known code part found in many examples. (OTAA)

      if (LMIC.dataLen != 0) {
         // data received in rx slot after tx
        printf2("%X\n", LMIC.frame[LMIC.dataBeg]);
        message.byte1 = LMIC.frame[LMIC.dataBeg];


5930448: engineUpdate, opmode=0x908
5931266: TXMODE, freq=868300000, len=15, SF=7, BW=125, CR=4/5, IH=0
5996920: RXMODE_SINGLE, freq=868300000, SF=7, BW=125, CR=4/5, IH=0
6058840: RXMODE_SINGLE, freq=869525000, SF=9, BW=125, CR=4/5, IH=0
6063388: processRx2DnData*****
6063472: [processRx2DnData]--Nothing--
6063580: processDnData*****
** Event received ** 10 [a403]
6067031: engineUpdate, opmode=0x900

I defined the LMIC_DEBUG_LEVEL 1 in the limic library and also added some extra debugging in lmic.c.

The uplink message is send to TTN, but it seems that the downlink message is never received by the lmic library in the slot after tx.
In the TTN Console Gateway Traffic,I see that the downlink message is received. (see pictures).
I use:

downlink2 downlink1

Can someone help?, thanks.

These 3 lines are the uplink, RX1 (one second after the uplink was done) and RX2 (2 seconds after the uplink was done).

Now, assuming the timestamps (actually: ticks) are printed right before the action is being executed, a bit of math: 6,058,840 - 5,996,920 = 61,920, so 1 second between RX1 and RX2 is 61,920 ticks. Also, 5,996,920 - 5,931,266 = 65,654, in which an uplink with 2 bytes of application payload at SF7 takes about 46.3 ms, so here 1.0463 seconds = 65,654, hence converting back to one second yields 62,748 ticks? Those variations might make it hard for the device to be listening at the exact time that a gateway might be transmitting the downlink.

To mitigate that, see MAX_CLOCK_ERROR.

thanks for you quick response.
I already used the setting: setClockError(MAX_CLOCK_ERROR * 1 / 100);.
Are there other things you know of, that can solve this timing issue?

static void initfunc (osjob_t* j) {
    // reset MAC state
    LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
    // start joining
    // init done - onEvent() callback will be invoked...


If it is a timing issue indeed, then you could try to increase the value, like changing it from 1/100 to 10/100. (Very large values, like even 100% might not be supported.)

What else did you already try? Make sure the node is not too close to the gateway. Is there any difference (like for the SF that is used) for the messages that do work, and those that don’t?

(Please see How do I format my forum post?)

Is the counter for the downlink always missing? I also wonder if subscribing to the MQTT event topic reveals something.


I changed to LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100) and this seems to solve my issue. No missing messages anymore.
The counter field is always empty also when successful. (maybe only shown for downlink).
In the device overview I see that the frames down counter also adds up, so ok.
I red the “format my forum post”.

I like to thank you very much for your help!.

To save battery, you could try smaller values too. (The larger the value, the longer the device will be in a listening state.)

Be sure to test with both low SF (where downlinks are probably sent in RX1 after 1 second, which at least in EU868 uses the same SF as the uplink, like the SF7 as shown in your screenshot) and high SF (likely using RX2 after 2 seconds, in EU868 always using SF9 in TTN).

As an aside: apparently the downlink counter is never shown in the application/device’s Data page, but only in the gateway’s Traffic page. Maybe the downlink counter value is actually assigned by the network, not by the application.

OK, clear.

Thanks again,

I use Thingpark network

  • this is TTN … So you’re in the wrong forum