diff --git a/platformio.ini b/platformio.ini
index 29949d33c0..1645a52727 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -122,6 +122,7 @@ build_flags =
-D DECODE_LG=true
-DWLED_USE_MY_CONFIG
-D WLED_PS_DONT_REPLACE_FX ; PS replacement FX are purely a flash memory saving feature, do not replace classic FX until we run out of flash
+ -D WLED_ENABLE_DMX
build_unflags =
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index 97b48c4ab6..4268c70a2f 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -607,6 +607,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
tdd = if_live[F("timeout")] | -1;
if (tdd >= 0) realtimeTimeoutMs = tdd * 100;
+#ifdef WLED_ENABLE_DMX
+ CJSON(dmxOutputPin, if_live_dmx[F("dmxOutputPin")]);
+#endif
#ifdef WLED_ENABLE_DMX_INPUT
CJSON(dmxInputTransmitPin, if_live_dmx[F("inputRxPin")]);
CJSON(dmxInputReceivePin, if_live_dmx[F("inputTxPin")]);
@@ -1133,6 +1136,9 @@ void serializeConfig(JsonObject root) {
if_live_dmx[F("addr")] = DMXAddress;
if_live_dmx[F("dss")] = DMXSegmentSpacing;
if_live_dmx["mode"] = DMXMode;
+ #ifdef WLED_ENABLE_DMX
+ if_live_dmx[F("dmxOutputPin")] = dmxOutputPin;
+ #endif
#ifdef WLED_ENABLE_DMX_INPUT
if_live_dmx[F("inputRxPin")] = dmxInputTransmitPin;
if_live_dmx[F("inputTxPin")] = dmxInputReceivePin;
diff --git a/wled00/const.h b/wled00/const.h
index 95e69d855b..aac2c232a6 100644
--- a/wled00/const.h
+++ b/wled00/const.h
@@ -650,13 +650,8 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
// Defaults pins, type and counts to configure LED output
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3)
- #ifdef WLED_ENABLE_DMX
- #define DEFAULT_LED_PIN 1
- #warning "Compiling with DMX. The default LED pin has been changed to pin 1."
- #else
#define DEFAULT_LED_PIN 2 // GPIO2 (D4) on Wemos D1 mini compatible boards, safe to use on any board
- #endif
-#else
+ #else
#if defined(WLED_USE_ETHERNET)
#define DEFAULT_LED_PIN 4 // GPIO4 seems to be a "safe bet" for all known ethernet boards (issue #5155)
//#warning "Compiling with Ethernet support. The default LED pin has been changed to pin 4."
diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm
index 43baaf6718..97937f70b3 100644
--- a/wled00/data/settings_sync.htm
+++ b/wled00/data/settings_sync.htm
@@ -50,7 +50,10 @@
}
function hideDMXInput(){gId("dmxInput").style.display="none";}
function hideNoDMXInput(){gId("dmxInputOff").style.display="none";}
- function hideNoDMXOutput(){gId("dmxOnOffOutput").style.display="none";}
+ function hideNoDMXOutput(){
+ gId("dmxOnOffOutput").style.display="none";
+ gId("dmxOutput").style.display="inline";
+ }
@@ -179,7 +182,11 @@ Wired DMX Input Pins
DMX TX: DI
DMX Enable: RE+DE
DMX Port:
-
+
+
+
Wired DMX Output Pin
+ DMX TX:
+
This firmware build does not include DMX Input support.
diff --git a/wled00/dmx_input.cpp b/wled00/dmx_input.cpp
index 83ab606688..6ab1d4af33 100644
--- a/wled00/dmx_input.cpp
+++ b/wled00/dmx_input.cpp
@@ -134,14 +134,6 @@ void DMXInput::init(uint8_t rxPin, uint8_t txPin, uint8_t enPin, uint8_t inputPo
// }
#endif
- if (inputPortNum <= (SOC_UART_NUM - 1) && inputPortNum > 0) {
- this->inputPortNum = inputPortNum;
- }
- else {
- DEBUG_PRINTF("DMXInput: Error: invalid inputPortNum: %d\n", inputPortNum);
- return;
- }
-
if (rxPin > 0 && enPin > 0 && txPin > 0) {
const managed_pin_type pins[] = {
@@ -156,6 +148,15 @@ void DMXInput::init(uint8_t rxPin, uint8_t txPin, uint8_t enPin, uint8_t inputPo
DEBUG_PRINTF("en in use by: %s\n", PinManager::getPinOwner(enPin));
return;
}
+ if (inputPortNum <= (SOC_UART_NUM - 1) && inputPortNum > 0) {
+ this->inputPortNum = inputPortNum;
+ }
+ else {
+ DEBUG_PRINTF("DMXInput: Error: invalid inputPortNum: %d, default to 1\n", inputPortNum);
+ this->inputPortNum = 1;
+ return;
+ }
+
this->rxPin = rxPin;
this->txPin = txPin;
diff --git a/wled00/dmx_output.cpp b/wled00/dmx_output.cpp
index eace2145e6..8e9fc541ee 100644
--- a/wled00/dmx_output.cpp
+++ b/wled00/dmx_output.cpp
@@ -1,13 +1,11 @@
#include "wled.h"
-
+#include "dmx_output.h"
/*
- * Support for DMX output via serial (e.g. MAX485).
- * Change the output pin in src/dependencies/ESPDMX.cpp, if needed (ESP8266)
- * Change the output pin in src/dependencies/SparkFunDMX.cpp, if needed (ESP32)
+ * Support for DMX output via serial (e.g. MAX485).
* ESP8266 Library from:
* https://github.com/Rickgg/ESP-Dmx
* ESP32 Library from:
- * https://github.com/sparkfun/SparkFunDMX
+ * https://github.com/someweisguy/esp_dmx
*/
#ifdef WLED_ENABLE_DMX
@@ -68,13 +66,42 @@ void handleDMXOutput()
dmx.update(); // update the DMX bus
}
-void initDMXOutput() {
- #if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
- dmx.init(512); // initialize with bus length
- #else
- dmx.initWrite(512); // initialize with bus length
- #endif
+void initDMXOutput(int outputPin) {
+ if (outputPin < 1) return;
+ const bool pinAllocated = PinManager::allocatePin(outputPin, true, PinOwner::DMX);
+ if (!pinAllocated) {
+ DEBUG_PRINTF("DMXOutput: Error: Failed to allocate pin for DMX_OUTPUT. Pin already in use:\n");
+ DEBUG_PRINTF("In use by: %s\n", PinManager::getPinOwner(outputPin));
+ return;
+ }
+ DEBUG_PRINTF("DMXOutput: init: pin %d\n", outputPin);
+ dmx.init(outputPin); // set output pin and initialize DMX output
+}
+
+#if !defined(ESP8266)
+void DMXOutput::init(uint8_t outputPin) {
+ dmx_config_t config = DMX_CONFIG_DEFAULT;
+ const bool installOk = dmx_driver_install(dmxPort, &config, DMX_INTR_FLAGS_DEFAULT);
+ if (!installOk) {
+ DEBUG_PRINTF("DMXOutput: Error: Failed to install dmx driver\n");
+ return;
+ }
+ const bool setPin = dmx_set_pin(dmxPort, outputPin, -1, -1);
+ if (!setPin) {
+ DEBUG_PRINTF("DMXOutput: Error: Failed to set DMX output pin\n");
+ return;
+ }
}
+void DMXOutput::write(uint8_t channel, uint8_t value) {
+ dmxdata[channel] = value;
+}
+void DMXOutput::update() {
+ dmx_write(dmxPort, dmxdata, DMX_PACKET_SIZE);
+ dmx_send(dmxPort, DMX_PACKET_SIZE);
+}
+#endif
+
+
#else
void initDMXOutput(){}
void handleDMXOutput() {}
diff --git a/wled00/dmx_output.h b/wled00/dmx_output.h
new file mode 100644
index 0000000000..e292634cb3
--- /dev/null
+++ b/wled00/dmx_output.h
@@ -0,0 +1,33 @@
+//
+// Created by will on 1/10/26.
+//
+
+#ifndef DMX_OUTPUT_H
+#define DMX_OUTPUT_H
+
+#if defined(ESP8266)
+#include "src/dependencies/dmx/ESPDMX.h"
+#else
+#include
+/**
+ * Support for DMX Output via serial (e.g. max485) on ESP32
+ * ESP32 Library from:
+ * https://github.com/someweisguy/esp_dmx
+ */
+class DMXOutput
+{
+public:
+ void init(uint8_t outputPin);
+ void write(uint8_t channel, uint8_t value);
+ void update();
+private:
+ byte dmxdata[DMX_PACKET_SIZE];
+ /* Next, lets decide which DMX port to use. The ESP32 has either 2 or 3 ports.
+Port 0 is typically used to transmit serial data back to your Serial Monitor,
+so we shouldn't use that port. Lets use port 1! */
+ dmx_port_t dmxPort = 1;
+};
+#endif
+
+
+#endif //DMX_OUTPUT_H
diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h
index 67958314b4..86722a7c05 100644
--- a/wled00/fcn_declare.h
+++ b/wled00/fcn_declare.h
@@ -90,7 +90,7 @@ typedef struct WiFiConfig {
} wifi_config;
//dmx_output.cpp
-void initDMXOutput();
+void initDMXOutput(int outputPin);
void handleDMXOutput();
//dmx_input.cpp
diff --git a/wled00/pin_manager.h b/wled00/pin_manager.h
index 5f774bb47d..265180edc2 100644
--- a/wled00/pin_manager.h
+++ b/wled00/pin_manager.h
@@ -43,11 +43,12 @@ enum struct PinOwner : uint8_t {
Relay = 0x87, // 'Rly' == Relay pin from configuration
SPI_RAM = 0x88, // 'SpiR' == SPI RAM
DebugOut = 0x89, // 'Dbg' == debug output always IO1
- DMX = 0x8A, // 'DMX' == hard-coded to IO2
+ DMX = 0x8A, // 'DMX' == DMX output via serial
HW_I2C = 0x8B, // 'I2C' == hardware I2C pins (4&5 on ESP8266, 21&22 on ESP32)
HW_SPI = 0x8C, // 'SPI' == hardware (V)SPI pins (13,14&15 on ESP8266, 5,18&23 on ESP32)
DMX_INPUT = 0x8D, // 'DMX_INPUT' == DMX input via serial
HUB75 = 0x8E, // 'Hub75' == Hub75 driver
+ DMX_OUTPUT = 0x8F, // 'DMX_OUTPUT' == DMX output via serial
// Use UserMod IDs from const.h here
UM_Unspecified = USERMOD_ID_UNSPECIFIED, // 0x01
UM_Example = USERMOD_ID_EXAMPLE, // 0x02 // Usermod "usermod_v2_example.h"
diff --git a/wled00/set.cpp b/wled00/set.cpp
index 3c6c72b7b3..a1e29840cc 100644
--- a/wled00/set.cpp
+++ b/wled00/set.cpp
@@ -473,7 +473,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
arlsDisableGammaCorrection = request->hasArg(F("RG"));
t = request->arg(F("WO")).toInt();
if (t >= -255 && t <= 255) arlsOffset = t;
-
+#ifdef WLED_ENABLE_DMX
+ dmxOutputPin = request->arg(F("IDMO")).toInt();
+#endif
#ifdef WLED_ENABLE_DMX_INPUT
dmxInputTransmitPin = request->arg(F("IDMT")).toInt();
dmxInputReceivePin = request->arg(F("IDMR")).toInt();
diff --git a/wled00/src/dependencies/dmx/ESPDMX.cpp b/wled00/src/dependencies/dmx/ESPDMX.cpp
index a80cad71c8..e6c9193d30 100644
--- a/wled00/src/dependencies/dmx/ESPDMX.cpp
+++ b/wled00/src/dependencies/dmx/ESPDMX.cpp
@@ -18,24 +18,8 @@
#include "ESPDMX.h"
-
-#define dmxMaxChannel 512
-#define defaultMax 32
-
-#define DMXSPEED 250000
-#define DMXFORMAT SERIAL_8N2
-#define BREAKSPEED 83333
-#define BREAKFORMAT SERIAL_8N1
-
-bool dmxStarted = false;
-int sendPin = 2; //default on ESP8266
-
-//DMX value array and size. Entry 0 will hold startbyte, so we need 512+1 elements
-uint8_t dmxDataStore[dmxMaxChannel+1] = {};
-int channelSize;
-
-
-void DMXESPSerial::init() {
+void DMXESPSerial::init(int sendPin) {
+ this->sendPin = sendPin;
channelSize = defaultMax;
Serial1.begin(DMXSPEED);
@@ -43,37 +27,10 @@ void DMXESPSerial::init() {
dmxStarted = true;
}
-// Set up the DMX-Protocol
-void DMXESPSerial::init(int chanQuant) {
-
- if (chanQuant > dmxMaxChannel || chanQuant <= 0) {
- chanQuant = defaultMax;
- }
-
- channelSize = chanQuant;
-
- Serial1.begin(DMXSPEED);
- pinMode(sendPin, OUTPUT);
- dmxStarted = true;
-}
-
-// Function to read DMX data
-uint8_t DMXESPSerial::read(int Channel) {
- if (dmxStarted == false) init();
-
- if (Channel < 1) Channel = 1;
- if (Channel > dmxMaxChannel) Channel = dmxMaxChannel;
- return(dmxDataStore[Channel]);
-}
-
// Function to send DMX data
void DMXESPSerial::write(int Channel, uint8_t value) {
- if (dmxStarted == false) init();
-
if (Channel < 1) Channel = 1;
if (Channel > channelSize) Channel = channelSize;
- if (value < 0) value = 0;
- if (value > 255) value = 255;
dmxDataStore[Channel] = value;
}
@@ -85,8 +42,6 @@ void DMXESPSerial::end() {
}
void DMXESPSerial::update() {
- if (dmxStarted == false) init();
-
//Send break
digitalWrite(sendPin, HIGH);
Serial1.begin(BREAKSPEED, BREAKFORMAT);
diff --git a/wled00/src/dependencies/dmx/ESPDMX.h b/wled00/src/dependencies/dmx/ESPDMX.h
index 4585bdd26f..f3f5a42df5 100644
--- a/wled00/src/dependencies/dmx/ESPDMX.h
+++ b/wled00/src/dependencies/dmx/ESPDMX.h
@@ -16,16 +16,32 @@
#ifndef ESPDMX_h
#define ESPDMX_h
+
+#define dmxMaxChannel 512
+#define defaultMax 32
+
+#define DMXSPEED 250000
+#define DMXFORMAT SERIAL_8N2
+#define BREAKSPEED 83333
+#define BREAKFORMAT SERIAL_8N1
+
// ---- Methods ----
class DMXESPSerial {
public:
- void init();
- void init(int MaxChan);
+ void init(int sendPin);
uint8_t read(int Channel);
void write(int channel, uint8_t value);
void update();
void end();
+private:
+ int sendPin;
+ bool dmxStarted = false;
+
+ //DMX value array and size. Entry 0 will hold startbyte, so we need 512+1 elements
+ uint8_t dmxDataStore[dmxMaxChannel+1] = {};
+ int channelSize;
+
};
#endif
diff --git a/wled00/src/dependencies/dmx/SparkFunDMX.cpp b/wled00/src/dependencies/dmx/SparkFunDMX.cpp
deleted file mode 100644
index 064b9ff620..0000000000
--- a/wled00/src/dependencies/dmx/SparkFunDMX.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/******************************************************************************
-SparkFunDMX.h
-Arduino Library for the SparkFun ESP32 LED to DMX Shield
-Andy England @ SparkFun Electronics
-7/22/2019
-
-Development environment specifics:
-Arduino IDE 1.6.4
-
-This code is released under the [MIT License](http://opensource.org/licenses/MIT).
-Please review the LICENSE.md file included with this example. If you have any questions
-or concerns with licensing, please contact techsupport@sparkfun.com.
-Distributed as-is; no warranty is given.
-******************************************************************************/
-
-/* ----- LIBRARIES ----- */
-#if defined(ARDUINO_ARCH_ESP32)
-
-#include
-#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2)
-
-#include "SparkFunDMX.h"
-#include
-
-#define dmxMaxChannel 512
-#define defaultMax 32
-
-#define DMXSPEED 250000
-#define DMXFORMAT SERIAL_8N2
-#define BREAKSPEED 83333
-#define BREAKFORMAT SERIAL_8N1
-
-static const int enablePin = -1; // disable the enable pin because it is not needed
-static const int rxPin = -1; // disable the receiving pin because it is not needed - softhack007: Pin=-1 means "use default" not "disable"
-static const int txPin = 2; // transmit DMX data over this pin (default is pin 2)
-
-//DMX value array and size. Entry 0 will hold startbyte, so we need 512+1 elements
-static uint8_t dmxData[dmxMaxChannel+1] = { 0 };
-static int chanSize = 0;
-#if !defined(DMX_SEND_ONLY)
-static int currentChannel = 0;
-#endif
-
-// Some new MCUs (-S2, -C3) don't have HardwareSerial(2)
-#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
- #if SOC_UART_NUM < 3
- #error DMX output is not possible on your MCU, as it does not have HardwareSerial(2)
- #endif
-#endif
-
-static HardwareSerial DMXSerial(2);
-
-/* Interrupt Timer for DMX Receive */
-#if !defined(DMX_SEND_ONLY)
-static hw_timer_t * timer = NULL;
-static portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
-#endif
-
-static volatile int _interruptCounter = 0;
-static volatile bool _startCodeDetected = false;
-
-
-#if !defined(DMX_SEND_ONLY)
-/* Start Code is detected by 21 low interrupts */
-void IRAM_ATTR onTimer() {
- if ((rxPin >= 0) && (digitalRead(rxPin) == 1))
- {
- _interruptCounter = 0; //If the RX Pin is high, we are not in an interrupt
- }
- else
- {
- _interruptCounter++;
- }
- if (_interruptCounter > 9)
- {
- portENTER_CRITICAL_ISR(&timerMux);
- _startCodeDetected = true;
- DMXSerial.begin(DMXSPEED, DMXFORMAT, rxPin, txPin);
- portEXIT_CRITICAL_ISR(&timerMux);
- _interruptCounter = 0;
- }
-}
-
-void SparkFunDMX::initRead(int chanQuant) {
-
- timer = timerBegin(0, 1, true);
- timerAttachInterrupt(timer, &onTimer, true);
- timerAlarmWrite(timer, 320, true);
- timerAlarmEnable(timer);
- _READWRITE = _READ;
- if (chanQuant > dmxMaxChannel || chanQuant <= 0)
- {
- chanQuant = defaultMax;
- }
- chanSize = chanQuant;
- if (enablePin >= 0) {
- pinMode(enablePin, OUTPUT);
- digitalWrite(enablePin, LOW);
- }
- if (rxPin >= 0) pinMode(rxPin, INPUT);
-}
-#endif
-
-// Set up the DMX-Protocol
-void SparkFunDMX::initWrite (int chanQuant) {
-
- _READWRITE = _WRITE;
- if (chanQuant > dmxMaxChannel || chanQuant <= 0) {
- chanQuant = defaultMax;
- }
-
- chanSize = chanQuant + 1; //Add 1 for start code
-
- DMXSerial.begin(DMXSPEED, DMXFORMAT, rxPin, txPin);
- if (enablePin >= 0) {
- pinMode(enablePin, OUTPUT);
- digitalWrite(enablePin, HIGH);
- }
-}
-
-#if !defined(DMX_SEND_ONLY)
-// Function to read DMX data
-uint8_t SparkFunDMX::read(int Channel) {
- if (Channel > chanSize) Channel = chanSize;
- return(dmxData[Channel - 1]); //subtract one to account for start byte
-}
-#endif
-
-// Function to send DMX data
-void SparkFunDMX::write(int Channel, uint8_t value) {
- if (Channel < 0) Channel = 0;
- if (Channel > chanSize) chanSize = Channel;
- dmxData[0] = 0;
- dmxData[Channel] = value; //add one to account for start byte
-}
-
-
-
-void SparkFunDMX::update() {
- if (_READWRITE == _WRITE)
- {
- //Send DMX break
- digitalWrite(txPin, HIGH);
- DMXSerial.begin(BREAKSPEED, BREAKFORMAT, rxPin, txPin);//Begin the Serial port
- DMXSerial.write(0);
- DMXSerial.flush();
- delay(1);
- DMXSerial.end();
-
- //Send DMX data
- DMXSerial.begin(DMXSPEED, DMXFORMAT, rxPin, txPin);//Begin the Serial port
- DMXSerial.write(dmxData, chanSize);
- DMXSerial.flush();
- DMXSerial.end();//clear our DMX array, end the Hardware Serial port
- }
-#if !defined(DMX_SEND_ONLY)
- else if (_READWRITE == _READ)//In a perfect world, this function ends serial communication upon packet completion and attaches RX to a CHANGE interrupt so the start code can be read again
- {
- if (_startCodeDetected == true)
- {
- while (DMXSerial.available())
- {
- dmxData[currentChannel++] = DMXSerial.read();
- }
- if (currentChannel > chanSize) //Set the channel counter back to 0 if we reach the known end size of our packet
- {
-
- portENTER_CRITICAL(&timerMux);
- _startCodeDetected = false;
- DMXSerial.flush();
- DMXSerial.end();
- portEXIT_CRITICAL(&timerMux);
- currentChannel = 0;
- }
- }
- }
-#endif
-}
-
-// Function to update the DMX bus
-#endif
-#endif
diff --git a/wled00/src/dependencies/dmx/SparkFunDMX.h b/wled00/src/dependencies/dmx/SparkFunDMX.h
deleted file mode 100644
index 73861153b2..0000000000
--- a/wled00/src/dependencies/dmx/SparkFunDMX.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/******************************************************************************
-SparkFunDMX.h
-Arduino Library for the SparkFun ESP32 LED to DMX Shield
-Andy England @ SparkFun Electronics
-7/22/2019
-
-Development environment specifics:
-Arduino IDE 1.6.4
-
-This code is released under the [MIT License](http://opensource.org/licenses/MIT).
-Please review the LICENSE.md file included with this example. If you have any questions
-or concerns with licensing, please contact techsupport@sparkfun.com.
-Distributed as-is; no warranty is given.
-******************************************************************************/
-
-#include
-
-
-#ifndef SparkFunDMX_h
-#define SparkFunDMX_h
-
-#define DMX_SEND_ONLY // this disables DMX sending features, and saves us two GPIO pins
-
-// ---- Methods ----
-
-class SparkFunDMX {
-public:
- void initWrite(int maxChan);
-#if !defined(DMX_SEND_ONLY)
- void initRead(int maxChan);
- uint8_t read(int Channel);
-#endif
- void write(int channel, uint8_t value);
- void update();
-private:
- const uint8_t _startCodeValue = 0xFF;
- const bool _READ = true;
- const bool _WRITE = false;
- bool _READWRITE;
-};
-
-#endif
\ No newline at end of file
diff --git a/wled00/wled.cpp b/wled00/wled.cpp
index d67f784078..7d5fea8782 100644
--- a/wled00/wled.cpp
+++ b/wled00/wled.cpp
@@ -443,9 +443,6 @@ void WLED::setup()
#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
PinManager::allocatePin(hardwareTX, true, PinOwner::DebugOut); // TX (GPIO1 on ESP32) reserved for debug output
#endif
-#ifdef WLED_ENABLE_DMX //reserve GPIO2 as hardcoded DMX pin
- PinManager::allocatePin(2, true, PinOwner::DMX);
-#endif
DEBUG_PRINTF_P(PSTR("heap %u\n"), getFreeHeapSize());
@@ -555,7 +552,7 @@ void WLED::setup()
}
#endif
#ifdef WLED_ENABLE_DMX
- initDMXOutput();
+ initDMXOutput(dmxOutputPin);
#endif
#ifdef WLED_ENABLE_DMX_INPUT
dmxInput.init(dmxInputReceivePin, dmxInputTransmitPin, dmxInputEnablePin, dmxInputPort);
diff --git a/wled00/wled.h b/wled00/wled.h
index 21b340d94c..784e756ccb 100644
--- a/wled00/wled.h
+++ b/wled00/wled.h
@@ -142,11 +142,7 @@
#endif
#ifdef WLED_ENABLE_DMX
- #if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
- #include "src/dependencies/dmx/ESPDMX.h"
- #else //ESP32
- #include "src/dependencies/dmx/SparkFunDMX.h"
- #endif
+#include "dmx_output.h"
#endif
#ifdef WLED_ENABLE_DMX_INPUT
@@ -454,11 +450,12 @@ WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if
WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black
#ifdef WLED_ENABLE_DMX
- #if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
+ #if defined(ESP8266)
WLED_GLOBAL DMXESPSerial dmx;
- #else //ESP32
- WLED_GLOBAL SparkFunDMX dmx;
- #endif
+ #else
+ WLED_GLOBAL DMXOutput dmx;
+ #endif
+ WLED_GLOBAL int dmxOutputPin _INIT(-1); // DMX output pin (use -1 for disabled)
WLED_GLOBAL uint16_t e131ProxyUniverse _INIT(0); // output this E1.31 (sACN) / ArtNet universe via MAX485 (0 = disabled)
// dmx CONFIG
WLED_GLOBAL byte DMXChannels _INIT(7); // number of channels per fixture
diff --git a/wled00/xml.cpp b/wled00/xml.cpp
index dceebbdf09..8091569797 100644
--- a/wled00/xml.cpp
+++ b/wled00/xml.cpp
@@ -494,6 +494,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
printSetFormValue(settingsScript,PSTR("EU"),e131Universe);
#ifdef WLED_ENABLE_DMX
settingsScript.print(SET_F("hideNoDMXOutput();")); // hide "not compiled in" message
+ printSetFormValue(settingsScript,SET_F("IDMO"), dmxOutputPin);
#endif
#ifndef WLED_ENABLE_DMX_INPUT
settingsScript.print(SET_F("hideDMXInput();")); // hide "dmx input" settings