Improve sleep and add button waking

This commit is contained in:
2026-03-24 23:29:34 +01:00
parent 0fc38a5e1b
commit 14e9c96f55
2 changed files with 34 additions and 6 deletions
+32 -4
View File
@@ -66,6 +66,11 @@ static void imuInt1ISR() {
imuWakeFlag = true; imuWakeFlag = true;
} }
static volatile bool btnWakeFlag = false;
static void btnWakeISR() {
btnWakeFlag = true;
}
// Arm wakeup interrupt // Arm wakeup interrupt
static void armWakeupInterrupt() { static void armWakeupInterrupt() {
lsmWrite(SLP_WAKE_UP_DUR, (uint8_t)((SLEEP_WAKEUP_DUR & 0x03) << 4)); lsmWrite(SLP_WAKE_UP_DUR, (uint8_t)((SLEEP_WAKEUP_DUR & 0x03) << 4));
@@ -127,6 +132,15 @@ static void enterImuLP() {
armWakeupInterrupt(); armWakeupInterrupt();
// Arm button wake interrupt
#if BTN_LEFT_PIN != BTN_PIN_NONE
btnWakeFlag = false;
attachInterrupt(digitalPinToInterrupt(BTN_LEFT_PIN), btnWakeISR, FALLING);
#endif
// Turn off all LEDs for sleep
digitalWrite(LED_RED, HIGH); digitalWrite(LED_GREEN, HIGH); digitalWrite(LED_BLUE, HIGH);
lpEnteredMs = millis(); lpEnteredMs = millis();
sleepStage = SLEEP_IMU_LP; sleepStage = SLEEP_IMU_LP;
Serial.print("[SLEEP] IMU LP entered - idle for "); Serial.print("[SLEEP] IMU LP entered - idle for ");
@@ -153,9 +167,9 @@ static void enterDeepSleep() {
Serial.println("[SLEEP] Deep sleep - WFE on INT1"); Serial.println("[SLEEP] Deep sleep - WFE on INT1");
Serial.flush(); Serial.flush();
digitalWrite(LED_RED, LOW); delay(80); digitalWrite(LED_RED, HIGH); digitalWrite(LED_RED, HIGH); digitalWrite(LED_GREEN, HIGH); digitalWrite(LED_BLUE, HIGH);
while (!imuWakeFlag) { while (!imuWakeFlag && !btnWakeFlag) {
(void)lsmRead(SLP_WAKE_UP_SRC); (void)lsmRead(SLP_WAKE_UP_SRC);
sd_app_evt_wait(); sd_app_evt_wait();
} }
@@ -172,6 +186,11 @@ void sleepManagerWakeIMU() {
disarmWakeupInterrupt(); disarmWakeupInterrupt();
// Detach button wake interrupt — normal polling takes over
#if BTN_LEFT_PIN != BTN_PIN_NONE
detachInterrupt(digitalPinToInterrupt(BTN_LEFT_PIN));
#endif
// Only recalibrate if gyro was off long enough for thermal drift to accumulate, // Only recalibrate if gyro was off long enough for thermal drift to accumulate,
// or if waking from full deep sleep. Short LP naps reuse the existing bias. // or if waking from full deep sleep. Short LP naps reuse the existing bias.
unsigned long lpDuration = millis() - lpEnteredMs; unsigned long lpDuration = millis() - lpEnteredMs;
@@ -225,14 +244,23 @@ void sleepManagerInit() {
// Returns true → caller must skip IMU reads this iteration. // Returns true → caller must skip IMU reads this iteration.
bool sleepManagerUpdate(unsigned long nowMs, bool idle, bool bleConnected) { bool sleepManagerUpdate(unsigned long nowMs, bool idle, bool bleConnected) {
// ISR wakeup // ISR wakeup (IMU motion or button press)
bool woke = false;
if (imuWakeFlag) { if (imuWakeFlag) {
imuWakeFlag = false; imuWakeFlag = false;
Serial.print("[SLEEP] INT1 fired - stage="); Serial.println((int)sleepStage); Serial.print("[SLEEP] INT1 fired - stage="); Serial.println((int)sleepStage);
woke = true;
}
if (btnWakeFlag) {
btnWakeFlag = false;
Serial.print("[SLEEP] Button fired - stage="); Serial.println((int)sleepStage);
woke = true;
}
if (woke) {
if (sleepStage == SLEEP_DEEP || sleepStage == SLEEP_IMU_LP) { if (sleepStage == SLEEP_DEEP || sleepStage == SLEEP_IMU_LP) {
sleepManagerWakeIMU(); sleepManagerWakeIMU();
} else { } else {
(void)lsmRead(SLP_WAKE_UP_SRC); // normal-mode edge, clear latch only (void)lsmRead(SLP_WAKE_UP_SRC);
} }
} }
+2 -2
View File
@@ -11,12 +11,12 @@
// LSM6DS3 wakeup threshold: 1 LSB = 7.8 mg at ±2 g FS (±2g range). // LSM6DS3 wakeup threshold: 1 LSB = 7.8 mg at ±2 g FS (±2g range).
#ifndef SLEEP_WAKEUP_THS #ifndef SLEEP_WAKEUP_THS
#define SLEEP_WAKEUP_THS 16 // 063 #define SLEEP_WAKEUP_THS 6 // 063
#endif #endif
// Number of consecutive 26 Hz samples that must exceed the threshold. // Number of consecutive 26 Hz samples that must exceed the threshold.
#ifndef SLEEP_WAKEUP_DUR #ifndef SLEEP_WAKEUP_DUR
#define SLEEP_WAKEUP_DUR 2 // 03 #define SLEEP_WAKEUP_DUR 1 // 03
#endif #endif
// GPIO pin connected to LSM6DS3 INT1. // GPIO pin connected to LSM6DS3 INT1.