economie-energie.ino
Energy is NB-IoT's trump card: this sketch configures PSM and eDRX on the MKR NB 1500 SARA-R4 modem, then sleeps the SAMD21 between fifteen-minute readings. Well tuned, the whole thing lasts months on a small LiPo.
Hardware
An Arduino MKR NB 1500 (SAMD21 microcontroller, u-blox LTE-M/NB-IoT modem, external antenna, LiPo power on J6 or USB). LiPo on the battery connector, IoT SIM, antenna; an operator supporting PSM/eDRX (Orange, SFR, DT...).
Wiring
No wiring; remove unused LEDs and peripherals to target the lowest quiescent current.
How it works
AT+PSMTAU/RATTAU commands negotiate deep-sleep durations with the network; nb.sleep() parks the module, LowPower.deepSleep() stops the MCU. The RTC alarm wakes everyone up.
Running it
Install the Arduino SAMD Boards package and the MKRNB library, select the board, upload. Plan for an activated IoT SIM (LTE-M or NB1) and good reception: attaching to the network can take several minutes.
Variants
Tune the period to data criticality, or also wake on an external interrupt (door, water sensor) to serve as an alarm device.
economie-energie.ino
// Économie d'energie LPWA : PSM + deepSleep SAMD entre deux mesures.
#include <MKRNB.h>
#include <ArduinoLowPower.h>
#include <RTCZero.h>
const char PIN_SIM[] = "0000";
const char APN[] = "iot.1nce.net";
NB nb;
NBClient client;
RTCZero rtc;
void setup() {
Serial.begin(9600);
if (nb.begin(PIN_SIM) != NB_READY) while (true);
while (nb.getStatus() != NETWORK_JOINED) delay(2000);
nb.attachGPRS(APN);
// Demandes PSM au reseau (valeur en secondes, selon operateur)
nb.sendCheckConfig("PSMTAU=11000001"); // TAU 1 h (encodage 3GPP)
nb.sendCheckConfig("RATTAU=11000010"); // eDRX ~40 s
rtc.begin();
LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, NULL, RISING);
}
void loop() {
mesure();
nb.sleep(); // modem en mode economique
rtc.setAlarmEvery(15 * 60);
rtc.enableAlarm(rtc.MATCH_SS);
LowPower.deepSleep(); // MCU dort jusqu'a l'alarme
}
void mesure() {
float vbat = 3.3 * analogRead(VBAT) / 1023.0 * 1.5;
Serial.println("VBAT=" + String(vbat, 2));
// ... ouverture client + envoi periodique ...
}