From f29e964e91fe6aa7424c7a50a67f681d347ddf52 Mon Sep 17 00:00:00 2001 From: David Montero Date: Wed, 1 Apr 2026 18:47:15 +0200 Subject: [PATCH] fix: ESP32 Run button auto-compiles and recovers firmware after page refresh - handleRun now auto-compiles for ESP32/QEMU boards when no firmware is available (same behavior as AVR/RP2040 boards) - startBoard now reloads compiledProgram into the bridge if _pendingFirmware was lost (e.g. after a page refresh between compile and run) - Adds Esp32Bridge.hasFirmware() helper used by the store check Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/components/editor/EditorToolbar.tsx | 16 +++++++++++++++- frontend/src/simulation/Esp32Bridge.ts | 5 +++++ frontend/src/store/useSimulatorStore.ts | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/editor/EditorToolbar.tsx b/frontend/src/components/editor/EditorToolbar.tsx index 6d43dbd..ae41d92 100644 --- a/frontend/src/components/editor/EditorToolbar.tsx +++ b/frontend/src/components/editor/EditorToolbar.tsx @@ -164,8 +164,22 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi const board = boards.find((b) => b.id === activeBoardId); const isQemuBoard = board?.boardKind === 'raspberry-pi-3' || board?.boardKind === 'esp32' || board?.boardKind === 'esp32-s3'; - // QEMU boards don't need compilation + // QEMU boards: auto-compile if no firmware available yet if (isQemuBoard) { + if (!board?.compiledProgram || codeChangedSinceLastCompile) { + autoRunAfterCompile.current = true; + await handleCompile(); + const updatedBoard = useSimulatorStore.getState().boards.find((b) => b.id === activeBoardId); + if (autoRunAfterCompile.current && updatedBoard?.compiledProgram) { + autoRunAfterCompile.current = false; + trackRunSimulation(updatedBoard.boardKind); + startBoard(activeBoardId); + setMessage(null); + } else { + autoRunAfterCompile.current = false; + } + return; + } trackRunSimulation(board?.boardKind); startBoard(activeBoardId); setMessage(null); diff --git a/frontend/src/simulation/Esp32Bridge.ts b/frontend/src/simulation/Esp32Bridge.ts index a3fcc48..8152f38 100644 --- a/frontend/src/simulation/Esp32Bridge.ts +++ b/frontend/src/simulation/Esp32Bridge.ts @@ -240,6 +240,11 @@ export class Esp32Bridge { this._pendingSensors = sensors; } + /** Returns true if a firmware has been loaded and is ready to send. */ + hasFirmware(): boolean { + return this._pendingFirmware !== null && this._pendingFirmware !== ''; + } + /** * Load a compiled firmware (base64-encoded .bin) into the running ESP32. * If not yet connected, the firmware will be sent on next connect(). diff --git a/frontend/src/store/useSimulatorStore.ts b/frontend/src/store/useSimulatorStore.ts index 0962331..f0ce286 100644 --- a/frontend/src/store/useSimulatorStore.ts +++ b/frontend/src/store/useSimulatorStore.ts @@ -669,6 +669,12 @@ export const useSimulatorStore = create((set, get) => { ); esp32Bridge.wifiEnabled = hasWifi; + // Ensure firmware is loaded into the bridge (handles page-refresh case + // where _pendingFirmware is lost but compiledProgram is still in store). + if (!esp32Bridge.hasFirmware() && board.compiledProgram) { + esp32Bridge.loadFirmware(board.compiledProgram); + } + esp32Bridge.connect(); } } else {