CapLog — Brownout‑Proof Event Logging for Tiny MCUs
Why bother?
Battery or vehicle‑powered sensors sometimes lose power unpredictably. You want to know what happened at shutdown (last sensor reading, error code, uptime) but you don’t have room for a big power supervisor or a real-time clock. CapLog is a minimal pattern for capturing a few bytes of useful state during a brownout using a supercapacitor, a diode, a GPIO interrupt, and a tiny append‑only flash routine.
What you need
- A tiny MCU with at least one GPIO interrupt and an SPI/I2C flash or internal flash you can write from code (AVR, ARM Cortex‑M0+, etc.).
- A supercapacitor (0.1F–1F depending on desired hold‑up time) and a low‑drop diode (Schottky).
- A resistor divider if you need to sense a higher supply voltage or a simple P‑channel MOSFET for power isolation in more advanced setups.
- Optionally: a small low‑ESR capacitor for decoupling and a write‑protected external flash if you prefer wear leveling off‑MCU.
How the circuit works (simple)
The trick is to keep the MCU powered long enough after the main supply collapses to grab a small record and write it to nonvolatile storage.
- Power the MCU from Vcc. Tie a diode from Vcc to the supercap so that when Vcc is present the cap charges through the diode but when Vcc falls the cap can still feed the MCU (the diode prevents back‑feeding other parts of the system).
- Monitor Vcc with a GPIO via a simple resistor divider (or use ADC if you prefer), configured to trigger an interrupt on falling edge or threshold crossing.
- When the interrupt fires, the ISR quickly samples the state you want saved and starts an append write to flash. The supercap supplies the MCU until the write completes. Choose cap and write size so the voltage drop during the write still stays above flash write margin.
Component sizing — a rough rule
Estimate energy needs from the write time and MCU current. For example:
- MCU active during flash write: 10–20 mA (tiny MCUs are often much lower).
- Flash write time for a small page: 5–20 ms per page (depends on memory).
- Reserve some headroom for worst case operations and flash block erase if you must erase during brownout (avoid erases during brownout — see firmware section).
Energy formula: E = 0.5 * C * (Vstart^2 - Vend^2). Solve for C given E = Vavg * I * t. Keep Vend above MCU brownout threshold and flash programming minimum voltage.
Firmware pattern
Keep it tiny and deterministic. The core rules:
- Use the GPIO falling edge (or ADC threshold) to trigger a single, short ISR that only stores pointers or copies a fixed small state to RAM, then sets a flag.
- In main loop, detect the flag and perform a short append write. Do not perform block erases during emergency — the system should maintain a pre‑erased pool of pages for emergency writes.
- Use checksums and a simple slot rotation so corrupted writes are detectable and you can recover the last valid entry on boot.
Practical rule: emergency code should touch as little code and as few peripherals as possible. No prints, no allocations, no dynamic behavior.
Example append routine (pseudo‑C)
This is intentionally small and style‑guiding rather than drop‑in for any platform.
volatile bool caplog_flag = false;
// ISR for Vcc falling
void VCC_ISR(void) {
// copy tiny state (4–16 bytes) into reserved RAM
memcpy(emergency_buffer, &state_snapshot, sizeof(emergency_buffer));
caplog_flag = true;
}
void loop(void) {
if (caplog_flag) {
disable_interrupts_except_vcc();
// write to next pre-erased flash page
flash_write(next_page_addr, emergency_buffer, sizeof(emergency_buffer));
flash_write(next_page_addr + sizeof(emergency_buffer), &crc, sizeof(crc));
increment_next_page();
caplog_flag = false;
enable_all_interrupts();
}
// normal operation...
}
Wear leveling and pre‑erased pool
Flash erase is expensive and should not be attempted when power is failing. The standard trick: during normal operation, maintain a ring of pre‑erased pages that the emergency routine can consume. Background task: when idle and Vcc is stable, erase the next block in the ring so it's ready. The emergency append only writes to a page already erased, minimizing time and energy.
Boot recovery
On power up, scan the ring for the most recent valid entry (use the CRC and a monotonically increasing sequence number). If you find a valid entry, process or upload it as part of diagnostics, then mark consumed pages as free for reuse in the ring.
Testing and debugging
- Start with the smallest possible record and measure write time with oscilloscope on the MCU Vcc pin.
- Drop Vcc abruptly and ensure the supercap holds Vcc above minimum for the whole write time. Tune cap value or reduce write size if not.
- Test with a sequence of brownouts to validate CRC and recovery; intentionally corrupt a page to verify detection logic.
Failure modes and mitigations
- If the cap can't hold Vcc long enough, reduce data written or move critical fields into a smaller emergency snapshot.
- If the diode drop is too high, use a low‑drop Schottky or a MOSFET ideal diode to reduce voltage loss.
- Watch out for inrush charging currents if the cap is large — they can disturb other supply rails. A series resistor or an NTC limits charging surge.
Wrap up
CapLog is intentionally simple: a capacitor buys you time, an interrupt grabs a tiny state, and pre‑erased flash pages preserve it. It doesn’t replace a proper power management IC or a hardware RTC, but for many low‑cost sensors and embedded devices it’s a pragmatic, private, and low‑component way to know what happened last.