This is our team’s first year implementing LEDs on our robot for driver/operator feedback (shooter aligned, shooter wheels spun up). We are using the AddressableLED class and have been able to get simple patterns working (solid colours, strobe) but have been unable to create complex patterns (chase, cylon etc).
One of our main issues is that we are not sure where to place the code to loop through the code to set the LED Buffer and ultimately set the LEDs. We currently have an LED subsystem that is responsible for setting the patterns but when we try to implement a while loop in those methods, it crashes the code.
If anyone has been successful in implementing these complex patterns and doesn’t mind posting a link to the code, it would be greatly appreciated!
One of our students has been working on this and has some cool pulsing patterns working. The code is not in a “publishable” state (it is a mess of copy/paste spaghetti code) but we’ll share it when we can.
I think you just want to have something that’s called during teleopPeriodic() that would calculate the current state of all the LEDs, and write it to the buffer. This rate-limits your changes to the periodic timer (50 Hz?) but that should be plenty fast for chases and fades. Don’t do while loops within the teleop periodic loop - unless I am misunderstanding your question.
I’ll post the code for this tonight. The basic concept is in teleopPeriodic update the buffer the way you want to, and then set the LEDs to the buffer.
We have had success using global variable that are adjusted each time the specific led method is set. Here is one that just pulses the lights blue. There is a global variable bluePulseBrightness that is modified each time the method is called. You could do all kinds of effects with a similar implementation. This method would then need to be called periodically by a command or placing it somewhere in your code that runs periodically.
public void bluePulse(){
for (var i = 0; i < m_ledBuffer.getLength(); i++) {
// Sets the specified LED to the RGB values for blue
m_ledBuffer.setRGB(i, 0, 0, bluePulseBrightness);
}
//increase brightness
bluePulseBrightness += 5;
//Check bounds
bluePulseBrightness %= 255;
m_led.setData(m_ledBuffer);
}
Just saw you edit and it answered my next question…
For us it was tough to get the LEDs to trigger for specific conditions when using the new command based framework since subsystems are private to the RobotContainer class. My guess to implementing it would be to pass the LED subsystem into a command (let’s saw limelight alignment) and then display some pattern in the execute() block but I’m not sure if that would work…
Thank you for the idea of the global variable though! I will definitely pass it along to the rest of the team. Am I correct in saying that you declare the variable as a subsystem constant?
We created a LEDSubsystem and are calling it as commands. The only downside to the way I have it at the moment is before the robot is enabled the lights are in a static state.
Here is a link to a version of our robot code that uses the LED subsystem.
While loops are generally a no-go in FRC programming.
Allow the scheduler loop to be your while iterator…then use for loops to address the LED buffers.
Basically, to get our patterns to animate the construct is something like this:
A member variable representing the current index and one to represent the scheduler. Some sort of modulus that determines the frequency of updates.
Pseudocode of our animations are something like:
if timerIndex++ % 10 (every tenth scheduler loop, or .2 seconds)
currentIndex++
for i = 0; i < ledbufsize ; i+=4:
setled(i + currentIndex, RGB)
setled(i + 1 + currentIndex, RGB)
setled(i + 2 + currentIndex, RGB)
setled(i + 3 + currentIndex, RGB)
That is sort of the basic mantra we’ve used to do specific color based animations.
We found it much easier to have an arduino drive the LED’s . The arduino reads 3 digital IO’s from the roborio to select the pattern. After the pattern is completed it checks the state of the digital IO’s again . The whole thing is in an infinite loop on the arduino . The robo code just needs to set the IO pins once when a pattern change is desired.
We thought of this but then decided to go the RIO route because of how easy it is to implement (solder the end of the LEDs to a PWM cable and plug in). An offseason project is definitely going to this.
Here’s the code for the Thanksgiving scrolling message. It’s written in C++.
If you want to just switch between fixed patterns (rather than do animation), you can just create multiple buffer objects and just call setData() to choose the pattern.