Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

trouble coding multiple strips of addressable LEDs sk9822 a-star 32U4 mini SV

Error im getting:
“reference to ‘APA102’ is ambiguous”
how do i get 4 strips running the same code?

adapted from the apa102 XMAS example
Using the FastLED example for mirroring strips
(https://github.com/FastLED/FastLED/blob/master/examples/Multiple/MirroringSample/MirroringSample.ino)
or
https://github.com/pololu/apa102-arduino/blob/master/APA102.h
?
I know theres a bunch of extra stuff/its not the most succinct (aka why do i need a switch pattern if there’s one state) but every time I try to fix it something else goes wrong so here we are

//https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples

#include <FastGPIO.h>
#define APA102_USE_FAST_GPIO
#include <APA102.h>
#include <EEPROM.h>

#include "FastLED.h"



const uint8_t dataPin = 10; //do i get rid of this part and instead write it in as an addled thing or not?
const uint8_t clockPin = 12;
APA102<dataPin, clockPin> ledStrip; //i feel like this line is going to confuse line 36 but idk 

#define NEXT_PATTERN_BUTTON_PIN  2  // button between this pin and ground
#define AUTOCYCLE_SWITCH_PIN  3  // switch between this pin and ground

#define LED_COUNT 90
CRGB leds[LED_COUNT];
rgb_color colors[LED_COUNT];

const uint8_t globalBrightness = 15;//max 31
#define NUM_STATES  1

unsigned int loopCount = 0;
unsigned int seed = 0;  

enum Pattern {
  WarmWhiteShimmer = 0,
  AllOff = 255
};
unsigned char pattern = AllOff;
unsigned int maxLoops;  // go to next state when loopCount >= maxLoops


void setup()
{
  //https://github.com/FastLED/FastLED/wiki/SPI-Hardware-or-Bit-banging
  FastLED.addleds< APA102,9,8>(leds,LED_COUNT); // data, clock

  
  for (int i = 0; i < 8; i++)
  {
    seed += analogRead(i);
  }
  seed += EEPROM.read(0);  
  randomSeed(seed);
  EEPROM.write(0, random(256));
  pinMode(AUTOCYCLE_SWITCH_PIN, INPUT_PULLUP);
  pinMode(NEXT_PATTERN_BUTTON_PIN, INPUT_PULLUP);
  delay(10);  
}

void loop()
{
  uint8_t startTime = millis();

  handleNextPatternButton();

  if (loopCount == 0){
    for (int i = 0; i < LED_COUNT; i++) {
      colors[i] = rgb_color(0, 0, 0);
    }
  }

  if (pattern == WarmWhiteShimmer )
  {
    // for these two patterns, we want to make sure we get the same
    // random sequence six times in a row (this provides smoother
    // random fluctuations in brightness/color)
    if (loopCount % 8 == 0)
    {
      seed = random(30000);
    }
    randomSeed(seed);
  }

  // call the appropriate pattern routine based on state; these
  // routines just set the colors in the colors array
  switch (pattern)
  {
    case WarmWhiteShimmer:
      // warm white shimmer for 300 loopCounts, fading over last 70
      maxLoops = 300;
      warmWhiteShimmer(loopCount > maxLoops - 100);
      break;
      
  
  
  }

  // update the LED strips with the colors in the colors array
  ledStrip.write(colors, LED_COUNT, globalBrightness);

  // Make sure that loops are not too fast there are a small number
  // of LEDs and the colors are calculated quickly.
  while((uint8_t)(millis() - startTime) < 20) { }
  loopCount++;  // increment our loop counter/timer.

  if (loopCount >= maxLoops && digitalRead(AUTOCYCLE_SWITCH_PIN))
  {
    // if the time is up for the current pattern and the optional hold
    // switch is not grounding the AUTOCYCLE_SWITCH_PIN, clear the
    // loop counter and advance to the next pattern in the cycle
    loopCount = 0;  // reset timer
    pattern = ((unsigned char)(pattern+1))%NUM_STATES;  // advance to next pattern
  }
}


// This function detects if the optional next pattern button is pressed
// (connecting the pin to ground) and advances to the next pattern
// in the cycle if so.  It also debounces the button.
void handleNextPatternButton()
{
  if (digitalRead(NEXT_PATTERN_BUTTON_PIN) == 0)
  {
    // if optional button is pressed
    while (digitalRead(NEXT_PATTERN_BUTTON_PIN) == 0)
    {
      // wait for button to be released
      while (digitalRead(NEXT_PATTERN_BUTTON_PIN) == 0);
      delay(10);  // debounce the button
    }
    loopCount = 0;  // reset timer
    pattern = ((unsigned char)(pattern+1))%NUM_STATES;  // advance to next pattern
  }
}



void randomWalk(unsigned char *val, unsigned char maxVal, unsigned char changeAmount, unsigned char directions)
{
  unsigned char walk = random(directions);  // direction of random walk
  if (walk == 0)
  {
    // decrease val by changeAmount down to a min of 0
    if (*val >= changeAmount)
    {
      *val -= changeAmount;
    }
    else
    {
      *val = 0;
    }
  }
  else if (walk == 1)
  {
    // increase val by changeAmount up to a max of maxVal
    if (*val <= maxVal - changeAmount)
    {
      *val += changeAmount;
    }
    else
    {
      *val = maxVal;
    }
  }
}


// This function fades val by decreasing it by an amount proportional
// to its current value.  The fadeTime argument determines the
// how quickly the value fades.  The new value of val will be:
//   val = val - val*2^(-fadeTime)
// So a smaller fadeTime value leads to a quicker fade.
// If val is greater than zero, val will always be decreased by
// at least 1.
// val is a pointer to the byte to be faded.
void fade(unsigned char *val, unsigned char fadeTime)
{
  if (*val != 0)
  {
    unsigned char subAmt = *val >> fadeTime;  // val * 2^-fadeTime
    if (subAmt < 1)
      subAmt = 1;  // make sure we always decrease by at least 1
    *val -= subAmt;  // decrease value of byte pointed to by val
  }
}


// ***** PATTERN WarmWhiteShimmer *****
// This function randomly increases or decreases the brightness of the
// even red LEDs by changeAmount, capped at maxBrightness.  The green
// and blue LED values are set proportional to the red value so that
// the LED color is warm white.  Each odd LED is set to a quarter the
// brightness of the preceding even LEDs.  The dimOnly argument
// disables the random increase option when it is true, causing
// all the LEDs to get dimmer by changeAmount; this can be used for a
// fade-out effect.
void warmWhiteShimmer(unsigned char dimOnly)
{
  const unsigned char maxBrightness = 120;  // cap on LED brighness
  const unsigned char changeAmount = 13;   // size of random walk step 8

  for (int i = 0; i < LED_COUNT; i += 2) //1
  {
    // randomly walk the brightness of every even LED
    randomWalk(&colors[i].red, maxBrightness, changeAmount, dimOnly ? 1 : 2);

    // warm white: red = x, green = 0.8x, blue = 0.125x
    colors[i].green = colors[i].red*7/15; 
    colors[i].blue = colors[i].red*1/5 ;  
    

    // every odd LED gets set to a quarter the brighness of the preceding even LED
    if (i + 1 < LED_COUNT)
    {
      colors[i+1] = rgb_color(colors[i].red >> 2, colors[i].green >> 2, colors[i].blue >> 2);
    }
  }
}
void AllOn ()
{}



  1. where do plug the other ground connections in from the other 3 led strips?
  2. in this part :
    FastLED.addLeds<APA102,7,11>(leds,NUM_LEDS);
    instead of NUM_LEDS can I input the number for that strip? does each strip need the same # of leds for me to use the mirroring? will it hurt to use 120 as the established NUM_LEDS and then have a strip of 30?

HARDWARE

pololu a-star 32U4 mini sv

4 sk9822 strips/objects(?)
understanding each set of 180 needs separate 5v power
-120 leds 2 meter
-60 1 meter+ 60 1 meter
-30 1 meter +60 1 meter
-30 1/2 meter

1 toggle switch for the whole thing, right now its intercepting the power to the a*, but then the LEDs rest on not off- hopefully ill figure this out with googling

GOAL
weave lights into intricate braided wig to replicate this:
https://youtu.be/hUHRvOERDyE
(at the moment I’m settling for allover twinkle, but I want this so “realistic” little kids pee their pants with excitement and their parents are so impressed they throw money at me)
theoretically if the code isn’t written to have the lights eminate from the “scalp”, i could just get 7meters of wire and loop it back up to keep the whole thing in one chain, which is what i might end up doing if I cant figure this out

ANY INPUT IS MUCH APPRECIATED!!! THANK YOU!!!

Hello, kmelville.

You should use either the FastLED library or our library, not both. If you use our library, it is possible to instantiate multiple objects (one for each of your LED strips), each with its own data and clock pins. This would also allow you to specify the number of LEDs on each strip. It is probably not trivial to modify the XMAS example code to handle this; that code is already fairly complex, so you might be better off writing your own code from scratch.

If you really want all of the LED strips to do the same thing, another option could be to simply connect all of the LED strips to the same signal pins on your Arduino. However, if the LED strips are different lengths, they will match up differently. For example, the 30 LED strip will do the same thing as the first 30 LEDs in the 120 LED strip.

Brandon