Professional DMX512 receiver library for ESP32 microcontrollers with Arduino Core 3.0+ support.
- Features
- Requirements
- Installation
- Quick Start
- Hardware Setup
- API Documentation
- Examples
- Technical Details
- Thread Safety and Multi-Core Support
- Troubleshooting
- Contributing
- License
- Acknowledgments
| Feature | Status |
|---|---|
| Full 512 channel support | ✅ |
| Arduino Core 3.0+ compatible | ✅ |
| Automatic break detection | ✅ |
| Packet statistics | ✅ |
| Zero-copy channel reading | ✅ |
| Thread-safe operation | ✅ |
| Multi-core support (ESP32) | ✅ |
| Partial universe support | ✅ |
| Multiple UART support | ✅ |
| DMX transmission | ❌ |
| RDM support | ❌ |
- Packet Rate: 44-50 Hz (standard DMX)
- Latency: < 1ms from packet reception to data availability
- Memory Usage: ~1.5KB RAM
- CPU Usage: < 1% at 50Hz packet rate
- Arduino IDE 1.8.13+ or PlatformIO
- ESP32 Arduino Core 3.0.0 or later
- No additional library dependencies
- ESP32, ESP32-S2, or ESP32-S3 development board
- RS485 transceiver module (MAX485, SN75176B, or equivalent)
- DMX512 signal source
| Board | Core Version | Status |
|---|---|---|
| ESP32 DevKitC | 3.0.0 | ✅ Tested |
| ESP32-S2 | 3.0.0 | ✅ Tested |
| ESP32-S3 | 3.3.0 | ✅ Tested |
- Open Arduino IDE
- Go to Tools → Manage Libraries...
- Search for "ESP32S3DMX"
- Click Install
cd ~/Documents/Arduino/libraries
git clone https://github.com/yourusername/ESP32S3DMX.gitAdd to platformio.ini:
lib_deps =
https://github.com/yourusername/ESP32S3DMX.git#include <ESP32S3DMX.h>
ESP32S3DMX dmx;
void setup() {
Serial.begin(115200);
dmx.begin(); // Initialize with default pins
}
void loop() {
if (dmx.isConnected()) {
uint8_t brightness = dmx.read(1); // Read channel 1
Serial.printf("Channel 1: %d\n", brightness);
}
delay(100);
}ESP32 RS485 Module DMX Connector
------ ------------ -------------
GPIO 6 <--- RO
GPIO 5 ---> DE/RE
GPIO 4 ---> DI (NC)
3V3/5V ---> VCC
GND ---> GND -----------> Pin 1 (GND)
A -----------> Pin 3 (Data+)
B -----------> Pin 2 (Data-)
- Connect DE and RE pins together for receive-only operation
- Some RS485 modules require 5V power (check specifications)
- DMX uses XLR 5-pin or 3-pin connectors
- 120Ω termination may be required for long cable runs
| Board | Default RX | Default TX | Default Enable | Recommended UART |
|---|---|---|---|---|
| ESP32 | GPIO 16 | GPIO 17 | GPIO 4 | UART2 |
| ESP32-S2 | GPIO 6 | GPIO 4 | GPIO 5 | UART1 |
| ESP32-S3 | GPIO 6 | GPIO 4 | GPIO 5 | UART2 |
ESP32S3DMX()Creates a new DMX receiver instance. Only one instance should be created per UART.
void begin(uint8_t uart_num = 2, int rx_pin = 6, int tx_pin = 4, int enable_pin = 5)Initializes the DMX receiver.
Parameters:
uart_num: UART peripheral to use (1 or 2, not 0 on ESP32-S3)rx_pin: GPIO pin connected to RS485 RO (receiver output)tx_pin: GPIO pin connected to RS485 DI (driver input) - unused for receiveenable_pin: GPIO pin connected to RS485 DE/RE (direction control)
Example:
dmx.begin(); // Use defaults
dmx.begin(2, 16, 17, 4); // Custom pinsvoid end()Stops the DMX receiver and releases resources.
uint8_t read(uint16_t channel)Reads a single DMX channel value. Thread-safe.
Parameters:
channel: DMX channel number (1-512)
Returns: Channel value (0-255), or 0 if channel is invalid or no signal
Example:
uint8_t dimmer = dmx.read(1);
uint8_t red = dmx.read(2);uint16_t readChannels(uint8_t* buffer, uint16_t start_channel, uint16_t count)Reads multiple consecutive channels efficiently. Thread-safe.
Parameters:
buffer: Array to store channel valuesstart_channel: First channel to read (1-512)count: Number of channels to read
Returns: Number of channels actually read
Example:
uint8_t rgbw[4];
dmx.readChannels(rgbw, 10, 4); // Read channels 10-13bool isConnected()Checks if receiving valid DMX signal.
Returns: true if DMX received within last second, false otherwise
float getPacketRate()Gets the current packet reception rate.
Returns: Packets per second (0.0 if no signal)
| Method | Returns | Description |
|---|---|---|
getPacketCount() |
uint32_t |
Total valid packets received |
getErrorCount() |
uint32_t |
Total reception errors |
timeSinceLastPacket() |
uint32_t |
Milliseconds since last packet |
getLastPacketSize() |
uint16_t |
Size of last packet (bytes) |
getBuffer() |
const uint8_t* |
Direct access to DMX buffer |
Simple DMX channel display - perfect for getting started.
// Displays first 8 channels continuouslyMonitor specific channels and trigger actions on changes.
// Detect changes, thresholds, and mode switchesInteractive channel viewer with Serial Monitor commands.
// View any range of channels interactively- Baud Rate: 250,000 bps
- Format: 8 data bits, no parity, 2 stop bits (8N2)
- Break: Minimum 88μs (detected via UART error)
- MAB: Minimum 8μs (tolerates down to 2μs)
- Start Code: 0x00 (null start code only)
The ESP32-S3 UART hardware captures an extra byte at the beginning of the break signal. This library automatically compensates for this behavior, ensuring correct channel mapping.
dmxData[0] = Start code (0x00)
dmxData[1] = Channel 1
dmxData[2] = Channel 2
...
dmxData[512] = Channel 512
The ESP32S3DMX library is designed to be thread-safe and can be safely used in multi-threaded environments:
- Reading channels from multiple threads/tasks simultaneously
- Calling
begin()from any core (0 or 1) - Accessing data while reception is ongoing
- Using from FreeRTOS tasks without additional synchronization
- Atomic Operations: Critical sections protected with
noInterrupts()/interrupts() - Volatile Buffers: Ensures memory coherency between cores
- Double Buffering: Separate receive and read buffers prevent corruption
- No Dynamic Memory: All buffers are statically allocated
// Example: Running DMX on Core 1
void dmxTask(void* param) {
dmx.begin(); // Initialize on Core 1
while(1) {
if (dmx.isConnected()) {
uint8_t value = dmx.read(1);
// Process DMX data...
}
vTaskDelay(1);
}
}
void setup() {
xTaskCreatePinnedToCore(dmxTask, "DMX", 4096, NULL, 1, NULL, 1);
}// Task 1: Read lighting channels
void lightingTask(void* param) {
while(1) {
uint8_t brightness = dmx.read(1);
uint8_t color = dmx.read(2);
// Update lights...
vTaskDelay(20);
}
}
// Task 2: Read effects channels
void effectsTask(void* param) {
while(1) {
uint8_t effect = dmx.read(10);
uint8_t speed = dmx.read(11);
// Update effects...
vTaskDelay(50);
}
}- UART interrupts run on the core that calls
begin() - DMX data can be read from any core
- No core affinity requirements
- Default scheduler assignment works perfectly
- Interrupt disable time: < 100μs (minimal impact)
- Safe for real-time applications
- No mutex overhead for read operations
- Zero-copy design for efficiency
| Problem | Possible Causes | Solutions |
|---|---|---|
| No signal detected | Wiring issue | Check connections, verify power |
| Wrong polarity | Swap A/B connections | |
| No DMX source | Verify console is outputting | |
| Wrong channel values | Universe size | Check console universe settings |
| Channel offset | Verify channel numbering | |
| Intermittent signal | Termination | Add 120Ω terminator |
| Cable quality | Use DMX-rated cable | |
| Compilation error | Core version | Update to Core 3.0+ |
- ✓ RS485 module powered (LED indicator?)
- ✓ DE/RE pins connected together and to GPIO
- ✓ A/B polarity correct (try swapping)
- ✓ DMX source actively transmitting
- ✓ Using UART1 or UART2 (not UART0)
We welcome contributions! Please see our Contributing Guidelines.
git clone https://github.com/yourusername/ESP32S3DMX.git
cd ESP32S3DMX
# Create feature branch
git checkout -b feature/your-feature- Use 4 spaces for indentation
- Follow Arduino style guide
- Document all public methods
- Include examples for new features
This library is available under a dual license model:
For open source projects and non-commercial use, this library is licensed under the GNU Lesser General Public License v2.1.
For use in commercial products or closed-source applications, a commercial license is required.
Commercial licenses include:
- Rights to use in commercial products
- Ability to create closed-source derivatives
- Priority support
- Custom feature development options
To obtain a commercial license, contact: [your.email@example.com]
Note: If you're unsure which license applies to your use case, please reach out for clarification.
- ESP32 Arduino Core team for Core 3.0
- DMX512 specification by ESTA
- RS485 transceiver manufacturers
- All contributors and testers
Need Help? Open an issue on GitHub.