diff --git a/src/defs/defs.h b/src/defs/defs.h index ce9e527..6fc408f 100644 --- a/src/defs/defs.h +++ b/src/defs/defs.h @@ -40,9 +40,9 @@ // SPEAKER PINOUT #define SPK_PIN 7 -// MPU6050 PINOUT -#define MPU_SCL_PIN 9 -#define MPU_SDA_PIN 8 +// I2C PINOUT +#define I2C_SCL_PIN 9 +#define I2C_SDA_PIN 8 // SPECIAL SCREEN THAT OPENS WHEN TIMERS ARE DONE // RECEIVES AN EXTRA PARAMETER (INTERRUPTKEY) @@ -211,4 +211,8 @@ extern struct CharacterData* charaData; extern struct SpriteData mainCharacterSprites; +extern bool isSamplingSteps; +extern uint64_t sampleStartTime; +extern uint16_t initialSteps; + #endif \ No newline at end of file diff --git a/src/energy/energy.h b/src/energy/energy.h index bd92d56..4ec7ae1 100644 --- a/src/energy/energy.h +++ b/src/energy/energy.h @@ -2,6 +2,5 @@ #define ENERGY_H void energy_startLightSleep(); -void energy_setUpLightSleep(); #endif \ No newline at end of file diff --git a/src/energy/light_sleep.cpp b/src/energy/light_sleep.cpp index 19b80f5..1427a6f 100644 --- a/src/energy/light_sleep.cpp +++ b/src/energy/light_sleep.cpp @@ -1,5 +1,7 @@ #include "energy.h" #include +#include +#include #include "defs/defs.h" #include "defs/chara_data.h" #include "defs/sprite_data.h" @@ -11,14 +13,27 @@ #define SLEEP_TIME_US 60000000ull // 60 seconds periodic wakeup -void energy_setUpLightSleep() { - // Left as a placeholder for backward compatibility -} - void energy_startLightSleep() { printf("[ENERGY] Entering light sleep...\n"); - // 1. Configure wake-up sources + // Keep RTC peripherals powered on during sleep so internal pullups/pulldowns stay active + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + // EXT1 wakeup uses the RTC IO subsystem. We must explicitly configure the RTC pull resistors + // so the pins do not float and cause immediate wake-ups. + // NOTE: We must initialize the pins as RTC GPIOs using rtc_gpio_init() first! + #if BUTTON_MODE == INPUT_PULLUP + rtc_gpio_init((gpio_num_t)K1_PIN); rtc_gpio_pullup_en((gpio_num_t)K1_PIN); rtc_gpio_pulldown_dis((gpio_num_t)K1_PIN); + rtc_gpio_init((gpio_num_t)K2_PIN); rtc_gpio_pullup_en((gpio_num_t)K2_PIN); rtc_gpio_pulldown_dis((gpio_num_t)K2_PIN); + rtc_gpio_init((gpio_num_t)K3_PIN); rtc_gpio_pullup_en((gpio_num_t)K3_PIN); rtc_gpio_pulldown_dis((gpio_num_t)K3_PIN); + rtc_gpio_init((gpio_num_t)K4_PIN); rtc_gpio_pullup_en((gpio_num_t)K4_PIN); rtc_gpio_pulldown_dis((gpio_num_t)K4_PIN); + #else + rtc_gpio_init((gpio_num_t)K1_PIN); rtc_gpio_pulldown_en((gpio_num_t)K1_PIN); rtc_gpio_pullup_dis((gpio_num_t)K1_PIN); + rtc_gpio_init((gpio_num_t)K2_PIN); rtc_gpio_pulldown_en((gpio_num_t)K2_PIN); rtc_gpio_pullup_dis((gpio_num_t)K2_PIN); + rtc_gpio_init((gpio_num_t)K3_PIN); rtc_gpio_pulldown_en((gpio_num_t)K3_PIN); rtc_gpio_pullup_dis((gpio_num_t)K3_PIN); + rtc_gpio_init((gpio_num_t)K4_PIN); rtc_gpio_pulldown_en((gpio_num_t)K4_PIN); rtc_gpio_pullup_dis((gpio_num_t)K4_PIN); + #endif + esp_sleep_enable_timer_wakeup(SLEEP_TIME_US); uint64_t mask = (1ULL << K1_PIN) | (1ULL << K2_PIN) | (1ULL << K3_PIN) | (1ULL << K4_PIN); @@ -32,18 +47,24 @@ void energy_startLightSleep() { esp_sleep_enable_ext1_wakeup(mask, ESP_EXT1_WAKEUP_ANY_HIGH); #endif - // 2. Start light sleep (powers down CPU core and clocks, keeps RAM and state) + digitalWrite(48, LOW); + esp_light_sleep_start(); - // 3. Woken up! Let's check why + digitalWrite(48, HIGH); + + // Release the pins from RTC control after waking up so digitalRead works normally + rtc_gpio_deinit((gpio_num_t)K1_PIN); + rtc_gpio_deinit((gpio_num_t)K2_PIN); + rtc_gpio_deinit((gpio_num_t)K3_PIN); + rtc_gpio_deinit((gpio_num_t)K4_PIN); + esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); printf("[ENERGY] Woken up. Cause: %d\n", cause); - // 4. Force immediate simulation update runVpetTasks = true; vpet_runVpetTasks(); - // 5. Evaluate the current character's state to see if any alert/event was triggered if (cause == ESP_SLEEP_WAKEUP_TIMER) { bool hasAlert = ( charaData[currentCharacter].hunger == 0 || @@ -53,8 +74,7 @@ void energy_startLightSleep() { ); if (hasAlert) { - // Wake up display and backlight to notify the user - printf("[ENERGY] Periodic wakeup triggered a critical alert! Waking up completely.\n"); + printf("[ENERGY] Periodic wakeup triggered, maybe care mistake.\n"); digitalWrite(BL_PIN, HIGH); screenOff = false; inactive = false; @@ -62,16 +82,20 @@ void energy_startLightSleep() { screenKey = TIMER_FINISHED_SCREEN; } } else { - // Background checkpoint save, then let the loop put the CPU back to sleep - printf("[ENERGY] Periodic simulation update successful. No alerts. Saving state...\n"); + printf("[ENERGY] Periodic wake up triggered, no alerts. Sampling steps...\n"); + isSamplingSteps = true; + sampleStartTime = esp_timer_get_time(); + initialSteps = stepCounter; storage_saveState(); } } else if (cause == ESP_SLEEP_WAKEUP_EXT1) { - // Woken up by a user button press - printf("[ENERGY] User button press detected. Restoring UI...\n"); + printf("[ENERGY] User button press detected.\n"); digitalWrite(BL_PIN, HIGH); screenOff = false; inactive = false; screenKey = MAIN_SCREEN; + } else { + // Fallback for other wake-up causes to prevent high-speed loop thrashing + delay(200); } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 65529e5..604a8aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -64,16 +64,25 @@ uint8_t eggNumber = 0; // Tasks TaskHandle_t secondLoop = NULL; +bool isSamplingSteps = false; +uint64_t sampleStartTime = 0; +uint16_t initialSteps = 0; + void loop2(); void secondCoreTask(void*); void setup() { Serial.begin(115200); + while (!Serial) { } + //delay(10000); - //Wire.begin(MPU_SDA_PIN, MPU_SCL_PIN); // I2C init before MPU6050 - //mpu.initialize(); + pinMode(48, OUTPUT); + digitalWrite(48, HIGH); + + Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); // I2C init before MPU6050 + mpu.initialize(); tft_initDisplay(tft, TFT_BLACK); tft_initScreenBuffer(TFT_TRANSPARENT); @@ -207,7 +216,7 @@ void loop() { } if (screenKey == IDLE_SCREEN || screenKey == OFF_SCREEN) { - //steps_countSteps(); + steps_countSteps(); } } @@ -218,7 +227,29 @@ void loop2() { getLocalTime(&timeInfo, 50); dayUnixTime = mktime(&timeInfo) % SECONDS_IN_DAY; - if (screenOff) { energy_startLightSleep(); } + if (screenOff) { + if (isSamplingSteps) { + uint64_t currentTime = esp_timer_get_time(); + + if ((currentTime - sampleStartTime) > 10000000) { + isSamplingSteps = false; + + uint16_t sampledSteps = stepCounter - initialSteps; + + uint16_t approximatedSteps = sampledSteps * 6; + + stepCounter += approximatedSteps; + + printf("[STEPS] Sampled %d steps in 10s, added %d approximated steps for sleep period.\n", sampledSteps, approximatedSteps); + + energy_startLightSleep(); + } + } else { + energy_startLightSleep(); + } + } else { + isSamplingSteps = false; + } } void secondCoreTask(void*) { diff --git a/src/vpet/steps/steps.cpp b/src/vpet/steps/steps.cpp index e3170c6..3eccc0b 100644 --- a/src/vpet/steps/steps.cpp +++ b/src/vpet/steps/steps.cpp @@ -22,7 +22,7 @@ void steps_countSteps() { float dyn = mag - gravity; unsigned long now = esp_timer_get_time(); - if (dyn > thresh && (now - lastStepTime) > 250000) { + if (dyn > thresh && (now - lastStepTime) > 350000) { stepCounter++; lastStepTime = now; }