fix(ui): inicializar spr.setTextFont(1) y spr.setFreeFont(NULL) para evitar excepcion LoadStoreError al renderizar fuente 1

This commit is contained in:
Sebastián Nieto 2026-09-22 00:19:57 -03:00
parent 9b7249b321
commit bd62cb991d
2 changed files with 25 additions and 3 deletions

View file

@ -1363,13 +1363,18 @@ inline void renderPage1ToSprite(TFT_eSprite &s, int x_offset, int y_slice, int s
// 100% Flicker-Free Double-Buffered Mobile Slide Transition // 100% Flicker-Free Double-Buffered Mobile Slide Transition
// Safe 25KB sprite with pixel-perfect clipping and smooth ease-out pacing // Safe 25KB sprite with pixel-perfect clipping and smooth ease-out pacing
inline void animateSlideTransition(bool swipeLeft) { inline void animateSlideTransition(bool swipeLeft) {
Serial.println(">>> [DB] animateSlideTransition ENTER");
const int slice_h = 40; // 320x40 = only 25KB (100% safe, leaves 70KB+ free for Bluetooth) const int slice_h = 40; // 320x40 = only 25KB (100% safe, leaves 70KB+ free for Bluetooth)
const uint8_t numSlices = 240 / slice_h; // exactly 6 slices const uint8_t numSlices = 240 / slice_h; // exactly 6 slices
TFT_eSprite spr(&tft); TFT_eSprite spr(&tft);
if (spr.createSprite(320, slice_h) == nullptr) { if (spr.createSprite(320, slice_h) == nullptr) {
Serial.println(">>> [DB] spr.createSprite FAILED (nullptr)!");
return; // Safety fallback return; // Safety fallback
} }
spr.setTextFont(1); // CRITICAL: initializes textfont=1 and clears uninitialized gfxFont=NULL
spr.setFreeFont(NULL); // CRITICAL: prevents crash in textWidth() when drawing Font 1 on stack sprite
Serial.printf(">>> [DB] Sprite created OK. Heap: %u, MaxAlloc: %u\n", ESP.getFreeHeap(), ESP.getMaxAllocHeap());
const uint8_t FRAMES = 28; const uint8_t FRAMES = 28;
// High-density sine ease-out deceleration over 28 frames: // High-density sine ease-out deceleration over 28 frames:
@ -1381,6 +1386,9 @@ inline void animateSlideTransition(bool swipeLeft) {
}; };
for (uint8_t f = 0; f < FRAMES; f++) { for (uint8_t f = 0; f < FRAMES; f++) {
if (f == 0 || f == FRAMES / 2 || f == FRAMES - 1) {
Serial.printf(">>> [DB] Frame %d / %d (heap: %u)\n", f, FRAMES, ESP.getFreeHeap());
}
int16_t shift = step_shifts[f]; int16_t shift = step_shifts[f];
int16_t splitX = swipeLeft ? (320 - shift) : shift; int16_t splitX = swipeLeft ? (320 - shift) : shift;
int16_t x0 = swipeLeft ? (-shift) : (shift - 320); int16_t x0 = swipeLeft ? (-shift) : (shift - 320);
@ -1422,15 +1430,14 @@ inline void animateSlideTransition(bool swipeLeft) {
} }
spr.deleteSprite(); // Release the 25KB spr.deleteSprite(); // Release the 25KB
Serial.printf(">>> [DB] animateSlideTransition LEAVE (heap: %u)\n", ESP.getFreeHeap());
} }
/*-------------------*/ /*-------------------*/
// initialize display // initialize display
void initScreen() { void initScreen() {
terminalLineCount = 0; terminalLineCount = 0;
#ifdef SERIAL_DEBUG Serial.printf(">>> [DB] initScreen START: page=%d, fullScreenCell=%d, heap=%u\n", currentScreenPage, fullScreenCell, ESP.getFreeHeap());
Serial.printf("Display init, fullScreenCell = %d\n", fullScreenCell);
#endif
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
pidList[i] = pidConfig[pidInCell[i]][2]; // get PID to list pidList[i] = pidConfig[pidInCell[i]][2]; // get PID to list
pidReadSkip[i] = pidConfig[pidInCell[i]][6].toInt(); // get read skip pidReadSkip[i] = pidConfig[pidInCell[i]][6].toInt(); // get read skip
@ -1444,10 +1451,13 @@ void initScreen() {
old_data[i] = -999; old_data[i] = -999;
} }
if (fullScreenCell >= 0 && fullScreenCell < 4) { if (fullScreenCell >= 0 && fullScreenCell < 4) {
Serial.println(">>> [DB] initScreen: drawing fullScreenMeter");
fullScreenMeter(fullScreenCell, pidInCell[fullScreenCell]); fullScreenMeter(fullScreenCell, pidInCell[fullScreenCell]);
} else if (currentScreenPage == 1) { } else if (currentScreenPage == 1) {
Serial.println(">>> [DB] initScreen: drawing drawTriTempScreen(0)");
drawTriTempScreen(0); drawTriTempScreen(0);
} else { } else {
Serial.println(">>> [DB] initScreen: drawing Page 0 quadrants");
tft.fillScreen(TFT_BLACK); // clear screen tft.fillScreen(TFT_BLACK); // clear screen
for (uint8_t c = 0; c < 4; c++) { for (uint8_t c = 0; c < 4; c++) {
uint8_t pid = pidInCell[c]; uint8_t pid = pidInCell[c];
@ -1462,6 +1472,7 @@ void initScreen() {
badgeEcoDrawn = false; badgeEcoDrawn = false;
updateEcoBadge(true); updateEcoBadge(true);
} }
Serial.printf(">>> [DB] initScreen FINISHED OK (heap: %u)\n", ESP.getFreeHeap());
} }
/*-------------------------------*/ /*-------------------------------*/

View file

@ -651,19 +651,29 @@ void loop() {
if (waitingForDoubleTap && (millis() - firstTapReleaseTime <= 400)) { if (waitingForDoubleTap && (millis() - firstTapReleaseTime <= 400)) {
// DOUBLE CLICK DETECTED: Switch Screen Page! // DOUBLE CLICK DETECTED: Switch Screen Page!
waitingForDoubleTap = false; waitingForDoubleTap = false;
Serial.println(">>> [DB] DOUBLE CLICK DETECTED!");
Serial.printf(">>> [DB] Free heap: %u, MaxAlloc: %u\n", ESP.getFreeHeap(), ESP.getMaxAllocHeap());
if (fullScreenCell != -1) { if (fullScreenCell != -1) {
fullScreenCell = -1; fullScreenCell = -1;
} }
if (currentScreenPage == 0) { if (currentScreenPage == 0) {
Serial.println(">>> [DB] Transitioning Page 0 -> 1");
animateSlideTransition(true); animateSlideTransition(true);
Serial.println(">>> [DB] Slide done. Setting currentScreenPage = 1");
currentScreenPage = 1; currentScreenPage = 1;
Serial.println(">>> [DB] Calling initScreen()...");
initScreen(); initScreen();
Serial.println(">>> [DB] initScreen() completed.");
} else { } else {
Serial.println(">>> [DB] Transitioning Page 1 -> 0");
animateSlideTransition(false); animateSlideTransition(false);
Serial.println(">>> [DB] Slide done. Setting currentScreenPage = 0");
currentScreenPage = 0; currentScreenPage = 0;
Serial.println(">>> [DB] Calling initScreen()...");
initScreen(); initScreen();
Serial.println(">>> [DB] initScreen() completed.");
} }
waitForTouchRelease(); waitForTouchRelease();
lastActivityTime = millis(); lastActivityTime = millis();
@ -673,6 +683,7 @@ void loop() {
firstTapReleaseTime = millis(); firstTapReleaseTime = millis();
firstTapX = lastTouchX; firstTapX = lastTouchX;
firstTapY = lastTouchY; firstTapY = lastTouchY;
Serial.printf(">>> [DB] First tap (X=%d, Y=%d), waiting for 2nd tap...\n", firstTapX, firstTapY);
} }
} }
} }