Christmas lighting with ws2811/FastLED

Hi guys,

following idea: I want to make christmas lighting for a garden shack. It should consist of various strips of different lengths hanging down from the roof. (Each strip will get a designated Arduino Pin).
For this i have gotten RGB-LED strips with ws2811 chips for designation, and an Arduino Nano.

Lighting: I want all LEDs to light at a warmwhite-similar dimmed status. In first stage i want to make individual LEDs to transition to full power white and go back to the dimmed warmwhite (like twinkling stars). Later on i will want to add warmwhite "comet" or "raindrop" effects.
Since the raindrops and the stars will be frequently called and also running simultaneously, i want to have those in an "external" function so i can pick a random strip, a random LED, and call the function. I do not want to use delay() because while one sparkle is running i will be having others start to sparkle, or start a raindrop.....

Right now im at the point where i light up a single strip at a dimmed level, and want to make a random LED "sparkle". However, it does not always loop the function as i want....
I have set up the RGB designation via a matrix function.
With the code i have written, the void star() function is called, it runs once, but then does nothing until the next star is selected......
Can someone help? I need to run the loop over and over, changing the affected LEDs on each run....

#include <FastLED.h>

#define Strips 1
#define Strip1_PIN 13
#define Strip1_LEDS 5

byte dropBlue=23;
byte dropRed=255;
byte dropGreen=103;
float BaseBrt=0.02;
byte dropLength=10;

byte starBlue=255;
byte starRed=255;
byte starGreen=255;
byte starSteps=50;
byte starfade=40;
int starstands=400;

byte SBlue;
byte SRed;
byte SGreen;

byte s1Matrix[Strip1_LEDS][4];

const unsigned long starInterval = 10000; //milliseconds. 
static unsigned long laststar=0;

CRGB Strip1[Strip1_LEDS];

void setup() {
  // put your setup code here, to run once:
FastLED.addLeds<WS2811, Strip1_PIN, RGB>(Strip1, Strip1_LEDS);

for (byte i = 0; i < (Strip1_LEDS-1); i = i + 1) {
  s1Matrix[i][0]=dropBlue*BaseBrt;
  s1Matrix[i][1]=dropRed*BaseBrt;
  s1Matrix[i][2]=dropGreen*BaseBrt;
  s1Matrix[i][3]=0;
  Strip1[i] = CRGB (s1Matrix[i][0], s1Matrix[i][1], s1Matrix[i][2]) ;
}
FastLED.show();

Serial.begin(115200);

}

void loop() {
 
  if(millis() - laststar > starInterval) {
    laststar = millis(); //record when star started
    star();
    Serial.println(millis());
   
 }
}

void star() {
  byte starLed = random(Strip1_LEDS);
  Serial.println(starLed);
  SBlue=s1Matrix[starLed][0];
  SRed=s1Matrix[starLed][1];
  SGreen=s1Matrix[starLed][2];
  float stepBlue=(starBlue-SBlue)/starSteps;
  float stepRed=(starRed-SRed)/starSteps;
  float stepGreen=(starGreen-SGreen)/starSteps;
  byte j=0;
   if((millis() > laststar + ((j+1)*starfade)) && (j<=starSteps-1) &&  (millis() < laststar + ((starSteps+1)*starfade))  ) {
    j++;
      s1Matrix[starLed][0]=SBlue+(j*stepBlue);
      s1Matrix[starLed][1]=SRed+(j*stepRed);
      s1Matrix[starLed][2]=SRed+(j*stepRed);
      Strip1[starLed] = CRGB (s1Matrix[starLed][0], s1Matrix[starLed][1], s1Matrix[starLed][2]) ;
      FastLED.show();
      Serial.println(j);
   }
  
if((millis() > laststar + (starSteps*starfade)+ starstands+ ((starSteps-j)*starfade)) && (j>0)) {
    j--;
      s1Matrix[starLed][0]=SBlue+(j*stepBlue);
      s1Matrix[starLed][1]=SRed+(j*stepRed);
      s1Matrix[starLed][2]=SRed+(j*stepRed);
      Strip1[starLed] = CRGB (s1Matrix[starLed][0], s1Matrix[starLed][1], s1Matrix[starLed][2]) ;
      FastLED.show();

 }  
  
}

what is happening now and what do you want to have happen, i can’t quite make it out based on your description,.

here is an example of a twinkle affect.

You mean something like this?

I just installed these a day before the snow started. There's 8 WS2811 strings of 25 LEDs, each on a different pin on a Wemos D Mini. If you are interested I can share the code.

SteveMann:
You mean something like this?

Where's the music?

Shouldn't you have more than one snowflake at a time?

OK i found my error. By using the BlinkWithoutDelay function, i called the code only once. What i needed was to call the code continuously, but only responding if the time has elapsed. This can be achieved by moving the BlinkWirhoutDelay function to within the called void().

Have been able to solve this part of the problem, and i am now at the point where i have a constant glow to all LEDs in warmwhite, and can randomly flash coldwhite stars with defined fadespeed and duration.

Now i will implement the "meteor" function....

There is another problem i have, but i will post it in the coding section, since it is a more general issue. I will report how it goes.

Steve: is Wemos and Arduino compatible?

Miniflyer:
There is another problem i have, but i will post it in the coding section, since it is a more general issue. I will report how it goes.

Probably not a good idea, since it would be a form of "cross posting" where not only have you already described your system in this thread, but people have contributed to it. If you post a different thread, then not only do you have to repeat all of your original description, but someone looking at that thread will not know what has already been posted to this, which tends to waste their time.

Miniflyer:
Steve: is Wemos and Arduino compatible?

What does that mean?

You program the WeMOS (D1 Mini) with the Arduino IDE using essentially the same libraries since they are "C" and reasonably processor agnostic. Pin allocations will change of course. :grinning:

Paul__B:
Where's the music?

Shouldn't you have more than one snowflake at a time?

I had a version that was sort-of working with multi drips, but I wasn't happy with it by the deadline, so I fell back to the stable version of one at a time, but random.
I have a second Wemos in the control box and when the snow melts, I may move four of the stings to it and run the same sketch on both. This way I will have two at a time dripping at random.

Wemos D1 Mini's are dirt cheap; for less than 20 bucks you could just use a D1 mini on each string...

DrAzzy:
Wemos D1 Mini's are dirt cheap; for less than 20 bucks you could just use a D1 mini on each string...

Next year.
The controller box is under a foot of snow and it's going to be in the 20's tonight.

Multi Wemo's sounds like a good idea. I could probably do it even cheaper with eight 8266-01 boards.

SteveMann:
I could probably do it even cheaper with eight 8266-01 boards.

I am very happy with them. Two I/O immediately available, another two if you forego the serial - which is mostly only for programming anyway.

I like these modules which attach them directly to a "Phone charger".

Paul__B:
Probably not a good idea, since it would be a form of "cross posting" where not only have you already described your system in this thread, but people have contributed to it. If you post a different thread, then not only do you have to repeat all of your original description, but someone looking at that thread will not know what has already been posted to this, which tends to waste their time.

True, BUT my question was totally off topic here. It is a very very basic IDE question, so i believe it will a) help more people if described there, and b) probably will be answered more quickly than if its just read by 5 or 6 guys involved with LEDs and clicking in here.

Aaaanyway, i have now finished a code which works pretty decent for 1 strip on the Nano. You can show one star within the strip at a time, at a random position in the Strip. You can predefine color of the star, amount of steps in the fade-in and fade-out, speed of the fade, duration of stay at full brightnes, and another random value which chooses the interval to the next stars within 2 values set by you.
For the drops you can define the color of the drop, a percentage value for this color (which forms the base hue for the entire strip), the speed the drop is travelling and the length of the comet trail.

Next step is to change the code so it can accomodate more than one pin. So Pin 2 runs strip 1, pin 3 strip 2 and so on. First i need to see how long the code runs for each strip....it will probably limit the amount of strips run by a single nano. I hope it will be quick enough to run 5-6 strips in paralell.....

Here is an external GIF, internal hosting is not working somehow:
https://gifyu.com/image/vrVi

Thanks, probably easier linking it like that :wink:

OK i have another issue:
I am now trying to code the code in a way that it can be initialised by defining Number of Strips (byte) and Number of LEDs per Strip (Array of bytes containing the LED count for each strip).
For instance: i could add 12 strips on an Arduino Nano, with lengths ranging between 8 and 15 LEDs.

What do i want to do? In the code, i want to modify ONLY:

1.) Pin definition
2.) Number of strips = 12
3.) Leds[Number of strips]={8,9,8,14,11,15,12,10,8,15,11,8}

Problem:

FastLED.addLeds<WS2811, Strip1_PIN, RGB>(Strip1, Leds[i]);

This is the Strip Definition does not allow me to setup with a for loop.
I want to ad a for loopfor (i=0, i<Number of strips, i++){}

Where each Strip is filled with the running number and the corresponding LEDs from the array....
The led count is working fine, but i cannot create a series of strip somehow.....

Miniflyer:
Here is an external GIF, internal hosting is not working somehow:

Ah yes, now I recall!
Some people assert it is better to upload images to the forum server. One reason is that the original may itself disappear or in fact, many image sites refuse to be linked to (so should be avoided like the plague!). :roll_eyes:

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:

Miniflyer:
OK i have another issue:
I am now trying to code the code in a way that it can be initialised by defining Number of Strips (byte) and Number of LEDs per Strip (Array of bytes containing the LED count for each strip).
For instance: i could add 12 strips on an Arduino Nano, with lengths ranging between 8 and 15 LEDs.

Here is my code- it may help. It is in a ZIP file on my DropBox because it's too long to post in code tags.

The 'setup_wifi' and 'start_OTA' are on tabs so if you want to compile my code, just comment these out in startup().

I have coded for eight arrays of 25 LEDs, but is would be easy to accommodate strings of different lengths. (I am using WS2811 Strings).

Creative criticism is welcome.

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

Would you trust my git?

Steve, thanks for sharing the code. But you are doing exactly what i want to avoid. You set up every strip manually, and have to run a seperate function for each strip.

I want to be able to setup the strips by just designating Pins and defining number of pins.

I want to be able to setup Strip, and then run a function Drop and Flake in a loop, instead of having to run 10 or 12 different functions that are fundamentally the same, but just speak to a different led....

I was facing a Thanksgiving deadline, so efficient or pretty code was not in the plan.
I may try making a C++ class or library of the almost identical functions, but I won't be finishing that any time soon. Mostly in learning time, not coding.