Connecting to WLED
This guide covers all the ways to connect your FRC robot to a WLED controller.
Connection Methods Overview
| Method | Best For | Latency | Complexity |
|---|---|---|---|
| USB Serial | Simple setups, single controller | ~5-10ms | Low |
| Network TCP | Multiple controllers, longer distances | ~10-20ms | Medium |
USB Serial Connection
Hardware Setup
- Connect the WLED controller to the roboRIO via USB
- Use a quality USB cable (micro-USB or USB-C depending on your ESP board)
- Connect to one of the roboRIO’s USB ports
- Note the port
- The first USB device is typically
kUSB - Additional devices use
kUSB1,kUSB2
- The first USB device is typically
Code Setup
import robowled.wledpipe.SerialPipe;
import edu.wpi.first.wpilibj.SerialPort;
public class LedSubsystem extends SubsystemBase {
private SerialPipe wled;
public LedSubsystem() {
try {
wled = new SerialPipe(SerialPort.Port.kUSB, 115200);
} catch (Exception e) {
System.err.println("Failed to initialize WLED: " + e.getMessage());
}
}
}
Baud Rate
WLED typically uses 115200 baud for serial communication. If you’re having issues, verify this matches your WLED configuration:
- Open the WLED web interface
- Go to Config → Sync Interfaces
- Check the Serial section for baud rate settings
Troubleshooting Serial
| Issue | Solution |
|---|---|
| No response from WLED | Check USB cable and port assignment |
| Garbled data | Verify baud rate matches WLED config |
| Intermittent connection | Try a different USB cable |
| Port not found | Check if another device is using the port |
Network Connection
Hardware Setup
Wired Ethernet
WLED Controller → Ethernet → Robot Radio/Switch
A PoE-enabled adapter will likely provide the best results.
Consult the WLED project Ethernet (LAN) documentation for details on supported ethernet adapters/interfaces and other related concerns.
Addressing Options
You have two options for addressing your WLED device on the network:
| Method | Pros | Cons |
|---|---|---|
| Static IP | Predictable, fast connection | Must configure IP on device, potential conflicts |
| mDNS Hostname | No IP configuration needed, survives network changes | Slightly slower initial resolution |
Using mDNS (Recommended)
mDNS (multicast DNS) allows you to connect to WLED devices using a hostname like wled-xxxxxx.local instead of an IP address. This is often simpler than managing static IPs.
Finding your WLED’s mDNS hostname:
- Open the WLED web interface
- Go to Config → Ethernet
- Look for the mDNS address field (e.g.,
wled-a1b2c3) - Your full hostname is that value plus
.local(e.g.,wled-a1b2c3.local)
You can also customize the mDNS name in the WLED settings to something memorable like wled-front or wled-underglow.
Code using mDNS:
import robowled.wledpipe.NetworkPipe;
import java.io.IOException;
public class LedSubsystem extends SubsystemBase {
private NetworkPipe wled;
// Use mDNS hostname instead of IP address
private static final String WLED_HOST = "wled-underglow.local";
private static final int WLED_PORT = 21324;
public LedSubsystem() {
try {
wled = new NetworkPipe(WLED_HOST, WLED_PORT);
} catch (IOException e) {
System.err.println("Failed to connect to WLED: " + e.getMessage());
}
}
}
mDNS considerations for FRC:
- mDNS resolution may take slightly longer on first connection (typically < 1 second)
- The roboRIO supports mDNS resolution out of the box
- mDNS works across the robot radio network
- If mDNS fails, you can fall back to a static IP
Using Static IP
If you prefer static IPs or mDNS isn’t working reliably, configure your WLED with a static IP:
- Open the WLED web interface
- Go to Config → Ethernet
- Set a static IP in your team’s subnet (e.g.,
10.TE.AM.100) - Set gateway to
10.TE.AM.1and subnet mask to255.255.255.0
Code Setup (Static IP)
import robowled.wledpipe.NetworkPipe;
import java.io.IOException;
public class LedSubsystem extends SubsystemBase {
private NetworkPipe wled;
private static final String WLED_IP = "10.95.67.100";
private static final int WLED_PORT = 21324;
public LedSubsystem() {
try {
wled = new NetworkPipe(WLED_IP, WLED_PORT);
} catch (IOException e) {
System.err.println("Failed to connect to WLED: " + e.getMessage());
}
}
}
Troubleshooting Network
| Issue | Solution |
|---|---|
| Connection refused | Check IP address/hostname and port number |
| Connection timeout | Verify WLED is on the same network |
| Intermittent disconnects | Check for IP conflicts, ensure stable ethernet connection |
| mDNS hostname not resolving | Verify hostname is correct, check WLED mDNS settings |
| Slow initial connection with mDNS | Normal on first connect; consider caching resolved IP |
Handling Connection Errors
Both connection types can fail. Here’s a robust pattern for handling errors:
public class LedSubsystem extends SubsystemBase {
private SerialPipe serialWled;
private NetworkPipe networkWled;
private boolean connected = false;
private int reconnectAttempts = 0;
private static final int MAX_RECONNECT_ATTEMPTS = 5;
public LedSubsystem() {
connect();
}
private void connect() {
// Try serial first
try {
serialWled = new SerialPipe(SerialPort.Port.kUSB, 115200);
connected = true;
System.out.println("Connected to WLED via serial");
return;
} catch (Exception e) {
System.out.println("Serial connection failed, trying network...");
}
// Fall back to network
try {
networkWled = new NetworkPipe("10.95.67.100", 21324);
connected = true;
System.out.println("Connected to WLED via network");
} catch (IOException e) {
System.err.println("All WLED connections failed");
connected = false;
}
}
public void sendCommand(String json) {
if (!connected) {
attemptReconnect();
return;
}
try {
if (serialWled != null) {
serialWled.sendString(json);
} else if (networkWled != null) {
networkWled.sendString(json);
}
} catch (Exception e) {
connected = false;
System.err.println("WLED send failed: " + e.getMessage());
}
}
private void attemptReconnect() {
if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
reconnectAttempts++;
connect();
}
}
@Override
public void periodic() {
// Reset reconnect counter periodically
if (connected) {
reconnectAttempts = 0;
}
}
}
Multiple WLED Controllers
You can connect to multiple WLED controllers simultaneously:
public class MultiLedSubsystem extends SubsystemBase {
private final NetworkPipe frontLeds;
private final NetworkPipe rearLeds;
private final SerialPipe statusLeds;
public MultiLedSubsystem() throws IOException {
frontLeds = new NetworkPipe("10.95.67.101", 21324);
rearLeds = new NetworkPipe("10.95.67.102", 21324);
statusLeds = new SerialPipe(SerialPort.Port.kUSB, 115200);
}
public void setAllColor(int r, int g, int b) {
String json = String.format("{\"seg\":[{\"col\":[[%d,%d,%d]]}]}\n", r, g, b);
try {
frontLeds.sendString(json);
rearLeds.sendString(json);
statusLeds.sendString(json);
} catch (Exception e) {
System.err.println("Failed to set color: " + e.getMessage());
}
}
}
Best Practices
- Use mDNS hostnames for simpler configuration, or static IPs if you need guaranteed fast connections
- Give WLED devices memorable mDNS names like
wled-front.localorwled-status.local - Handle exceptions gracefully - LED failures shouldn’t crash your robot
- Test connections during robot init to catch problems early
- Log connection status to help with debugging at competitions
Next Steps
- Sending Commands - Learn the WLED command format
- Triggering Patterns - Link patterns to robot events