downlink.ino
Un nodo LoRaWAN se pilota a distancia: esta MKR WAN 1310 escucha el puerto 8 y cambia su propio periodo de envío cuando el servidor le manda un byte. El patrón de configuración remota que evita recuperar físicamente un nodo desplegado en una azotea.
Hardware
Una Arduino MKR WAN 1310 (microcontrolador SAMD21, módem LoRa pilotado por un ESP32 integrado que también expone Wi-Fi, antena LoRa y antena Wi-Fi). MKR WAN 1310 unida, servidor LoRaWAN capaz de enviar un downlink (consola TTN, cola de downlinks ChirpStack).
Cableado
Sin cableado; el downlink llega en las ventanas RX1/RX2 tras un uplink (clase A).
Funcionamiento
parseIncoming() saca la cola de downlinks descifrados; getDataPort/getData/getDataSize exponen la carga de aplicación. El nuevo periodo se aplica de inmediato.
Ejecución
Instala Arduino SAMD Boards y la librería MKRWAN 2.x (MKRWAN1310), selecciona la placa y carga. La 1310 se controla con comandos AT a través de su ESP32 interno; para LoRa, prevé una segunda placa LoRa al otro lado.
Variantes
Añade un puerto 9 para reset de fábrica (borrado de claves) o codifica varios parámetros en un buffer con máscara de bits.
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);
}
}