Accelerometer-driven low-power mode (hardware, PCB only) - #47
Merged
Conversation
Adds a QMA6100P accelerometer (I2C, shared OLED bus) and enables host-commanded XBee pin-sleep, laying the hardware groundwork for a low-power mode: OLED off + XBee sleep after a short idle timeout (no buttons, no motion), full soft-latch power-off after a longer one. - QMA6100P chosen after checking JLCPCB's actual parts library: no candidate accelerometer is Basic-library, so it won on price, size, and standby current (500nA), which matters since it has to watch for motion through the whole low-power period. - Hand-authored symbol + footprint (no existing library part) — pad geometry pulled from JLCPCB/LCSC's own EasyEDA component data (LCSC C2887190), not estimated from the datasheet's low-res drawing. - New Accelerometer sheet, wired into the existing I2C bus and into a new GPIO46 (INT1) interrupt line so the MCU can light-sleep instead of polling for wake conditions. - XBee DTR moved off its permanent GND tie onto GPIO42 (SLEEP_RQ), so firmware can actually request/cancel pin-sleep instead of the radio being forced awake at all times. - Placed, routed, DRC- and ERC-clean. Firmware (driver, low-power state machine) and production file generation are follow-up work — this PR is hardware/schematic only. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Progressive-enhancement low-power mode: idle cascade through full -> dim OLED -> OLED off -> XBee sleep (each stage independently timed, capped by a configurable aggressiveness mode), plus an independent auto-poweroff timer that fires regardless of mode. - PowerManager (power_management.h/.cpp): pure, unit-tested state machine. Takes "did anything happen this tick" and current time, reports which tier to be in and a one-shot poweroff flag. No capability flags needed for progressive enhancement -- absence is handled naturally (no accelerometer ACK means motion never counts as activity; driving the XBee sleep pin on boards where it isn't wired is a harmless no-op). - Accelerometer (accelerometer.h/.cpp): QMA6100P driver configuring the chip's own ANY_MOT_INT hardware interrupt (non-latched, mapped to INT1/GPIO46) per the real register map in the datasheet. The motion-sensitivity threshold is a placeholder pending real-hardware bring-up tuning, same caveat as XbeeControl's AT command sequencing. - New "Power Management" menu screen (mode + 4 timeouts, same cycle-on-Enter pattern as Display Config) and NVS persistence (power_config_store.h/.cpp). - OLED gained setDimmed()/setPowerOn() for the dim/off tiers. - Fixed a latent main-menu overflow bug this feature's new menu entry would have tipped over: 8 items + a title line exceeds the display's 8 lines, so the last item would have silently never been drawn. renderMenuScreen() now scrolls to keep the selection visible. 214 native tests pass (97.6% line coverage); real ESP32-S3 firmware build succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Battery-safety layer on top of the low-power mode work: a warning blink at 10%, a 30-second safe-shutdown countdown at 5% (with debounce and recovery hysteresis so it can't flap on ADC noise), and a boot-time check that refuses to start a session at all if the battery is already past the critical line. - LowBatteryMonitor (low_battery.h/.cpp): pure, unit-tested state machine. 5% critical threshold is deliberately more conservative than battery.h's own linear model's "0%" (already only 3.0V) -- this design has no separate battery-protection/fuel-gauge IC (the bq25185 only charges), so firmware is the last line of defense, and needs margin for ADC noise, voltage sag under load, and the countdown itself continuing to draw power. - Countdown screen forces the OLED back to full power and sleeps the XBee immediately, overriding the menu and any power-management tier as the last thing touched each tick -- every bit of saved current matters during those 30 seconds. - Battery indicator (Display Config) and the status LED blink in lockstep at the same 2-second phase; both suppressed while charging. - Boot-time check: if the battery is already at/below 5% the instant the device is turned on, show "Battery Empty" for 3 seconds and cut power immediately -- no countdown, since no session has started yet. Also includes a small pending PCB/snips_controller.kicad_pro change from last night's KiCad session (an ERC exclusion removal), unrelated to this commit's content but not yet committed. 230 native tests pass; real ESP32-S3 firmware build succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardware (commit 1):
Low-power mode firmware (commit 2):
PowerManager(power_management.h/.cpp): pure, unit-tested state machine — no capability flags needed for progressive enhancement, absence is handled naturally (no accelerometer ACK means motion never counts as activity; driving the XBee sleep pin on boards where it isn't wired is a harmless no-op).Accelerometerdriver configuring the QMA6100P's own ANY_MOT_INT hardware interrupt (non-latched, mapped to INT1/GPIO46) per the real register map in the datasheet.renderMenuScreen()now scrolls to keep the selection visible.Battery safety firmware (commit 3):
LowBatteryMonitor(low_battery.h/.cpp): warning blink at 10%, a 30-second safe-shutdown countdown at 5% (debounced, with recovery hysteresis so it can't flap on ADC noise), immediately cancelled by charging.Part selection rationale, pin wiring, and decoupling details are in
PCB/GPIO_table.md's Accelerometer section.Status / what's NOT in this PR
Still to come as follow-up work:
Test plan
kicad-cli sch erc— 0 violations🤖 Generated with Claude Code