velxio/backend
davidmonterocrespo24 adad446518 fix(esp32): LEDC signal IDs are 71-86 per ESP32 TRM, not 72-87
User report: on the solar-tracker project (5218f9e3) only one servo
moved and the log showed `ch=0 duty=X% gpio=12` (wrong — servoPan was
attached to GPIO 13) and `ch=1 ... gpio=-1` (servoTilt's channel
never resolved).

Root cause traced through the GPIO Matrix dump: the firmware does
exactly what the Arduino-ESP32 Servo library says — `ledcAttachPin(
13, 0)` writes signal 71 (LEDC_HS_SIG_OUT0) into `gpio_out_sel[13]`,
and `ledcAttachPin(12, 1)` writes signal 72 (LEDC_HS_SIG_OUT1) into
`gpio_out_sel[12]`. Per the ESP32 Technical Reference Manual section
4.11, Table 4-3:

    71 .. 78  →  LEDC HS channels 0..7
    79 .. 86  →  LEDC LS channels 0..7

The legacy worker code at esp32_worker.py:426 used the off-by-one
range `72 <= signal <= 87` with `ledc_ch = signal - 72`. The mistake
masked itself for single-servo projects because the 0x5000 duty
callback's channel index was internally consistent with the bogus
math, so the duty STILL reached the correctly-routed pin (just
labelled wrong). The new SignalRouter unit tests caught the
discrepancy the moment two servos drove distinct channels: signal
71 (HS_CH0, gpio 13) was REJECTED by the off-by-one filter and
signal 72 (HS_CH1, gpio 12) was misclassified as channel 0.

When I ported the legacy range into `esp32_signals.SIG_LEDC_HS_CH0_OUT_IDX`
the bug came along for the ride. Fix both modules:

* `backend/app/services/esp32_signals.py`: HS 71-78, LS 79-86.
* `frontend/src/simulation/esp32-signals.ts`: mirror.
* tests updated; 20 backend + 23 frontend pass.

After deploy the user's two servos will resolve to their declared
pins:

    ch=0  duty=X%  gpio=13   (servoPan, was wrongly emitting gpio=12)
    ch=1  duty=X%  gpio=12   (servoTilt, was wrongly emitting gpio=-1)

This is also why the multi-servo blink "patch" in commit 77bf897
appeared to help: with both pins ALIASED to the same channel via
the off-by-one, the broadcast fallback was the only thing producing
ANY movement on the second servo at all.
2026-05-17 05:42:52 +02:00
..
app fix(esp32): LEDC signal IDs are 71-86 per ESP32 TRM, not 72-87 2026-05-17 05:42:52 +02:00
scripts feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
sdk Add ESP32 chip demos and comprehensive tests for I2C, SPI, and UART interactions 2026-04-28 19:24:39 -03:00
tests Add unit tests for I2C slave devices, MCP tools, and WiFi/BLE status parser 2026-04-10 23:39:51 -03:00
.env.example chore(oss): drop dead auth/DB dependencies from OSS image 2026-05-14 17:06:27 -03:00
Dockerfile Add comprehensive tests for Cyw43Emulator functionality and lifecycle 2026-04-29 00:21:26 -03:00
debug_qemu.py feat: add documentation page and Arduino serial integration test 2026-03-12 08:17:29 -03:00
mcp_server.py feat: integrate MCP (Model Context Protocol) for agent compatibility 2026-03-11 15:29:55 +00:00
mcp_sse_server.py feat: integrate MCP (Model Context Protocol) for agent compatibility 2026-03-11 15:29:55 +00:00
requirements.txt feat(sim): boot_images module + Pi 3 emulation restored 2026-05-16 05:41:46 +02:00