mirror of
https://github.com/nacabaro/nacapet.git
synced 2026-06-05 14:02:53 +00:00
Add support with light sleep and step sensing
This commit is contained in:
parent
55749ba2a8
commit
0b5c56b5e3
@ -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
|
||||
@ -2,6 +2,5 @@
|
||||
#define ENERGY_H
|
||||
|
||||
void energy_startLightSleep();
|
||||
void energy_setUpLightSleep();
|
||||
|
||||
#endif
|
||||
@ -1,5 +1,7 @@
|
||||
#include "energy.h"
|
||||
#include <Arduino.h>
|
||||
#include <esp_sleep.h>
|
||||
#include <driver/gpio.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
39
src/main.cpp
39
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*) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user