noeud-batterie.ino

Arduino MKR WAN 1310 · File : noeud-batterie.ino · Language : Arduino · Use case : Nœud sur pile : réveil RTC, uplink, deepSleep

Real battery deployment: since the LoRaWAN session survives deepSleep, the MKR WAN 1310 just does one uplink every thirty minutes with no re-join. On two AA NiMH the budget lasts months, provided serial port and LEDs are cut.

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). MKR WAN 1310, LiPo or 2x AA battery, sensor on A1, outdoor antenna if possible.

Wiring

Sensor on A1; in production, power the sensor through a switchable pin rather than permanently.

How it works

The MKRWiSOLAR stack keeps the session in flash: isSessionRestored() skips the (airtime-expensive) join. SAMD deepSleep + RTC alarm give a clean wake, then a single sendBuffer.

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 weekly confirmed sendBuffer to check the link, or a hardware watchdog if the site is unsupervised.

noeud-batterie.ino

// Noeud LoRaWAN sur pile : RTC + ArduinoLowPower + session conservee.
#include <MKRWiSOLAR.h>
#include <ArduinoLowPower.h>
#include <RTCZero.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

LoRaWAN lora;
RTCZero rtc;

void setup() {
  lora.setDeviceEui(DEVICE_EUI);
  lora.setAppEui(APP_EUI);
  lora.setAppKey(APP_KEY);
  lora.setRegion(EU_863_870_R1);
  // Reprise de session : ne join que si aucune session en flash
  if (!lora.isSessionRestored() &&
      lora.join(OTAA, MODEL_TYPE_A, 30000, 8) == 0)
    while (true); // join KO : attendre l'intervention
  rtc.begin();
  LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, NULL, RISING);
}

void loop() {
  int brut = analogRead(A1);
  uint8_t t[2] = { (uint8_t)(brut >> 8), (uint8_t)brut };
  lora.sendBuffer(t, 2, 2, 0);
  rtc.setAlarmEvery(30 * 60);
  rtc.enableAlarm(rtc.MATCH_SS);
  LowPower.deepSleep();
}

← Back to the board