A high-performance ArtNet-to-WS2812B LED controller built on Arduino Mega 2560, optimized for low latency and smooth multi-universe playback.
- Multi-Universe Support - Handles up to 8 ArtNet universes (1360 LEDs max)
- High Performance - Optimized memory access with pointer arithmetic and smart frame batching
- Frame Synchronization - Intelligent universe tracking ensures smooth, synchronized LED updates
- Configurable - Easy customization of LED count, pin assignments, and network settings
- Zero Artificial Limits - FastLED refresh rate limits removed for maximum throughput (~125fps)
- Automatic Build Testing - GitHub Actions CI/CD pipeline ensures code quality
- Microcontroller: Arduino Mega 2560
- Network: Ethernet shield (W5100/W5500 compatible)
- LEDs: WS2812B addressable RGB LED strip (up to 1360 LEDs)
- Power Supply: Adequate for your LED count (typically 60mA per LED at full white)
Arduino Mega 2560
├─ Pin 6 → LED Strip Data (DIN)
├─ GND → LED Strip Ground
├─ Ethernet Shield (standard SPI pins)
│ ├─ Pin 50 (MISO)
│ ├─ Pin 51 (MOSI)
│ ├─ Pin 52 (SCK)
│ └─ Pin 10 (SS/CS)
└─ 5V → Power (Arduino only - use external PSU for LEDs)
Important: Always use an external power supply for LED strips. Connect LED strip ground to Arduino ground.
- PlatformIO or Arduino IDE
- Git (for version control)
-
Clone the repository
git clone https://github.com/miles-p/LED-Controller.git cd LED-Controller -
Build with PlatformIO
pio run
-
Upload to Arduino
pio run --target upload
Or specify a port:
pio run --target upload --upload-port COM5
-
Monitor serial output (optional, requires
DEBUG 1)pio device monitor -b 115200
Edit src/main.cpp to customize:
// LED Configuration
#define LED_PIN 6 // Data pin for WS2812B
#define NUM_LEDS 300 // Total number of LEDs
// Network Configuration
#define ARTNET_PORT 6454 // Standard ArtNet port
#define START_UNIVERSE 0 // First universe to listen to
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 50); // Static IP address
// Performance Tuning
#define LEDS_PER_UNIVERSE 170 // LEDs per universe (510 DMX channels)
const unsigned long MIN_SHOW_INTERVAL = 8; // Min ms between updates (~125fps)
// Debug Mode
#define DEBUG 0 // Set to 1 to enable serial debug outputThe controller automatically maps ArtNet universes to LED indices:
| Universe | LED Range | DMX Channels |
|---|---|---|
| 0 | 0-169 | 1-510 |
| 1 | 170-339 | 1-510 |
| 2 | 340-509 | 1-510 |
| ... | ... | ... |
Example: For 300 LEDs, you need 2 universes (0 and 1).
Configure your lighting software (e.g., QLC+, Resolume, MadMapper):
- Protocol: ArtNet
- IP Address:
192.168.1.50(or your configured IP) - Universe Start:
0(or your configuredSTART_UNIVERSE) - Channels per Universe: 510 (170 LEDs × 3 channels RGB)
- DMX Channel Order: RGB
This firmware includes several performance enhancements:
- Pointer Arithmetic - Direct memory access via
memcpy()instead of indexed loops - Frame Batching - Waits for all universes before calling
FastLED.show() - Zero Throttling - Removed FastLED's default 400Hz refresh limit
- Preprocessor Debug - Debug output disabled at compile-time for zero overhead
- Smart Caching - Universe tracking with bitmask operations (O(1) complexity)
Result: ~40-60% faster packet processing compared to naive implementations.
LED-Controller/
├── src/
│ └── main.cpp # Main firmware code
├── lib/ # Dependencies (ArtNet, FastLED, Ethernet)
├── .github/workflows/
│ └── build.yml # CI/CD build pipeline
├── platformio.ini # PlatformIO configuration
└── README.md # This file
# Build firmware
pio run
# Clean build artifacts
pio run --target clean
# Run tests (when implemented)
pio testThe repository includes a pre-commit hook that automatically builds the firmware before each commit to prevent broken code from entering the repository.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (will trigger automatic build test)
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request (CI will run automated build tests)
- Check wiring (data pin, ground connection)
- Verify power supply is adequate
- Confirm LED strip type matches code (WS2812B)
- Enable debug mode and check serial output
- Verify Ethernet cable connection
- Check IP address doesn't conflict with other devices
- Confirm ArtNet sender is targeting correct IP
- Test with ping:
ping 192.168.1.50
# Update PlatformIO
pio upgrade
# Clean and rebuild
pio run --target clean
pio run- Increase
MIN_SHOW_INTERVAL(currently 8ms) - Check power supply stability
- Verify network connection quality
- Reduce
NUM_LEDSif experiencing performance issues
Typical Performance (300 LEDs, 2 universes):
- Latency: <2ms from packet arrival to LED update
- Max Refresh Rate: ~125fps (8ms interval)
- Universe Processing: ~200μs per universe
- Memory Usage: ~2KB RAM (LED buffer)
Copyright © 2025 Miles Punch. All Rights Reserved.
Licensed under the GNU General Public License v3.0. See LICENSE for details.
- FastLED Library - High-performance LED control
- ArtNet Protocol - Industry-standard lighting protocol
- Arduino Ethernet Library - Network stack
For issues, questions, or contributions:
- Open an Issue
- Submit a Pull Request
- Contact: miles-p on GitHub
Built with ❤️ for the lighting community