A 4x4 membrane keypad scan is us-timing-critical: firmware drives one row LOW and reads the columns back within the same loop pass, far faster than the browser<->QEMU websocket round trip, so the browser-side matrix simulation could never register a key on ESP32 boards. Worker: new 'matrix-keypad' sensor type (rows/cols GPIO lists, pressed key set). _on_dir_change/_on_pin_change recompute the column levels synchronously on the QEMU thread — the pinMode(OUTPUT) transition is the trigger on steady-state passes, since the row's output latch stays LOW and the digitalWrite fires no change callback. Async gpio_in writes to keypad-owned columns are ignored so the browser's generic matrix logic can't clobber them. Frontend: SimulatorCanvas attaches the keypad as a matrix-keypad sensor when every R/C pin resolves to an ESP32-family board GPIO, and streams the pressed-key set from the element's button-press/release events. |
||
|---|---|---|
| .. | ||
| api | ||
| core | ||
| database | ||
| mcp | ||
| models | ||
| schemas | ||
| services | ||
| utils | ||
| __init__.py | ||
| main.py | ||