Skip to content

Accelerometer-driven low-power mode (hardware, PCB only) - #47

Merged
thePunderWoman merged 3 commits into
mainfrom
accel-lowpower-mode
Sep 10, 2026
Merged

Accelerometer-driven low-power mode (hardware, PCB only)#47
thePunderWoman merged 3 commits into
mainfrom
accel-lowpower-mode

Conversation

@thePunderWoman

@thePunderWoman thePunderWoman commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

Hardware (commit 1):

  • Adds a QMA6100P accelerometer (I2C, shares the OLED bus) with a hardware motion/no-motion interrupt on GPIO46.
  • Moves the XBee's DTR line off its permanent GND tie onto GPIO42, enabling host-commanded pin-sleep.
  • Hand-authored the QMA6100P symbol + footprint — pad geometry pulled from JLCPCB/LCSC's own EasyEDA component data (LCSC C2887190).
  • Placed, routed, DRC- and ERC-clean.

Low-power mode firmware (commit 2):

  • Progressive-enhancement low-power mode: idle cascade through full -> dim OLED -> OLED off -> XBee sleep, each stage independently timed and capped by a configurable aggressiveness mode, plus an independent auto-poweroff timer that always applies regardless of mode.
  • 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).
  • Accelerometer driver configuring the QMA6100P's own ANY_MOT_INT hardware interrupt (non-latched, mapped to INT1/GPIO46) per the real register map in the datasheet.
  • New "Power Management" menu screen (mode + 4 timeouts) and NVS persistence.
  • Fixed a latent main-menu overflow bug this feature's new menu entry tipped over (8 items + title line exceeds the display's 8 lines) — 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.
  • 5% 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, so firmware is the last line of defense.
  • Countdown screen overrides the menu and any power-management tier, forces the OLED to full power, and sleeps the XBee immediately.
  • Battery indicator and status LED blink in lockstep; both suppressed while charging.
  • Boot-time check: if the battery is already at/below 5% the instant the device is turned on, shows "Battery Empty" for 3 seconds and cuts power immediately, before running a full boot.

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:

  • Physical continuity check of the QMA6100P footprint against a real part before fab (same outstanding step as the GuliKit hallstick footprint).
  • Real-hardware bring-up/tuning of the accelerometer's motion-sensitivity threshold (currently a best-effort placeholder from the preliminary datasheet).
  • Production file generation (BOM/gerbers/JLCPCB export).

Test plan

  • kicad-cli sch erc — 0 violations
  • DRC clean (user-verified in KiCad)
  • Placed and routed (user-verified in KiCad)
  • 230 native unit tests pass, coverage above threshold
  • Real ESP32-S3 firmware build succeeds
  • Physical continuity check against real QMA6100P part
  • On-hardware bring-up of accelerometer sensitivity + low-power mode + low-battery behavior

🤖 Generated with Claude Code

thePunderWoman and others added 3 commits September 8, 2026 22:55
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>
@thePunderWoman
thePunderWoman marked this pull request as ready for review September 10, 2026 01:51
@thePunderWoman
thePunderWoman merged commit 570c1b3 into main Sep 10, 2026
2 checks passed
@thePunderWoman
thePunderWoman deleted the accel-lowpower-mode branch September 10, 2026 01:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant