From f6f6f43cc209ea5482ddbd92733842704cc7c9d9 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Fri, 8 May 2026 16:32:12 -0300 Subject: [PATCH] feat(esp32): velxio_compat.h shim for arduino-esp32 3.x APIs on 2.0.17 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A user reported the LEDC PWM RGB example failing to compile. The sketch calls ledcAttach(pin, freq, resolution) — the one-shot API added in arduino-esp32 3.x. Our toolchain image pins arduino-esp32 to 2.0.17 (matched to ESP-IDF 4.4.7 + the lcgamboa QEMU ROM), where the API is the older two-step ledcSetup + ledcAttachPin pair. Sketches written against 3.x docs hit "ledcAttach was not declared in this scope". Bumping arduino-esp32 to 3.x means moving to ESP-IDF 5.x, which may break our QEMU fork. Cheaper fix: ship a compat shim header in the ESP-IDF project template that defines ledcAttach + ledcAttachChannel in terms of the 2.x API, gated on `!defined(ledcAttach)` so it disappears the day we bump. espidf_compiler.py now injects #include "velxio_compat.h" right after Arduino.h whether the user explicitly included Arduino.h or we prepended it ourselves. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../esp-idf-template/main/velxio_compat.h | 30 +++++++++++++++++++ backend/app/services/espidf_compiler.py | 16 ++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 backend/app/services/esp-idf-template/main/velxio_compat.h diff --git a/backend/app/services/esp-idf-template/main/velxio_compat.h b/backend/app/services/esp-idf-template/main/velxio_compat.h new file mode 100644 index 00000000..0cca12da --- /dev/null +++ b/backend/app/services/esp-idf-template/main/velxio_compat.h @@ -0,0 +1,30 @@ +#ifndef VELXIO_COMPAT_H +#define VELXIO_COMPAT_H + +// Compatibility shims for sketches written against arduino-esp32 3.x running +// on the toolchain pinned to 2.0.17. Only kept until we bump the toolchain. +// +// ledcAttach / ledcAttachChannel were added in 3.x. Map them onto the 2.x +// ledcSetup + ledcAttachPin pair so the sketch compiles unchanged. + +#if defined(ARDUINO_ARCH_ESP32) && !defined(ledcAttach) +#include "Arduino.h" + +static inline bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) { + static uint8_t _velxio_next_channel = 0; + if (_velxio_next_channel >= 16) return false; + uint8_t ch = _velxio_next_channel++; + ledcSetup(ch, freq, resolution); + ledcAttachPin(pin, ch); + return true; +} + +static inline bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel) { + if (channel >= 16) return false; + ledcSetup(channel, freq, resolution); + ledcAttachPin(pin, channel); + return true; +} +#endif + +#endif // VELXIO_COMPAT_H diff --git a/backend/app/services/espidf_compiler.py b/backend/app/services/espidf_compiler.py index 0633fe31..b0e55cb3 100644 --- a/backend/app/services/espidf_compiler.py +++ b/backend/app/services/espidf_compiler.py @@ -846,9 +846,21 @@ class ESPIDFCompiler: if self.has_arduino: # Arduino-as-component mode: copy sketch as .cpp sketch_cpp = project_dir / 'main' / 'sketch.ino.cpp' - # Prepend Arduino.h if not already included + # Prepend Arduino.h + velxio_compat.h if not already included. + # velxio_compat.h shims arduino-esp32 3.x APIs (ledcAttach, …) + # onto the 2.0.17 toolchain we currently pin. See + # esp-idf-template/main/velxio_compat.h. if '#include' not in main_content or 'Arduino.h' not in main_content: - main_content = '#include "Arduino.h"\n' + main_content + main_content = ( + '#include "Arduino.h"\n' + '#include "velxio_compat.h"\n' + main_content + ) + else: + main_content = main_content.replace( + '#include "Arduino.h"', + '#include "Arduino.h"\n#include "velxio_compat.h"', + 1, + ) sketch_cpp.write_text(main_content, encoding='utf-8') # Copy additional files (.h, .cpp)