Low Power
The NeuroN6-Powersave library: sleep modes, clock profiles, peripheral and sensor power-down, the one-shot camera engine, measured currents and the external watchdog.
The NeuroN6-Powersave library reduces the Neuro N6 from continuous operation to a duty cycle with an average current in the low tens of milliamps. It provides Stop mode sleep with RTC wake, run-time clock profiles, peripheral clock gating, sensor power-down, hard power control of the thermal camera, a one-shot VD66GY capture engine, and support for an external window watchdog.
#include <NeuroN6_PowerSave.h>
#include <PowerSaveCamera.h>
#include <VD66GY_Arduino.h>
VD66GY camera(VD66GY_CARRIER_THERMAL);
void setup() {
PowerSave.begin();
PowerSave.sensorsSleep(); // IMU, magnetometer, microphone
PowerSaveCam.begin(CAMERA_VGA); // sensor and DCMIPP only
PowerSaveCam.sensorSleep();
PowerSave.setClockProfile(PS_CLOCK_LOW); // CPU 100 MHz, NPU PLLs off
}
void loop() {
PowerSaveCam.sensorWake();
PowerSaveCam.capture(); // RGB888 into PowerSaveCam.buffer()
PowerSaveCam.sensorSleep();
PowerSave.sleepStop(10000); // Stop mode, RTC wake
}Idle hook
Linking the library replaces the FreeRTOS idle hook with a __WFI() instruction. Without it the idle task spins at the full core clock during every blocking wait, measured at about 100 mA at 800 MHz. Sketches that do not link the library retain the empty default hook.
Sleep modes
The STM32N6 provides Sleep (CPU clock stopped), Stop (system clock stopped, with a high and a low system voltage setting) and Standby (system powered down, with the backup domain retained). The library exposes them as follows.
| Method | Mode | Wake source | State retained | Notes |
|---|---|---|---|---|
sleepLight(ms) | WFI sleep | Any interrupt | Everything | USB remains connected |
sleepStop(ms) | Stop | RTC wake-up timer | SRAM and registers | Clocks restored automatically. USB disconnects |
standby(ms) | Standby | RTC | Backup domain only | Wake is a full reboot through the FSBL |
sleepStop() is called from loop() only; the scheduler is suspended for its duration. The core's 8 second watchdog runs through Stop, because the independent watchdog is clocked in the VDD domain, so sleeps are chunked (default 6000 ms, settable up to 6.5 s) with a watchdog feed at each internal wake. On the final wake the clock profile is reapplied and millis() is credited with the slept time. Timing uses the RTC's wake-up timer on the 32 kHz LSI oscillator at plus or minus 5%. The method returns false if a non-RTC interrupt ended the sleep early.
Clock profiles
| Profile | CPU | PLL1 | NPU PLLs | LTE UART |
|---|---|---|---|---|
PS_CLOCK_FULL | 800 MHz | On | Untouched | Works |
PS_CLOCK_CRUISE | 400 MHz | On | Off | Works |
PS_CLOCK_LOW | 100 MHz | On | Off | Works |
PS_CLOCK_ECO | 64 MHz (HSI) | Off | Off | Disabled |
Every profile leaves PLL4, the AXI bus, HCLK and APB unchanged, so XSPI, SDMMC, I2C, SPI, UART baud rates and the millisecond tick are unaffected by a profile change. Profiles may be switched at run time. setCpuDivider(d) gives finer control (800/d MHz). npuOff() leaves the NPU PLLs down in every profile and must not be called while a model is loaded.
Peripheral and sensor power
| Method | Effect |
|---|---|
sensorsSleep() | imuSleep(), magSleep() and micSleep() together |
imuSleep() | LSM6DSL accelerometer and gyroscope power-down, under 1 uA |
magSleep() | MMC5603NJ continuous mode off, about 1 uA. Single-shot reads still work |
micSleep() | MDF clock off, PDM clock pin driven low |
thermalPower(bool) | Lepton PWR_DWN_L and RESET_L. Off is the lowest state reachable; no rail switch exists |
usbOff() | TinyUSB soft disconnect and PHY supply off. One way until reboot |
periphOff(mask), periphOn(mask) | Clock gating for DCMIPP, CSI, I2C1, MDF1 and the camera. Register state is retained |
psramSleep(), norSleep() | Deep power down of the external memories |
npuRamOff() | Powers down the NPU's RAM |
PowerSave.begin() also turns off the purple run LED, which draws tens of milliamps.
One-shot camera
PowerSaveCam initialises only the VD66GY sensor and the DCMIPP pipes, without the encoder, the USB stream or the background tasks. capture() takes one RGB888 frame into a library-owned buffer. sensorSleep() and sensorWake() move the sensor between streaming and software standby; the carrier provides no power or reset GPIO, so full sensor power-off is not reachable. busSleep() and busWake() gate the DCMIPP and CSI clocks. Output dimensions may be reduced from the mode's native size. PowerSaveCam and Vision.begin() are mutually exclusive.
Measured currents
Measured with a Nordic PPK2 in ampere meter mode on the battery input, USB disconnected:
| Average current | Configuration |
|---|---|
| 52.6 mA | Camera, thermal and magnetometer every 10 s, awake at 800 MHz |
| 39.0 mA | Awake at PS_CLOCK_LOW |
| 29.9 mA | 15 s cycle |
| 24.4 mA | Idle WFI and sleep-mode peripheral clock gating |
| 22.8 mA | CSI D-PHY power-down and NOR deep power down |
| 19.9 mA | Camera only, no thermal, 10 s cycle |
At 22.8 mA the current divides into a floor of about 15 mA and a burst of about 8 mA. The floor is attributed to regulator quiescent current, the VD66GY software standby at 1 to 2 mA, and the STM32N6's Stop mode floor. The Lepton draws about 150 mW while powered and needs about 950 ms of boot plus 190 ms of VoSPI synchronisation per cycle; it does not boot across a Stop, so it is power cycled. Standby mode, with a full reboot per cycle, breaks even against Stop at cycle times of roughly 45 to 60 seconds or longer.
The library's README documents the PPK2 wiring, including four header pins that mark the awake, camera, thermal and auxiliary phases for correlation with the current trace.
External watchdog
The library drives a window watchdog such as the MikroE Watchdog Click (TI TPS3430) with an application-level heartbeat, so the supervisor monitors the sketch rather than the scheduler.
PowerSave.externalWatchdogArmPin(12); // SET1 held low disables the supervisor during boot
PowerSave.externalWatchdogBegin(13, 920, 1360, 1000);
PowerSave.externalWatchdogArm();Validated on hardware with the CWD strap floating: a 920 to 1360 ms window, kicked at 1000 ms, 126 consecutive kicks accepted and reset 1.4 to 1.9 s after kicks stop. Wider windows are set by a capacitor on CWD, following tWDU = 77.4 x C(uF) + 0.055 s.
A window watchdog faults on an early kick as well as a late one. A floating WDI input self-triggers on noise, so a disconnected wire causes a reset storm rather than a clean timeout; a 10k pull-down on WDI and a 2.2k pull-down on SET1 make disconnection survivable. The watchdog adds no measurable current at a 1 s kick.
Examples
SleepAndWake, under File > Examples > NeuroN6-Powersave, implements a full cycle: a VD66GY frame, a Lepton frame and a magnetometer temperature every 20 seconds, written to an SD card, with Stop mode between. WatchdogClickTest and WatchdogClickRecovery in extras/bench exercise the external watchdog.