Christmas lighting with ws2811/FastLED

That really doesnt help me now, does it? Still facing the adressing issue.

I'm even so far that i will accept settimg up all strips manually, because if i use less strips than i declare the surplus strips will simply not be adressed in the code.

But i really want to adress the strips in the code via an incremental counter.

Ive just benchmarked the code....the drop runs under 2ms, the star less than 1ms using 15 LEDs. The shortest interval i am currently running (and i'm running really fast) is 30ms. So running 12 strips with 15 leds each should be easy once i get the declaration right....

CrossRoads:
Reply, and "Attach" it here, many folks won't download from Dropbox.

Or indeed, download a "zip" file as a general rule due to security risks.

Noone with an idea how i can talk to strips using incrementing loops?

I am getting nowhere with this at the moment

OK, i found this:

Now let's get a little fancier. In order to make a dot that moves from one led strip to the next using the example above, you'd have to have some really ugly code to "pick" the current strip you were writing to. Or a lot of duplicated code. That's never any fun. Instead, here's a technique for using an array of arrays. Where before you had individual CRGB arrays of leds, now you have an array of CRGB arrays of leds (this example is in Examples, under Multiple/ArrayOfLedArrays):

#include "FastLED.h"
#define NUM_STRIPS 3
#define NUM_LEDS_PER_STRIP 60
CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];

This has set up a two dimensional array. If you want to access the first led on the first strip, you would use leds[0][0]. If you wanted to access the third led on the second strip, you would use leds[1][2] and so. Setup looks mostly the same, except now we have to tell it which array to use for each strip:

void setup() {
FastLED.addLeds<NEOPIXEL, 10>(leds[0], NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 11>(leds[1], NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 12>(leds[2], NUM_LEDS_PER_STRIP);

}

I tried to get fancy and did this:

for (i=0; i< Strips; i++) {
k=i+2;
FastLED.addLeds<WS2811, StripPin , RGB>(Strip_, ledNumber*); //initialize strips*
}[/quote]
All good and nice ... ithought. Well wrong. During compiling i got this:
> exit status 1
> the value of 'StripPin' is not usable in a constant expression
Any ideas? Would be great to not have to manually change everything if i change number of LEDs, Strips or something else...._

Paul__B:
On the other hand, the forum server itself is fouled up and returns them with bogus MIME (or whatever it is) types which mucks up the web browser. Some years ago it used to work properly but then was "updated". :astonished:

MIME is Multipurpose Internet Mail Extension. If you upload a GIF file with a JPG extension, you will confuse the MIME protocol and weird things happen.

Miniflyer:
OK, i found this:

I tried to get fancy and did this:

All good and nice ... ithought. Well wrong. During compiling i got this:

Any ideas? Would be great to not have to manually change everything if i change number of LEDs, Strips or something else....

When you are wondering what the function is expecting, look at the FastLED.h file.
It appears that .addLeds is expecting a pointer for the pin.

static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0);

BUT, pointers is definitely not my strong point. You might try making an array of pointers to the data pins and index the pins like this: ledPin[0] for the first data pin.

On the other hand, I fail to see why. This is for Christmas 2020? I don't think you will figure this out by this next Christmas.

Miniflyer:
OK, i found this:

I tried to get fancy and did this:

for (i=0; i< Strips; i++) {

k=i+2;
 FastLED.addLeds<WS2811, StripPin , RGB>(Strip, ledNumber);  //initialize strips
}



All good and nice ... ithought. Well wrong. During compiling i got this:


exit status 1
the value of 'StripPin' is not usable in a constant expression



Any ideas? Would be great to not have to manually change everything if i change number of LEDs, Strips or something else....

The compiler needs a specific pin number in the FastLED.addLeds statement, because it needs to generate some pin-specific machine code that cannot be done at runtime.

Miniflyer:
Any ideas? Would be great to not have to manually change everything if i change number of LEDs, Strips or something else....

Most of the code can be done with arrays, but the actual FastLED.addLeds statements have to be done individually. If you know the maximum number of LED strips you will be using, you can use compiler directives to selectively include only as many FastLED.addLeds statements as needed. As for using varying numbers of LEDs per strip, setting up a multi-dimensional array for that would be complex, probably involving an array of pointers to the actual LED arrays. If you have sufficient memory, its probably easier to make all LED arrays the length of the longest strip, and have the code handle the actual length, having FastLED send data for 25 pixels to a strip that only has 15 LEDs doesn't do any harm except for the slightly longer time needed.

Here is a modified version of SteveMann's code that will let you set from 1 to 8 strips, the only thing you need to change is the definition of NUM_STRINGS on line 9 and the rest of the code will adjust automatically.

#include <FastLED.h>

#define SKETCH "Curtain8cOTA.ino"

#define DEBUG false  //set to true for debug output, false for no debug ouput
#define Serial if(DEBUG)Serial

const byte NUM_LEDS = 25; // Per string
#define NUM_STRINGS  8    //number of LED strings, maximum of 8
const byte DATA_PIN1 = 2; //only necessary to define pins for the number of strings actually used
const byte DATA_PIN2 = 3; //any additional pin definitions will be ignored
const byte DATA_PIN3 = 4;
const byte DATA_PIN4 = 5;
const byte DATA_PIN5 = 6;
const byte DATA_PIN6 = 7;
const byte DATA_PIN7 = 8;
const byte DATA_PIN8 = 9;
const byte BRIGHTNESS = 100;
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB

CRGB leds[NUM_STRINGS][NUM_LEDS]; // This is an array of leds.  One item for each led in your strip.
CRGB leds_Saved[NUM_STRINGS];     // Save the LED color here (for the drip function)

// Variable holding the timer value so far. One for each string of LEDs
unsigned long leds_timer[NUM_STRINGS];

// Time periods of drips in milliseconds
unsigned long leds_Interval[NUM_STRINGS];

unsigned long dripSpeedFast = 2U;
unsigned long dripSpeedSlow = 75U;

// Delay between drips (ms)
int intervalMin = 100;
int intervalMax = 500;

#define CurtainColor CRGB(0x001bff)  //Blue (r=00, g=1b, b=ff)

#define MGPu CRGB(0x8010ff) // Mardi Gras Purple
#define MGGr CRGB(0x2cb004) // Green
#define MGGo CRGB(0xff4a00) // Gold

// =========================== setup() ===========================
void setup() {
  Serial.begin(115200);
  Serial.println();
#ifdef SKETCH
  Serial.println(F(SKETCH));
#endif
  Serial.println(F("---------------"));

  // The initial interval between drips in milliseconds
  for (byte i = 0; i < NUM_STRINGS; i++) {
    leds_Interval[i] = random(intervalMin, intervalMax);
  }

  // sanity check delay - allows reprogramming if accidently blowing power w/leds
  delay(1000);

  // This tells the library that there's a strand of LED_TYPE on pin DATA_PIN1 to DATA_PIN3,
  // and those leds will use the led array leds_1 to leds_3, and there are NUM_LEDS of them.
  FastLED.addLeds<LED_TYPE, DATA_PIN1, COLOR_ORDER>(leds[0], NUM_LEDS).setCorrection(TypicalLEDStrip);
#if (NUM_STRINGS >= 2)
  FastLED.addLeds<LED_TYPE, DATA_PIN2, COLOR_ORDER>(leds[1], NUM_LEDS).setCorrection(TypicalLEDStrip);
#endif
#if (NUM_STRINGS >= 3)
  FastLED.addLeds<LED_TYPE, DATA_PIN3, COLOR_ORDER>(leds[2], NUM_LEDS).setCorrection(TypicalLEDStrip);
#endif
#if (NUM_STRINGS >= 4)
  FastLED.addLeds<LED_TYPE, DATA_PIN4, COLOR_ORDER>(leds[3], NUM_LEDS).setCorrection(TypicalLEDStrip);
#endif
#if (NUM_STRINGS >= 5)
  FastLED.addLeds<LED_TYPE, DATA_PIN5, COLOR_ORDER>(leds[4], NUM_LEDS).setCorrection(TypicalLEDStrip);
#endif
#if (NUM_STRINGS >= 6)
  FastLED.addLeds<LED_TYPE, DATA_PIN6, COLOR_ORDER>(leds[5], NUM_LEDS).setCorrection(TypicalLEDStrip);
#endif
#if (NUM_STRINGS >= 7)
  FastLED.addLeds<LED_TYPE, DATA_PIN7, COLOR_ORDER>(leds[6], NUM_LEDS).setCorrection(TypicalLEDStrip);
#endif
#if (NUM_STRINGS >= 8)
  FastLED.addLeds<LED_TYPE, DATA_PIN8, COLOR_ORDER>(leds[7], NUM_LEDS).setCorrection(TypicalLEDStrip);
#endif
  FastLED.setBrightness(BRIGHTNESS);

  // Start with all LEDs off.
  oneColor(CRGB::Black);
  delay(500);

  // Curtain color- the LEDs normal color
  //oneColor(CRGB::Blue);
  oneColor(CurtainColor);

  for (byte i = 0; i < NUM_STRINGS; i++) {
    leds_timer[i] = millis();
  }
}


// =================== loop() ===================
void loop() {
  byte i = rrandom (1, NUM_STRINGS);           // Drip random strings, no duplicates
  drip_x(i - 1);
  delay(random(intervalMin, intervalMax));
}

// =========================== oneColor() ===========================
void oneColor(CRGB myColor) {
  // Light the leds one at a time. Leave them on.
  for (int ledNum = 0; ledNum < NUM_LEDS; ledNum = ledNum + 1) {
    for (byte i = 0; i < NUM_STRINGS; i++) {
      leds[i][ledNum] = myColor;
    }
    FastLED.show();
    delay(10);        // Not needed, but you can see the leds light up sequentially.
  }
}

// =========================== drip_x() ===========================
// Drip a white LED along the string.
void drip_x(byte drip_strip) {
  // For each LED
  // save the current color, set the LED to white, delay, then restore the color.
  Serial.print(F("drip_"));
  Serial.print(drip_strip);
  Serial.println(F("..."));
  //for (i = 0; i <= NUM_LEDS; i++) {
  for (int8_t i = NUM_LEDS - 1; i >= 0; i--) {           // Reverse the direction of the drip
    Serial.println(i);
    leds_Saved[drip_strip] = leds[drip_strip][i];
    leds[drip_strip][i] = CRGB::White;
    FastLED.show();
    delay(random(dripSpeedFast, dripSpeedSlow));      // Speed of the drip.  Lower is faster
    leds[drip_strip][i] = leds_Saved[drip_strip];
    FastLED.show();
  }
  leds_timer[drip_strip] = millis();       // remember when we dripped
  leds_Interval[drip_strip] = random(intervalMin, intervalMax);
}

// =========================== rrandom() ===========================
// Generate a random number with no duplicates.
int rrandom(int low, int high) {
  // Generate a random number between 'low' and 'high'
  static int previous_i = 0;
  static int i = random(low - 1, high + 1);
  while (i == previous_i || i == low - 1 || i == high + 1) {
    i = random(low - 1, high + 1);
  }
  previous_i = i;
  return i;
}