Compare commits

...

4 Commits

8 changed files with 122 additions and 45 deletions

View File

@ -2,17 +2,17 @@
#define USE_HSPI_PORT #define USE_HSPI_PORT
#define ST7789_DRIVER // Full configuration option, define additional parameters below for this display #define ST7789_DRIVER // Full configuration option, define additional parameters below for this display
#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue #define TFT_RGB_ORDER TFT_BGR // Colour order Red-Green-Blue
#define TFT_WIDTH 240 // ST7789 240 x 240 and 240 x 320 #define TFT_WIDTH 240 // ST7789 240 x 240 and 240 x 320
#define TFT_HEIGHT 240 // ST7789 240 x 240 #define TFT_HEIGHT 240 // ST7789 240 x 240
#define TFT_BL 1 // LED back-light control pin #define TFT_BL 1 // LED back-light control pin
#define TFT_BACKLIGHT_ON HIGH // Level to turn ON back-light (HIGH or LOW) #define TFT_BACKLIGHT_ON HIGH // Level to turn ON back-light (HIGH or LOW)
#define TFT_MOSI 1 #define TFT_MOSI 11
#define TFT_MISO -1 #define TFT_MISO -1
#define TFT_SCLK 2 #define TFT_SCLK 12
#define TFT_DC 4 #define TFT_DC 5
#define TFT_RST 3 #define TFT_RST 6
#define TOUCH_CS -1 #define TOUCH_CS -1

View File

@ -8,23 +8,38 @@
; Please visit documentation for the other options and examples ; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
;[env:alt] [env:s3-full]
;platform = espressif32 platform = espressif32
;board = 4d_systems_esp32s3_gen4_r8n16 board = 4d_systems_esp32s3_gen4_r8n16
;framework = arduino framework = arduino
;lib_deps = TFT_eSPI, fbiego/ESP32Time@^2.0.6, electroniccats/MPU6050@^1.4.3 monitor_filters = esp32_exception_decoder
;monitor_filters = esp32_exception_decoder monitor_speed = 115200
;monitor_speed = 115200
;
;build_flags =
; -DBOARD_HAS_PSRAM
; -mfix-esp32-psram-cache-issue
; ; These ensure the N16R8 uses the fast Octal (OPI) mode
; -DARDUINO_USB_CDC_ON_BOOT=1
; -DDEV_UNIT
; -DDEBUG
[env:alt] lib_deps =
TFT_eSPI
fbiego/ESP32Time@^2.0.6
electroniccats/MPU6050@^1.4.3
; --- Hardware & Memory Topology ---
board_build.arduino.psram = enabled
board_upload.flash_size = 16MB
board_build.partitions = default_16MB.csv
; FIX 2: Explicitly matches the 'mode:DIO' your ROM is reporting
board_build.flash_mode = dio
board_build.arduino.memory_type = dio_opi
build_flags =
-DBOARD_HAS_PSRAM
; FIX 1: Forces all Serial.print logs to stay on the hardware UART port
-DARDUINO_USB_CDC_ON_BOOT=0
-DDEV_UNIT
-DDEBUG
upload_port = COM8
monitor_port = COM8
[env:s3-supermini]
platform = espressif32 platform = espressif32
board = esp32-s3-devkitc-1 board = esp32-s3-devkitc-1
framework = arduino framework = arduino
@ -45,3 +60,5 @@ build_flags =
; Ensure partition table fits 4MB ; Ensure partition table fits 4MB
board_build.partitions = default.csv board_build.partitions = default.csv
lib_deps = TFT_eSPI, fbiego/ESP32Time@^2.0.6, electroniccats/MPU6050@^1.4.3 lib_deps = TFT_eSPI, fbiego/ESP32Time@^2.0.6, electroniccats/MPU6050@^1.4.3
upload_port = COM5
monitor_port = COM5

View File

@ -40,9 +40,9 @@
// SPEAKER PINOUT // SPEAKER PINOUT
#define SPK_PIN 7 #define SPK_PIN 7
// MPU6050 PINOUT // I2C PINOUT
#define MPU_SCL_PIN 9 #define I2C_SCL_PIN 9
#define MPU_SDA_PIN 8 #define I2C_SDA_PIN 8
// SPECIAL SCREEN THAT OPENS WHEN TIMERS ARE DONE // SPECIAL SCREEN THAT OPENS WHEN TIMERS ARE DONE
// RECEIVES AN EXTRA PARAMETER (INTERRUPTKEY) // RECEIVES AN EXTRA PARAMETER (INTERRUPTKEY)
@ -211,4 +211,8 @@ extern struct CharacterData* charaData;
extern struct SpriteData mainCharacterSprites; extern struct SpriteData mainCharacterSprites;
extern bool isSamplingSteps;
extern uint64_t sampleStartTime;
extern uint16_t initialSteps;
#endif #endif

View File

@ -2,6 +2,5 @@
#define ENERGY_H #define ENERGY_H
void energy_startLightSleep(); void energy_startLightSleep();
void energy_setUpLightSleep();
#endif #endif

View File

@ -1,5 +1,7 @@
#include "energy.h" #include "energy.h"
#include <Arduino.h> #include <Arduino.h>
#include <esp_sleep.h>
#include <driver/gpio.h>
#include "defs/defs.h" #include "defs/defs.h"
#include "defs/chara_data.h" #include "defs/chara_data.h"
#include "defs/sprite_data.h" #include "defs/sprite_data.h"
@ -11,14 +13,27 @@
#define SLEEP_TIME_US 60000000ull // 60 seconds periodic wakeup #define SLEEP_TIME_US 60000000ull // 60 seconds periodic wakeup
void energy_setUpLightSleep() {
// Left as a placeholder for backward compatibility
}
void energy_startLightSleep() { void energy_startLightSleep() {
printf("[ENERGY] Entering light sleep...\n"); 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); esp_sleep_enable_timer_wakeup(SLEEP_TIME_US);
uint64_t mask = (1ULL << K1_PIN) | (1ULL << K2_PIN) | (1ULL << K3_PIN) | (1ULL << K4_PIN); 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); esp_sleep_enable_ext1_wakeup(mask, ESP_EXT1_WAKEUP_ANY_HIGH);
#endif #endif
// 2. Start light sleep (powers down CPU core and clocks, keeps RAM and state) digitalWrite(48, LOW);
esp_light_sleep_start(); 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(); esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
printf("[ENERGY] Woken up. Cause: %d\n", cause); printf("[ENERGY] Woken up. Cause: %d\n", cause);
// 4. Force immediate simulation update
runVpetTasks = true; runVpetTasks = true;
vpet_runVpetTasks(); vpet_runVpetTasks();
// 5. Evaluate the current character's state to see if any alert/event was triggered
if (cause == ESP_SLEEP_WAKEUP_TIMER) { if (cause == ESP_SLEEP_WAKEUP_TIMER) {
bool hasAlert = ( bool hasAlert = (
charaData[currentCharacter].hunger == 0 || charaData[currentCharacter].hunger == 0 ||
@ -53,8 +74,7 @@ void energy_startLightSleep() {
); );
if (hasAlert) { if (hasAlert) {
// Wake up display and backlight to notify the user printf("[ENERGY] Periodic wakeup triggered, maybe care mistake.\n");
printf("[ENERGY] Periodic wakeup triggered a critical alert! Waking up completely.\n");
digitalWrite(BL_PIN, HIGH); digitalWrite(BL_PIN, HIGH);
screenOff = false; screenOff = false;
inactive = false; inactive = false;
@ -62,16 +82,20 @@ void energy_startLightSleep() {
screenKey = TIMER_FINISHED_SCREEN; screenKey = TIMER_FINISHED_SCREEN;
} }
} else { } else {
// Background checkpoint save, then let the loop put the CPU back to sleep printf("[ENERGY] Periodic wake up triggered, no alerts. Sampling steps...\n");
printf("[ENERGY] Periodic simulation update successful. No alerts. Saving state...\n"); isSamplingSteps = true;
sampleStartTime = esp_timer_get_time();
initialSteps = stepCounter;
storage_saveState(); storage_saveState();
} }
} else if (cause == ESP_SLEEP_WAKEUP_EXT1) { } else if (cause == ESP_SLEEP_WAKEUP_EXT1) {
// Woken up by a user button press printf("[ENERGY] User button press detected.\n");
printf("[ENERGY] User button press detected. Restoring UI...\n");
digitalWrite(BL_PIN, HIGH); digitalWrite(BL_PIN, HIGH);
screenOff = false; screenOff = false;
inactive = false; inactive = false;
screenKey = MAIN_SCREEN; screenKey = MAIN_SCREEN;
} else {
// Fallback for other wake-up causes to prevent high-speed loop thrashing
delay(200);
} }
} }

View File

@ -64,16 +64,25 @@ uint8_t eggNumber = 0;
// Tasks // Tasks
TaskHandle_t secondLoop = NULL; TaskHandle_t secondLoop = NULL;
bool isSamplingSteps = false;
uint64_t sampleStartTime = 0;
uint16_t initialSteps = 0;
void loop2(); void loop2();
void secondCoreTask(void*); void secondCoreTask(void*);
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
while (!Serial) { }
//delay(10000); //delay(10000);
//Wire.begin(MPU_SDA_PIN, MPU_SCL_PIN); // I2C init before MPU6050 pinMode(48, OUTPUT);
//mpu.initialize(); digitalWrite(48, HIGH);
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); // I2C init before MPU6050
mpu.initialize();
tft_initDisplay(tft, TFT_BLACK); tft_initDisplay(tft, TFT_BLACK);
tft_initScreenBuffer(TFT_TRANSPARENT); tft_initScreenBuffer(TFT_TRANSPARENT);
@ -207,7 +216,7 @@ void loop() {
} }
if (screenKey == IDLE_SCREEN || screenKey == OFF_SCREEN) { if (screenKey == IDLE_SCREEN || screenKey == OFF_SCREEN) {
//steps_countSteps(); steps_countSteps();
} }
} }
@ -218,7 +227,29 @@ void loop2() {
getLocalTime(&timeInfo, 50); getLocalTime(&timeInfo, 50);
dayUnixTime = mktime(&timeInfo) % SECONDS_IN_DAY; 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*) { void secondCoreTask(void*) {

View File

@ -53,5 +53,7 @@ void menu_clearPoopScreen(
menuKey = -1; menuKey = -1;
charaData[currentCharacter].poopNumber = 0; charaData[currentCharacter].poopNumber = 0;
vTaskResume(secondLoop);
return; return;
} }

View File

@ -22,7 +22,7 @@ void steps_countSteps() {
float dyn = mag - gravity; float dyn = mag - gravity;
unsigned long now = esp_timer_get_time(); unsigned long now = esp_timer_get_time();
if (dyn > thresh && (now - lastStepTime) > 250000) { if (dyn > thresh && (now - lastStepTime) > 350000) {
stepCounter++; stepCounter++;
lastStepTime = now; lastStepTime = now;
} }