🛠 Uplinks confirmés robustes et duty cycle

Arduino MKR WAN 1310 · avance · Schéma : IMG-mkr-wan-1310-avance-1-mkrwan1310-uplink-confirme-robuste.svg — File d'attente de messages sur une MKR WAN 1310, horloge de duty cycle 2 minutes, flèches ACK/retour vers la passerelle et réémissions.

Objectives

Ensure reliable LoRaWAN transmissions from the MKR WAN 1310: confirmed uplinks with ACK, respecting the firmware floor of one transmission every 2 minutes (EU duty cycle, not modifiable), RAM queue, backoff on failure, and workaround for the frame counter bug that blocks transmission after ~255 sends (MKRWAN issue #141).

Hardware

Complete code

// Uplink confirme robuste avec file d'attente — MKR WAN 1310
#include <MKRWAN.h>

LoRaModem modem;
String appEui = "0000000000000000";
String appKey = "00000000000000000000000000000000";

const int TAILLE_FILE = 8;
String file[TAILLE_FILE];
int tete = 0, queue = 0, nbFile = 0;
unsigned long dernierEnvoi = 0;
unsigned long totalEnvois = 0;

void setup {
  Serial.begin(115200);
  while (!Serial);
  if (!modem.begin(EU868)) { Serial.println("Module KO"); while (1); }
  // Le bug #141 (blocage apres ~255 trames) se contourne en re-joignant
  // periodiquement : rebegin + joinOTAA tous les 200 envois.
  if (!modem.joinOTAA(appEui, appKey)) { Serial.println("Join KO"); while (1); }
  modem.minPollInterval(60);
}

void loop {
  // Production : ici un capteur ou un bouton empile des messages
  if (millis % 60000 < 100 && nbFile < TAILLE_FILE) {
    file[queue] = "T=" + String(analogRead(A0));
    queue = (queue + 1) % TAILLE_FILE; nbFile++;
  }
  // Consommation : 1 message / 2 min maximum (plancher firmware EU)
  if (nbFile > 0 && millis - dernierEnvoi >= 125000UL) {
    modem.beginPacket;
    modem.print(file[tete]);
    int err = modem.endPacket(true);   // true = uplink_confirme (attend ACK)
    if (err > 0) {
      tete = (tete + 1) % TAILLE_FILE; nbFile--;
      totalEnvois++;
      Serial.println("ACK recu");
    } else {
      Serial.println("Sans ACK : on garde en file, backoff 2 min");
    }
    dernierEnvoi = millis;
    if (totalEnvois > 0 && totalEnvois % 200 == 0) {
      modem.begin(EU868);              // reinitialise le compteur de trames
      modem.joinOTAA(appEui, appKey);
    }
  }
}

Expected verification

Each confirmed message disappears from the queue and appears as "confirmed" in TTN live data; a message without ACK remains in the queue and is retried in the next cycle. After several hours, transmission no longer blocks thanks to periodic rejoining.

Common errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials