downlink.ino

Arduino MKR WAN 1310 · File : downlink.ino · Language : Arduino · Use case : Réception et exécution d'une commande descendante

A LoRaWAN node is steered remotely: this MKR WAN 1310 listens on port 8 and changes its own reporting period when the server sends it one byte. The remote-configuration pattern that avoids physically retrieving a rooftop node.

Hardware

An Arduino MKR WAN 1310 (SAMD21 microcontroller, LoRa modem driven by an onboard ESP32 that also exposes Wi-Fi, LoRa antenna and Wi-Fi antenna). Joined MKR WAN 1310, LoRaWAN server able to send a downlink (TTN console, ChirpStack downlink queue).

Wiring

No wiring; the downlink arrives in the RX1/RX2 windows after an uplink (class A).

How it works

parseIncoming() pops the decrypted downlink queue; getDataPort/getData/getDataSize expose the application payload. The new period applies immediately.

Running it

Install Arduino SAMD Boards and the MKRWAN 2.x library (MKRWAN1310), select the board, upload. The 1310 is driven through AT commands over its internal ESP32; for LoRa, plan a second LoRa board on the other end.

Variants

Add a port 9 for factory reset (key wipe), or encode several parameters in a field-bitmask buffer.

downlink.ino

// Downlinks port 8 (MKR WAN 1310) : l'octet recu = periode (min).
#include <MKRWiSOLAR.h>

const uint8_t DEVICE_EUI[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xED,0xC0,0xFF};
const uint8_t APP_EUI[]    = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const uint8_t APP_KEY[16]  = {0}; // a provisionner cote serveur

LoRaWAN lora;
unsigned long periode = 600000, dernier = 0;
void setup() {
  Serial.begin(9600);
  lora.setDeviceEui(DEVICE_EUI);
  lora.setAppEui(APP_EUI);
  lora.setAppKey(APP_KEY);
  lora.setRegion(EU_863_870_R1);
  if (lora.join(OTAA, MODEL_TYPE_A, 30000, 8) == 0) while (true);
}

void loop() {
  lora.run();
  if (lora.parseIncoming()) { // downlink en attente ?
    uint8_t port = lora.getDataPort();
    uint8_t *buf = lora.getData();
    uint8_t len = lora.getDataSize();
    if (port == 8 && len >= 1) {
      periode = (unsigned long)buf[0] * 60000UL;
      Serial.println("periode : " + String(buf[0]) + " min");
    }
  }
  if (millis() - dernier >= periode) {
    dernier = millis();
    uint8_t t[1] = { (uint8_t)(analogRead(A1) >> 2) };
    lora.sendBuffer(t, 1, 2, 0);
  }
}

← Back to the board