Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
965e794
Rename Network to WLEDNetwork to prevent clash
netmindz Aug 14, 2025
ba2b182
Update platformio.ini for V5
netmindz Aug 14, 2025
07ab6aa
Rename Network to WLEDNetwork to prevent clash
netmindz Aug 14, 2025
1de8c2e
Remove local copy of MQTT and disable for now in build
netmindz Aug 16, 2025
2c0259f
Rename Network to WLEDNetwork to prevent clash
netmindz Aug 16, 2025
03a9d9e
ledc changes for versions 2.X (based on ESP-IDF 4.4) to version 3.0 (…
netmindz Aug 16, 2025
bc19133
Update PlatformIO
netmindz Aug 16, 2025
e4815d1
Update PlatformIO
netmindz Aug 16, 2025
81c9225
Update PlatformIO
netmindz Aug 16, 2025
ec22c50
Update DMX Input for latest esp_dmx
netmindz Nov 8, 2025
68dff2d
mbedtls_sha1 workaround
netmindz Nov 8, 2025
7daada1
fix for esp32_eth
netmindz Nov 8, 2025
446c043
fix for esp32_eth
netmindz Nov 8, 2025
d4bafec
WLED_DISABLE_MQTT for 8266
netmindz Nov 8, 2025
2f8882e
WLED_DISABLE_INFRARED for 8266
netmindz Nov 8, 2025
5205110
mbedtls_sha1_shim.cpp not required for 8266
netmindz Nov 8, 2025
906d456
fix for pin usage logger
netmindz Nov 8, 2025
41878f0
WLED_DISABLE_INFRARED for 8266
netmindz Nov 8, 2025
44a483f
WLED_DISABLE_INFRARED for 8266
netmindz Nov 8, 2025
7a0325f
WLED_DISABLE_INFRARED for 8266
netmindz Nov 8, 2025
86679ed
ESP-IDF fix for PWM_fan.cpp
netmindz Nov 8, 2025
c5e2ec7
WLED_DISABLE_INFRARED for 8266
netmindz Nov 8, 2025
93821ef
disable usermods build for now
netmindz Nov 8, 2025
8cad34e
Merge branch 'main' into V5
netmindz Nov 8, 2025
ce84a57
NeoEsp32RmtHI does not support V5
netmindz Nov 8, 2025
2af23fc
AsyncTCP 3.4.7 does not support V5
netmindz Nov 8, 2025
51e1f4f
NeoEsp32RmtHI does not support V5
netmindz Nov 8, 2025
0653854
NeoEsp32RmtHI does not support V5
netmindz Nov 8, 2025
36eaca6
NeoEsp32RmtHI does not support V5
netmindz Nov 8, 2025
7c8b8fd
NeoPixelBus CORE3
netmindz Nov 8, 2025
d632cf8
improve esp32_dev env
netmindz Nov 8, 2025
b51e80f
Safety check: ensure multiWiFi is never empty to prevent crashes duri…
netmindz Nov 8, 2025
9f3e53a
disable 8266 builds for now
netmindz Nov 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/NeoESP32RmtHI/include/NeoEsp32RmtHIMethod.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#if false
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: remove once this has been updated for newer ESP-IDF

/*-------------------------------------------------------------------------
NeoPixel driver for ESP32 RMTs using High-priority Interrupt

Expand Down Expand Up @@ -467,3 +468,5 @@ typedef NeoEsp32RmtHI7Ws2805InvertedMethod NeoEsp32RmtHI7Ws2814InvertedMethod;
#endif // !defined(CONFIG_IDF_TARGET_ESP32C3)

#endif

#endif // NEOE_SP32_RMT_HI_METHODS_H
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: remove once this has been updated for newer ESP-IDF

6 changes: 5 additions & 1 deletion lib/NeoESP32RmtHI/src/NeoEsp32RmtHIMethod.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#if false
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: remove once this has been updated for newer ESP-IDF


/*-------------------------------------------------------------------------
NeoPixel library helper functions for Esp32.

Expand Down Expand Up @@ -504,4 +506,6 @@ esp_err_t NeoEsp32RmtHiMethodDriver::WaitForTxDone(rmt_channel_t channel, TickTy
return rv;
}

#endif
#endif
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: remove once this has been updated for newer ESP-IDF


#endif // ARDUINO_ARCH_ESP32
163 changes: 90 additions & 73 deletions platformio.ini

Large diffs are not rendered by default.

24 changes: 11 additions & 13 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile requirements.in
# pip-compile
#
ajsonrpc==1.2.0
# via platformio
anyio==4.8.0
anyio==4.10.0
# via starlette
bottle==0.13.2
bottle==0.13.4
# via platformio
certifi==2025.1.31
certifi==2025.8.3
# via requests
charset-normalizer==3.4.1
charset-normalizer==3.4.3
# via requests
click==8.1.8
click==8.1.7
# via
# platformio
# uvicorn
Expand All @@ -30,9 +30,9 @@ idna==3.10
# requests
marshmallow==3.26.1
# via platformio
packaging==24.2
packaging==25.0
# via marshmallow
platformio==6.1.17
platformio==6.1.18
# via -r requirements.in
pyelftools==0.32
# via platformio
Expand All @@ -44,15 +44,13 @@ semantic-version==2.10.0
# via platformio
sniffio==1.3.1
# via anyio
starlette==0.45.3
starlette==0.46.2
# via platformio
tabulate==0.9.0
# via platformio
typing-extensions==4.12.2
# via anyio
urllib3==2.5.0
# via requests
uvicorn==0.34.0
uvicorn==0.34.3
# via platformio
wsproto==1.2.0
# via platformio
7 changes: 5 additions & 2 deletions usermods/PWM_fan/PWM_fan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,14 @@ class PWMFanUsermod : public Usermod {
if (pwmChannel == 255) { //no more free LEDC channels
deinitPWMfan(); return;
}
// configure LED PWM functionalitites
// configure LED PWM functionalitites - ESP-IDF 5.x API
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
ledcAttach(pwmPin, 25000, 8); // New API: ledcAttach(pin, freq, resolution)
#else
ledcSetup(pwmChannel, 25000, 8);
// attach the channel to the GPIO to be controlled
ledcAttachPin(pwmPin, pwmChannel);
#endif
#endif
DEBUG_PRINTLN(F("Fan PWM sucessfully initialized."));
}

Expand Down
2 changes: 1 addition & 1 deletion usermods/ST7789_display/ST7789_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class St7789DisplayUsermod : public Usermod {

// Check if values which are shown on display changed from the last time.
if ((((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) ||
(knownIp != (apActive ? IPAddress(4, 3, 2, 1) : Network.localIP())) ||
(knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WLEDNetwork.localIP())) ||
(knownBrightness != bri) ||
(knownEffectSpeed != strip.getMainSegment().speed) ||
(knownEffectIntensity != strip.getMainSegment().intensity) ||
Expand Down
6 changes: 3 additions & 3 deletions usermods/quinled-an-penta/quinled-an-penta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ class QuinLEDAnPentaUsermod : public Usermod

bool oledCheckForNetworkChanges()
{
if (lastKnownNetworkConnected != Network.isConnected() || lastKnownIp != Network.localIP()
if (lastKnownNetworkConnected != WLEDNetwork.isConnected() || lastKnownIp != WLEDNetwork.localIP()
|| lastKnownWiFiConnected != WiFi.isConnected() || lastKnownSsid != WiFi.SSID()
|| lastKnownApActive != apActive || lastKnownApSsid != apSSID || lastKnownApPass != apPass || lastKnownApChannel != apChannel) {
lastKnownNetworkConnected = Network.isConnected();
lastKnownIp = Network.localIP();
lastKnownNetworkConnected = WLEDNetwork.isConnected();
lastKnownIp = WLEDNetwork.localIP();
lastKnownWiFiConnected = WiFi.isConnected();
lastKnownSsid = WiFi.SSID();
lastKnownApActive = apActive;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ void FourLineDisplayUsermod::setup() {
// interfaces here
void FourLineDisplayUsermod::connected() {
knownSsid = WiFi.SSID(); //apActive ? apSSID : WiFi.SSID(); //apActive ? WiFi.softAPSSID() :
knownIp = Network.localIP(); //apActive ? IPAddress(4, 3, 2, 1) : Network.localIP();
knownIp = WLEDNetwork.localIP(); //apActive ? IPAddress(4, 3, 2, 1) : WLEDNetwork.localIP();
networkOverlay(PSTR("NETWORK INFO"),7000);
}

Expand Down
9 changes: 4 additions & 5 deletions wled00/bus_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#if !(defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
#define LEDC_MUTEX_LOCK() do {} while (xSemaphoreTake(_ledc_sys_lock, portMAX_DELAY) != pdPASS)
#define LEDC_MUTEX_UNLOCK() xSemaphoreGive(_ledc_sys_lock)
extern xSemaphoreHandle _ledc_sys_lock;
extern SemaphoreHandle_t _ledc_sys_lock;
#else
#define LEDC_MUTEX_LOCK()
#define LEDC_MUTEX_UNLOCK()
Expand Down Expand Up @@ -467,8 +467,7 @@ BusPwm::BusPwm(const BusConfig &bc)
pinMode(_pins[i], OUTPUT);
#else
unsigned channel = _ledcStart + i;
ledcSetup(channel, _frequency, _depth - (dithering*4)); // with dithering _frequency doesn't really matter as resolution is 8 bit
ledcAttachPin(_pins[i], channel);
ledcAttach(_pins[i], _frequency, _depth - (dithering*4));
// LEDC timer reset credit @dedehai
uint8_t group = (channel / 8), timer = ((channel / 2) % 4); // same fromula as in ledcSetup()
ledc_timer_rst((ledc_mode_t)group, (ledc_timer_t)timer); // reset timer so all timers are almost in sync (for phase shift)
Expand Down Expand Up @@ -632,7 +631,7 @@ void BusPwm::deallocatePins() {
#ifdef ESP8266
digitalWrite(_pins[i], LOW); //turn off PWM interrupt
#else
if (_ledcStart < WLED_MAX_ANALOG_CHANNELS) ledcDetachPin(_pins[i]);
if (_ledcStart < WLED_MAX_ANALOG_CHANNELS) ledcDetach(_pins[i]);
#endif
}
#ifdef ARDUINO_ARCH_ESP32
Expand Down Expand Up @@ -754,7 +753,7 @@ size_t BusNetwork::getPins(uint8_t* pinArray) const {
#ifdef ARDUINO_ARCH_ESP32
void BusNetwork::resolveHostname() {
static unsigned long nextResolve = 0;
if (Network.isConnected() && millis() > nextResolve && _hostname.length() > 0) {
if (WLEDNetwork.isConnected() && millis() > nextResolve && _hostname.length() > 0) {
nextResolve = millis() + 600000; // resolve only every 10 minutes
IPAddress clnt;
if (strlen(cmDNS) > 0) clnt = MDNS.queryHost(_hostname);
Expand Down
14 changes: 14 additions & 0 deletions wled00/bus_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@
//#define NPB_CONF_4STEP_CADENCE
#include "NeoPixelBus.h"

// --- temporary shim for NeoPixelBus CORE3 / RMT driver_v2 ------------------
#if __has_include(<NeoPixelBus.h>)
#define NeoEsp32RmtNWs2812xMethod NeoEsp32RmtXWs2812xMethod
#define NeoEsp32RmtNSk6812Method NeoEsp32RmtXSk6812Method
#define NeoEsp32RmtN800KbpsMethod NeoEsp32RmtX800KbpsMethod
#define NeoEsp32RmtN400KbpsMethod NeoEsp32RmtX400KbpsMethod
#define NeoEsp32RmtNTm1814Method NeoEsp32RmtXTm1814Method
#define NeoEsp32RmtNTm1829Method NeoEsp32RmtXTm1829Method
#define NeoEsp32RmtNTm1914Method NeoEsp32RmtXTm1914Method
#define NeoEsp32RmtNApa106Method NeoEsp32RmtXApa106Method
#define NeoEsp32RmtNWs2805Method NeoEsp32RmtXWs2805Method
#endif
// ---------------------------------------------------------------------------

//Hardware SPI Pins
#define P_8266_HS_MOSI 13
#define P_8266_HS_CLK 14
Expand Down
106 changes: 60 additions & 46 deletions wled00/dmx_input.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "wled.h"

#ifdef WLED_ENABLE_DMX_INPUT
#pragma message "DMX physical input driver enabled"

#ifdef ESP8266
#error DMX input is only supported on ESP32
Expand All @@ -9,8 +10,8 @@
#include "dmx_input.h"
#include <rdm/responder.h>

void rdmPersonalityChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
void *context)
void rdmPersonalityChangedCb(dmx_port_t dmxPort, rdm_header_t *request_header,
rdm_header_t *response_header, void *context)
{
DMXInput *dmx = static_cast<DMXInput *>(context);

Expand All @@ -19,16 +20,16 @@ void rdmPersonalityChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
return;
}

if (header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
if (response_header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
const uint8_t personality = dmx_get_current_personality(dmx->inputPortNum);
DMXMode = std::min(DMX_MODE_PRESET, std::max(DMX_MODE_SINGLE_RGB, int(personality)));
configNeedsWrite = true;
DEBUG_PRINTF("DMX personality changed to to: %d\n", DMXMode);
}
}

void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
void *context)
void rdmAddressChangedCb(dmx_port_t dmxPort, rdm_header_t *request_header,
rdm_header_t *response_header, void *context)
{
DMXInput *dmx = static_cast<DMXInput *>(context);

Expand All @@ -37,7 +38,7 @@ void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
return;
}

if (header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
if (response_header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
const uint16_t addr = dmx_get_start_address(dmx->inputPortNum);
DMXAddress = std::min(512, int(addr));
configNeedsWrite = true;
Expand All @@ -47,46 +48,53 @@ void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,

static dmx_config_t createConfig()
{
dmx_config_t config;
config.pd_size = 255;
config.dmx_start_address = DMXAddress;
dmx_config_t config = DMX_CONFIG_DEFAULT;
config.model_id = 0;
config.product_category = RDM_PRODUCT_CATEGORY_FIXTURE;
config.software_version_id = VERSION;
strcpy(config.device_label, "WLED_MM");

const std::string versionString = "WLED_V" + std::to_string(VERSION);
strncpy(config.software_version_label, versionString.c_str(), 32);
config.software_version_label[32] = '\0'; // zero termination in case versionString string was longer than 32 chars

config.personalities[0].description = "SINGLE_RGB";
config.personalities[0].footprint = 3;
config.personalities[1].description = "SINGLE_DRGB";
config.personalities[1].footprint = 4;
config.personalities[2].description = "EFFECT";
config.personalities[2].footprint = 15;
config.personalities[3].description = "MULTIPLE_RGB";
config.personalities[3].footprint = std::min(512, int(strip.getLengthTotal()) * 3);
config.personalities[4].description = "MULTIPLE_DRGB";
config.personalities[4].footprint = std::min(512, int(strip.getLengthTotal()) * 3 + 1);
config.personalities[5].description = "MULTIPLE_RGBW";
config.personalities[5].footprint = std::min(512, int(strip.getLengthTotal()) * 4);
config.personalities[6].description = "EFFECT_W";
config.personalities[6].footprint = 18;
config.personalities[7].description = "EFFECT_SEGMENT";
config.personalities[7].footprint = std::min(512, strip.getSegmentsNum() * 15);
config.personalities[8].description = "EFFECT_SEGMENT_W";
config.personalities[8].footprint = std::min(512, strip.getSegmentsNum() * 18);
config.personalities[9].description = "PRESET";
config.personalities[9].footprint = 1;

config.personality_count = 10;
// rdm personalities are numbered from 1, thus we can just set the DMXMode directly.
config.current_personality = DMXMode;
config.software_version_label = versionString.c_str();

return config;
}

static dmx_personality_t personalities[10];

static void createPersonalities()
{
// Initialize personalities array
strncpy(personalities[0].description, "SINGLE_RGB", 32);
personalities[0].footprint = 3;

strncpy(personalities[1].description, "SINGLE_DRGB", 32);
personalities[1].footprint = 4;

strncpy(personalities[2].description, "EFFECT", 32);
personalities[2].footprint = 15;

strncpy(personalities[3].description, "MULTIPLE_RGB", 32);
personalities[3].footprint = std::min(512, int(strip.getLengthTotal()) * 3);

strncpy(personalities[4].description, "MULTIPLE_DRGB", 32);
personalities[4].footprint = std::min(512, int(strip.getLengthTotal()) * 3 + 1);

strncpy(personalities[5].description, "MULTIPLE_RGBW", 32);
personalities[5].footprint = std::min(512, int(strip.getLengthTotal()) * 4);

strncpy(personalities[6].description, "EFFECT_W", 32);
personalities[6].footprint = 18;

strncpy(personalities[7].description, "EFFECT_SEGMENT", 32);
personalities[7].footprint = std::min(512, strip.getSegmentsNum() * 15);

strncpy(personalities[8].description, "EFFECT_SEGMENT_W", 32);
personalities[8].footprint = std::min(512, strip.getSegmentsNum() * 18);

strncpy(personalities[9].description, "PRESET", 32);
personalities[9].footprint = 1;
}

void dmxReceiverTask(void *context)
{
DMXInput *instance = static_cast<DMXInput *>(context);
Expand All @@ -103,10 +111,11 @@ void dmxReceiverTask(void *context)

bool DMXInput::installDriver()
{

const auto config = createConfig();
createPersonalities();

DEBUG_PRINTF("DMX port: %u\n", inputPortNum);
if (!dmx_driver_install(inputPortNum, &config, DMX_INTR_FLAGS_DEFAULT)) {
if (!dmx_driver_install(inputPortNum, &config, personalities, 10)) {
DEBUG_PRINTF("Error: Failed to install dmx driver\n");
return false;
}
Expand All @@ -116,8 +125,14 @@ bool DMXInput::installDriver()
DEBUG_PRINTF("DMX enable pin is: %u\n", enPin);
dmx_set_pin(inputPortNum, txPin, rxPin, enPin);

// Set initial DMX start address and personality
dmx_set_start_address(inputPortNum, DMXAddress);
dmx_set_current_personality(inputPortNum, DMXMode);

// Register RDM callbacks for start address and personality changes
rdm_register_dmx_start_address(inputPortNum, rdmAddressChangedCb, this);
rdm_register_dmx_personality(inputPortNum, rdmPersonalityChangedCb, this);
rdm_register_dmx_personality(inputPortNum, 10, rdmPersonalityChangedCb, this);

initialized = true;
return true;
}
Expand Down Expand Up @@ -151,9 +166,9 @@ void DMXInput::init(uint8_t rxPin, uint8_t txPin, uint8_t enPin, uint8_t inputPo
const bool pinsAllocated = PinManager::allocateMultiplePins(pins, 3, PinOwner::DMX_INPUT);
if (!pinsAllocated) {
DEBUG_PRINTF("DMXInput: Error: Failed to allocate pins for DMX_INPUT. Pins already in use:\n");
DEBUG_PRINTF("rx in use by: %s\n", PinManager::getPinOwner(rxPin));
DEBUG_PRINTF("tx in use by: %s\n", PinManager::getPinOwner(txPin));
DEBUG_PRINTF("en in use by: %s\n", PinManager::getPinOwner(enPin));
DEBUG_PRINTF("rx in use by: %hhd\n", PinManager::getPinOwner(rxPin));
DEBUG_PRINTF("tx in use by: %hhd\n", PinManager::getPinOwner(txPin));
DEBUG_PRINTF("en in use by: %hhd\n", PinManager::getPinOwner(enPin));
return;
}

Expand Down Expand Up @@ -247,12 +262,11 @@ void DMXInput::enable()

bool DMXInput::isIdentifyOn() const
{

uint8_t identify = 0;
bool identify = false;
const bool gotIdentify = rdm_get_identify_device(inputPortNum, &identify);
// gotIdentify should never be false because it is a default parameter in rdm
// but just in case we check for it anyway
return bool(identify) && gotIdentify;
return identify && gotIdentify;
}

void DMXInput::checkAndUpdateConfig()
Expand Down
Loading
Loading