See the controller in action here: https://www.instagram.com/p/DZA0ANeuV61/
What this is not:
- not a user-friendly GUI-based software like WLED or similar
- not ready to use as I developed it to specific project requirements, you'll likely need to do some tweakings
What this is:
- A functional real-time esp32 firmware for controlling SPI LEDs using DMX
- A DMX-controlled FX player streaming prerendered animations from SD Card
- A stable multi-core firmware that can be modified and extended to your requirements
First you should know that you need to...
- know how to compile/flash ESP32 firmware with platformIO
- have at least some understanding of the required hardware, esp, rs485 to receive DMX signal etc.
- be fine with doing simple C++ code modifications
This is a firmware for ESP32, optimized for realtime applications controlled by DMX input. No networking, no fancy GUI.
- DMX-Controlled Dimmer+RGB Tinting per strip
- set up to control 2 dual-channel (clock + control) LED strips of type HD108. Other configurations like for example 4 single-channel strips can be implemented but require some code tweaking.
- for use with QuinLED Dig-Quad, should be possible to modify for other ESP32 setups
- implemented on FreeRTOS tasks, allowing it to use both cores of the ESP32
- Core 0 is fully focused on frequent LED data updates
- Core 1 receives DMX data and reads SDcard data
- Output based on NeoPixelBus library, so all of its features and supported strips can be added to match your use case
If you flash the firmware on a QuinLED-ESP32-AE+ or a Octa Brainboard, you can store and stream up to 255 prerendered animations from SDcard in real time.
The animation's brightness and coloring can be modified dynamically per strip using the Dimmer+RGB DMX channels! To play back a colored animation without tinting it, set all Dimmer+RGB DMX values to maximum/255.
FX Engine is controlled by 3 DMX Channels:
- Selection Channel: if set to 0, animation engine is disabled. Range <1-255> will search sdcard for files <1-255>.fseq
- Playback Speed: 127 will run at default speed (40fps). Increasing the value will speed the animation up to double speed. Note: If playback speed is > 1, every second frame will be skipped, because the esp cannot handle more than 40 fps. Decreasing will smoothly reduce the frame rate until its near zero.
- Playback mode:
- 0 = loop - animations will loop, if no animation is playing, the light will be on according to Dim+RGB channels
- 1 = pingpong - animations will go forth and back, if no animation is playing, the light will be on according to Dim+RGB channels
- 2 = oneshot - the animation will play once, ending with black. Before animation is playing, the light will be on according to Dim+RGB channels
- 3 = loop + blackout - animations will loop, if no animation is playing, the light will be off
- 4 = pingpong + blackout - animations will go forth and back, if no animation is playing, the light will be off
- 5 = oneshot + blackout - the animation will play once, ending with black. If no animation is playing, the light will be off
- 10-255 = index mode, allows to flip through the frames 0-245 of the selected animations. this has some great potential - dynamic effects and swipes, one could even store a list of totally different single frames to use as masks etc.
To create animations, use the free software xlights. Set your xlights sequences to 40 fps (firmware will ignore different fps settings). Export your sequences as fseq v1 animations. Name them <1-255>.fseq and put them on a fat32-formatted sdcard.
- TODO: Investigate Frame interpolation possibilities to smoothen low-fps speed multipliers
- TODO: Animation phasing/delay per output
Writing data to the LEDs using the NeoPixelBus API seems to be the primary bottleneck. Updating 340 16-bit LED strips with gamma correction takes about 20ms. This still leaves some margin to run with smooth 40 fps. I am guessing that 8-bit LED output calculation will be quite a bit faster.
Tweak constants.hpp to fit your setup (DMX Address, number of pixels etc)
For working with .fseq files, I've written some useful scripts. See fseq-utils.
Due to ESP32 and Dig-Quad restrictions, some pins cannot be used freely:
- Pins 0 + 3 are usb rx/tx. Dig-Quad uses Pin 3 as LED data outputs which will block serial logging.
- Pin 0 must be LOW to enable flashing
- Pin 1 outputs debug data during boot
- Pin 2 floating or LOW to enter flashing mode
- Pin 3 is HIGH during booting
- Pin 12 can affect boot and flashing capabilities (must not be pulled high at boot)
- Pins 34-36 + 39 - Input Only!
- LED Out Pins: 16, 3, 1, 4
- Relay Pin: 15, 5V
- Button: 0
- general purpose Qx GPIOs available on headers: 15 (Q2), 12 (Q2), 2 (Q3), 32 (Q4)
- Temp Sensor: 13
With ESP32-AE+ extension:
- SD-Card: CLK = 18, DI/MOSI = 23, CS = 5, DO/MISO = 19
- Mic: 27, 25, 32
- Touch: 33
- IR: 26
- LED Outputs: 21, 17, 22
Pins not used anywhere:
- 14, 34, 35, 36 - these pins are on the leftmost row of the quin-esp32 and are not connected to anywhere at all.
Due to above limitations, following mapping was selected:
- No use of LED out pins 1+3 to leave serial logging intact
- Strip 1 uses pins 4 + 16
- Strip 2 uses extension board outs 17 + 21
- DMX tx is not connected, DMX rx connected to Pin 15 (Q1, exposed on Dig-Quad)
Further concept:
- Pins 2+32 could be used for alternative serial logging, allowing pins 1+3 to be used for LED output
See https://randomnerdtutorials.com/esp32-pinout-reference-gpios/
Serial0 (UART0): Pins 0 + 3 (pins locked for USB TTL) Serial1 (UART1): Standard Pins 9 + 10 (locked, used for flash communication) Serial2 (UART2): Standard Pins 16 + 17 Serial3 (UART3): Standard Pins 14 + 15