#include "wled.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) * ESP8266 Library from: * https://github.com/Rickgg/ESP-Dmx * ESP32 Library from: * https://github.com/sparkfun/SparkFunDMX */ #ifdef WLED_ENABLE_DMX #pragma message "DMX output enabled" #define MAX_DMX_RATE 44 // max DMX update rate in Hz // WLEDMM: seems that DMX output triggers watchdog resets when compiling for IDF 4.4.x #ifdef ARDUINO_ARCH_ESP32 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) #warning DMX output support might cause watchdog reset when compiling with ESP-IDF V4.4.x // E (24101) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time: // E (24101) task_wdt: - IDLE (CPU 0) // E (24101) task_wdt: Tasks currently running: // E (24101) task_wdt: CPU 0: FFT // E (24101) task_wdt: CPU 1: IDLE // E (24101) task_wdt: Aborting. //abort() was called at PC 0x40143b6c on core 0 #endif #endif void handleDMXOutput() { // don't act, when in DMX Proxy mode if (e131ProxyUniverse != 0) return; // Ensure segments exist before accessing strip data if (strip.getSegmentsNum() == 0) return; // Rate limiting static unsigned long last_dmx_time = 0; constexpr unsigned long dmxFrameTime = (1000UL + MAX_DMX_RATE - 1) / MAX_DMX_RATE; // Ceiling division to round up if (millis() - last_dmx_time < dmxFrameTime) return; uint8_t brightness = strip.getBrightness(); // Skip DMX entirely if strip is off //if (brightness == 0) return; // WLEDMM not sure about this line - it possibly prevents that the final "black" color gets transmitted last_dmx_time = millis(); bool calc_brightness = true; // check if no shutter channel is set for (byte i = 0; i < DMXChannels; i++) { if (DMXFixtureMap[i] == 5) calc_brightness = false; } uint16_t len = strip.getLengthTotal(); for (int i = DMXStartLED; i < len; i++) { // uses the amount of LEDs as fixture count uint32_t in = strip.getPixelColor(i); // get the colors for the individual fixtures as suggested by Aircoookie in issue #462 byte w = W(in); byte r = R(in); byte g = G(in); byte b = B(in); int DMXFixtureStart = DMXStart + (DMXGap * (i - DMXStartLED)); for (int j = 0; j < DMXChannels; j++) { int DMXAddr = DMXFixtureStart + j; switch (DMXFixtureMap[j]) { case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. dmx.write(DMXAddr, 0); break; case 1: // Red dmx.write(DMXAddr, calc_brightness ? (r * brightness) / 255 : r); break; case 2: // Green dmx.write(DMXAddr, calc_brightness ? (g * brightness) / 255 : g); break; case 3: // Blue dmx.write(DMXAddr, calc_brightness ? (b * brightness) / 255 : b); break; case 4: // White dmx.write(DMXAddr, calc_brightness ? (w * brightness) / 255 : w); break; case 5: // Shutter channel. Controls the brightness. dmx.write(DMXAddr, brightness); break; case 6: // Sets this channel to 255. Like 0, but more wholesome. dmx.write(DMXAddr, 255); break; } } } dmx.update(); // update the DMX bus } void initDMXOutput() { #ifdef ESP8266 dmx.init(512); // initialize with bus length #else dmx.initWrite(512); // initialize with bus length #endif } #else void initDMXOutput(){} void handleDMXOutput() {} #endif