Complex LED Pattern Code

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!

1 Like

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.

1 Like

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.

1 Like

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?

That would be much apreciated!

This is what we originally thought of but were stumped by the subsystem dependencies to display patterns conditionally

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.

1 Like

Thanks so much!

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.

2 Likes

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.

Makes sense.

What is your timerIndex referencing / how do you initialize the variable?

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.

FYI, I made a subtle edit to my example with the timerIndex, I wasn’t incrementing it.

We initialize it to 0 and let it count.

I think I have a pretty good solution. It allows for adding multiple patterns quickly.

You’d just have to pop it into your project and obviously replace my mock FRC classes with the default ones

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.