Files
WLED_MM_Infinity/wled00/dmx.cpp
2023-02-18 16:05:42 +00:00

157 lines
5.3 KiB
C++

#include "wled.h"
/*
* Support for DMX Output via 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
// 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 handleDMX()
{
// don't act, when in DMX Proxy mode
if (e131ProxyUniverse != 0) return;
uint8_t brightness = strip.getBrightness();
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
}
#else
void handleDMX() {}
#endif
#if defined(WLED_ENABLE_DMX) || defined(WLED_ENABLE_DMX_INPUT)
void initDMX() {
#ifdef ESP8266
dmx.init(512); // initialize with bus length
#else
dmx.initWrite(512); // initialize with bus length
#endif
}
#else
void initDMX() {}
#endif
#ifdef WLED_ENABLE_DMX_INPUT
bool dmxIsConnected = false;
unsigned long dmxLastUpdate = 0;
void handleDMXInput() {
byte data[DMX_PACKET_SIZE];
/* We need a place to store information about the DMX packets we receive. We
will use a dmx_packet_t to store that packet information. */
dmx_packet_t packet;
/* And now we wait! The DMX standard defines the amount of time until DMX
officially times out. That amount of time is converted into ESP32 clock
ticks using the constant `DMX_TIMEOUT_TICK`. If it takes longer than that
amount of time to receive data, this if statement will evaluate to false. */
if (dmx_receive(dmxPort, &packet, DMX_TIMEOUT_TICK)) {
/* If this code gets called, it means we've received DMX data! */
/* Get the current time since boot in milliseconds so that we can find out
how long it has been since we last updated data and printed to the Serial
Monitor. */
unsigned long now = millis();
/* We should check to make sure that there weren't any DMX errors. */
if (!packet.err) {
/* If this is the first DMX data we've received, lets log it! */
if (!dmxIsConnected) {
DEBUG_PRINTLN("DMX is connected!");
dmxIsConnected = true;
}
/* Don't forget we need to actually read the DMX data into our buffer so
that we can print it out. */
dmx_read(dmxPort, data, packet.size);
if (now - dmxLastUpdate > 1000) {
/* Print the received start code - it's usually 0. */
DEBUG_PRINTF("Start code is 0x%02X and slot 1 is 0x%02X\n", data[0],
data[1]);
dmxLastUpdate = now;
}
} else {
/* Oops! A DMX error occurred! Don't worry, this can happen when you first
connect or disconnect your DMX devices. If you are consistently getting
DMX errors, then something may have gone wrong with your code or
something is seriously wrong with your DMX transmitter. */
DEBUG_PRINTLN("A DMX error occurred.");
}
} else if (dmxIsConnected) {
DEBUG_PRINTLN("DMX was disconnected.");
}
if(dmxIsConnected) {
DEBUG_PRINTF("DMX channel 1 = %u\n", data(1)); // TODO: remove from final code
handleDMXData(1, 512, data, 1, REALTIME_MODE_DMX, 0);
}
}
#endif