The LED subsystem provides real-time visual feedback to drive teams and referees during a match. Spectrum’s 2026 codebase uses a CTREDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/spectrum3847/2026-Spectrum/llms.txt
Use this file to discover all available pages before exploring further.
CANdle device (CAN ID 1, CANIVORE bus) to drive an RGB LED strip with 20 addressable LEDs. The implementation follows the same States-based architecture as every other subsystem: a main class (CANdleLeds) configures hardware, and LedStates declares triggers and binds animations.
The
CANdleLeds and LedStates classes are currently scaffolded but commented out — the hardware integration is ready to be enabled when the physical CANdle is wired. The patterns shown below reflect the intended design already written in the source.CANdleLeds configuration
CANdleLeds configures the CANdle at startup:
CANdleLeds.java
- Strip type: RGB (no white channel used)
- Brightness: 50% scalar applied globally
- Loss-of-signal behavior: LEDs disable if CAN communication is lost, preventing stuck animations during a brownout
- Default animation: Purple single-fade at 100 Hz frame rate on startup
Multiple strip instances via LEDBufferView
SpectrumLEDs (from SpectrumLib) supports creating multiple subsystem instances, each targeting a different LEDBufferView slice of the full strip. This lets you command the front strip, back strip, or any segment independently without conflicts.
LedStates reference pattern
Default command and mode-based animations
LedStates calls setupDefaultCommand() and bindTriggers() from setupDefaultCommand() and setupStates() on the subsystem. The default command can detect the current DriverStation mode and dispatch mode-specific animations:
- Autonomous: Alliance-color single fade
- Teleop (normal shift): Alliance-color single fade, switching between blue and red based on
ShiftHelpers.isCurrentShiftBlue() - Disabled: No command is scheduled (LEDs idle)
Trigger-based animation priorities
LedStates declares time-based and state-based triggers and binds animations using .onTrue(Commands.runOnce(...)):
LedStates.java
| Trigger | Animation | Priority |
|---|---|---|
auto | Alliance-color single fade | 15 |
transitionShift (140–133 s) | Alliance-color single fade | 15 |
transitionAboutToEnd (133–130 s) | Alliance-color strobe | 25 |
redShift | Red single fade | 10 |
blueShift | Blue single fade | 10 |
aboutToChangeShift | Current-alliance strobe | 25 |
endgame (≤ 30 s) | Yellow-green single fade (#CFff04) | 20 |
bothInShift guard (auto.or(transitionShift, endgame)) prevents shift-color animations from running when a higher-priority animation is already active.
Creating new LED commands
Follow these steps to add a new animation:Define the animation
Create a
SingleFadeAnimation, StrobeAnimation, or other CTRE LED control object with the desired color and LED range.LedStates.java
Create a command
Wrap the animation in a
Commands.runOnce that calls candle.setControl(...).LedStates.java
Declare a trigger
Declare the trigger as a
public static final variable in LedStates so it is accessible from RobotStates.LedStates.java
Binding to robot state triggers
LED commands can also be driven byRobotStates triggers instead of time. For example, to strobe when the launcher is aiming:
RobotStates.java (example binding)
CANdleLeds source
Hardware init, CANdle configuration, and brightness settings.
LedStates source
All time-based and state-based triggers with animation bindings.
