Help with a pacing program - Arduino, Addressable LEDs

Hello everyone, I am new to the world of programming - I’m working in a biomechanics lab and we developed the idea of an LED pace system using Pololu’s Addressable LEDs and an Arduino MEGA 2560. I have scoured the forums for an applicable program and have found that the “LEDStripGradient” -provided by David Grayson- in the resources section of the Addressable LED was the most conducive to work with in developing an accurate pacing system. My set-up includes 4 - 1m 30 light Addressable LED RGB strips tethered in series, pig-tails hooked into pin 12 of the Arduino MEGA 2560, a MacBook Pro running Arduino 1.0.5 connected to the MEGA 2560 via USB, and a 5V power supply powering the LED series. I have manipulated the code aforementioned above and posted it below. My problem seems to stem from understanding the “time” variable in line “byte x = time*[int] - [n]*i”. I’ve multiplied “time” by integers 1-7 and put coefficients in front of the i term in the line “byte x = time*[int] - [n]*i” to manipulate the velocity of the gradient across the 4m strand. The RGB colors write ‘Red’ to a ‘Blue’ strand and the ‘Red’ fades to purple and eventually ‘Blue’ again until the next cycle. My goal is to write the time code to be dependent on an inputted velocity (Range → 0.5 meter/s - 10 meter/s). As I said before, this is my first project involving code and I find it daunting! Any help is greatly appreciated, thank you, kindly, in advance.

/* LedStripGradient: Example Arduino sketch that shows
 * how to control an Addressable RGB LED Strip from Pololu.
 *
 * To use this, you will need to plug an Addressable RGB LED
 * strip from Pololu into pin 12.  After uploading the sketch,
 * you should see a pattern on the LED strip that fades from
 * green to pink and also moves along the strip.
 */
 
#include <PololuLedStrip.h>

// Create an ledStrip object on pin 12.
PololuLedStrip<12> ledStrip;

// Create a buffer for holding 60 colors.  Takes 180 bytes.
#define LED_COUNT 120
rgb_color colors[LED_COUNT];

void setup()
{
}

void loop()
{
  // Update the colors.
  byte time = millis() >> 2;
  for(byte i = 0; i < LED_COUNT; i++)
  {
    byte x = time*3 - 2.5*i;
    colors[i] = (rgb_color){ 2000/x , 0, x };
  }
  
  // Write the colors to the LED strip.
  ledStrip.write(colors, LED_COUNT);  
  
  delay(10);
}

Best Regards,
Mikey

Hello, Mikey.

Here is a much simpler program that you can work with that demonstrates a white LED moving along the LED strip. To change the speed, you just need to change the delay value.

/* LedStripGradient: Example Arduino sketch that shows
 * how to control an Addressable RGB LED Strip from Pololu.
 *
 * To use this, you will need to plug an Addressable RGB LED
 * strip from Pololu into pin 12.  After uploading the sketch,
 * you should see a white LED moving along the strip
 */
 
#include <PololuLedStrip.h>

// Create an ledStrip object on pin 12.
PololuLedStrip<12> ledStrip;

// Create a buffer for holding 120 colors.  Takes 360 bytes.
#define LED_COUNT 120
rgb_color colors[LED_COUNT];
int white_led = LED_COUNT - 1;

void setup()
{
  // set all LEDs to be off ("black")
  for(byte i = 0; i < LED_COUNT; i++)
  {
    colors[i] = (rgb_color){0, 0, 0};
  }
}

void loop()
{
  // Update the colors.
  colors[white_led] = (rgb_color){0, 0, 0};  // turn off previous white LED
  white_led = (white_led + 1)%LED_COUNT;  // increment white LED position
  colors[white_led] = (rgb_color){255, 255, 255};  // set new LED to be white
    
  // Write the colors to the LED strip.  It takes about 8 ms to update 120 LEDs (4m)
  ledStrip.write(colors, LED_COUNT);  
    
  delay(60); // changing this delay will change the speed of your LED
}

I hope this helps.

-Jamee

Thank you very much Jamee! This is much simpler to pace for lower speeds! However, I can only get it to max out at 4.8m/s; this will be fine for our walking pace purposes, and, fortunately, the code I posted previously - the modifications to David Grayson’s gradient code - work well for going above 5.0 m/s, it just takes a little fine tuning of the delay, time coefficient and i coefficient. I modified the code provided by Jamee to have the start value of the strands to be blue, the initial white LED is followed by a stream of red so the subject can focus on a larger series of lights to keep pace (I kept the theme of Red, White, and Blue in spirit of the 4th!) :laughing:

I’ll post our modified code below, in case someone is looking to achieve the same goal. Thank you again Jamee!

/* LedStripGradient: Example Arduino sketch that shows
* how to control an Addressable RGB LED Strip from Pololu.
*
* To use this, you will need to plug an Addressable RGB LED
* strip from Pololu into pin 12.  After uploading the sketch,
* you should see a white LED moving along the strip
*/

#include <PololuLedStrip.h>

// Create an ledStrip object on pin 12.
PololuLedStrip<12> ledStrip;

// Create a buffer for holding 120 colors.  Takes 360 bytes.
#define LED_COUNT 120
rgb_color colors[LED_COUNT];
int white_led = LED_COUNT - 1;
int red_leds = LED_COUNT - 8;
void setup()
{
  // set all LEDs to be light blue
  for(byte i = 0; i < LED_COUNT; i++)
  {
    colors[i] = (rgb_color){0, 20, 125};
  }
}

void loop()
{
  // Update the colors.
  colors[white_led] = (rgb_color){255, 0, 0};  // turn subsequent 7 LEDs after white to red
  colors[red_leds] = (rgb_color){0, 20, 125}; // turn red lights back to blue
  white_led = (white_led + 1)%LED_COUNT;  // increment white LED position
  red_leds = (red_leds + 1)%LED_COUNT; // increment red LED positions
  colors[white_led] = (rgb_color){255, 255, 255};  // turn blue LEDs to white
   
  // Write the colors to the LED strip.  It takes about 8 ms to update 120 LEDs (4m)
  ledStrip.write(colors, LED_COUNT); 
   
  delay(50); // changing this delay will change the speed of the LEDs
}

Best Regards,
Mikey

Hello, Mikey.

I’m glad the code helped! Good luck with the rest of your project.

- Jamee

Update! I have heavily modified the code to adapt to speed in meters per second.

There’s a new light strip available at Pololu and this code is built for that. I’m running this on an Arduino Uno.

 //This code only works with A*prime or Arduino Uno; FastLED is the alternative pacing program.
 //Processor requirement for FastGPIO: AT328p (UNO) or ATmega32U4 (A*prime)

// Input the Target Velocity (m/s)
float 

Velocity = 1.566

;


#include <FastGPIO.h>           //Makes for faster LED update regardless of LED count
#define APA102_USE_FAST_GPIO    //Overrides digitalWrite function for faster LED updates
#include <APA102.h>             //RGB addressable LED light strip model

// Define which pins to use.
const uint8_t dataPin = 11;
const uint8_t clockPin = 12;

// Create an object for writing to the LED strip.
APA102<dataPin, clockPin> ledStrip;

// Set the number of LEDs to control and input the length of LED strip (m)
const uint16_t LED_COUNT = 120;
const uint16_t Length = 4;

// Calculates appropriate delay parameters
float ms = (1/((Velocity/1000)*(LED_COUNT/Length)));
int milli = ms;
float us = ms-milli;
int micro = us * 1000;


// Create a buffer for holding the colors (3 bytes per color).
rgb_color colors[LED_COUNT];
int white_led = LED_COUNT - 1;
int red_leds = LED_COUNT - 6;
int white_led2 = LED_COUNT - (LED_COUNT/4) - 1;
int red_leds2 = LED_COUNT - (LED_COUNT/4) - 6;
int white_led3 = LED_COUNT - (LED_COUNT/4) - (LED_COUNT/4) - 1;
int red_leds3 = LED_COUNT - (LED_COUNT/4) - (LED_COUNT/4) - 6;
int white_led4 = LED_COUNT - (LED_COUNT/4) - (LED_COUNT/4) - (LED_COUNT/4) - 1;
int red_leds4 = LED_COUNT - (LED_COUNT/4) - (LED_COUNT/4) - (LED_COUNT/4) - 6;  

void setup()
{
   for(byte i = 0; i < LED_COUNT; i++)       
  {
    colors[i] = (rgb_color){0, 20, 125};   // set all LEDs to be blue
  }

//This outputs the millisecond and microsecond delays to the serial moniter for debugging 
//  Serial.begin(9600);
//  Serial.println(ms);
//  Serial.println(milli);
//  Serial.println(us);  
//  Serial.println(micro);

}

void loop()
{
  colors[white_led] = (rgb_color){255, 0, 0};      // 7 red lights follow the white
  colors[red_leds] = (rgb_color){0, 20, 100};      // Turn blue after red cycle
  colors[white_led2] = (rgb_color){255, 0, 0};     // Second cycle of red lights
  colors[red_leds2] = (rgb_color){0, 20, 100};     // Turn blue after 2nd red cycle
  colors[white_led3] = (rgb_color){255, 0, 0};     // Third cycle of red lights
  colors[red_leds3] = (rgb_color){0, 20, 100};     // Turn blue after 3rd red cycle
  colors[white_led4] = (rgb_color){255, 0, 0};     // Fourth cycle of red lights
  colors[red_leds4] = (rgb_color){0, 20, 100};     // Turn blue after 4th red cycle  
  white_led = (white_led + 1)%LED_COUNT;           // Increment white LED position
  red_leds = (red_leds + 1)%LED_COUNT;             // Increment red LED positions
  white_led2 = (white_led2 + 1)%LED_COUNT;         // Increment 2nd white LED position
  red_leds2 = (red_leds2 + 1)%LED_COUNT;           // Increment 2nd red LED positions
  white_led3 = (white_led3 + 1)%LED_COUNT;         // Increment 3rd white LED position
  red_leds3 = (red_leds3 + 1)%LED_COUNT;           // Increment 3rd red LED positions
  white_led4 = (white_led4 + 1)%LED_COUNT;         // Increment 4th white LED position
  red_leds4 = (red_leds4 + 1)%LED_COUNT;           // Increment 4th red LED positions
  colors[white_led] = (rgb_color){255, 255, 255};  // Leading white LED
  colors[white_led2] = (rgb_color){255, 255, 255}; // 2nd cycle 
  colors[white_led3] = (rgb_color){255, 255, 255}; // 3rd cycle
  colors[white_led4] = (rgb_color){255, 255, 255}; // 4th cycle
   
  // Write the colors to the LED strip. 
  ledStrip.write(colors, LED_COUNT); 

  // Changing this delay will change the speed of the LEDs
  delay(milli);
  delayMicroseconds (micro);
}

Any improvements are gladly welcome!!

Cheers,
Mike