One WS2812b strip displaying multiple colors/effects simultaneously

Hello all! I am currently working on a project where i need to be able to create multiple "zones" displaying a different effect simultaneously . I am hoping I can accomplish this with a single RGB strip but i cant find an example to try and learn from. Is this possible? or do I need to use and individual strip and pin per each zone? the former would be ideal since it would make for a neater overall job. ive been searching online for a few days now but cant seem to find anything using a single strip but instead multiple strips on each dedicated data pins.

I already have a working sketch that splits a strip into 3 zones and displays 3 separate static colors. I accomplished this using CRGBset. Can this be done with CRGBSet and CRGBArray? I am struggling trying to understand how i can add different effects to each zone with this current sketch.

what i want to accomplish is say have the beginning(0,5) of the strip display the built in fill_rainbow function and the middle(6,11) display a theater lights effect and so on. utlimatley i would like to add a push button to cycle it between static colors and a few effects with each button press but right now its important i learn how to accomplish the effects per zone.

I have included my current sketch. please note that the number of leds used in the sketch is not final. its just a strip i had laying around that i use to test sketches. please be kind and laymen's terms are helpful since i am no programmer, just a hobbyist.

Also I dont know if its helpful to you or not to know that the project in question is a sort of shadow box i made from wood. there are various cut outs in the shape of a flamingo, the sun, clouds, and some leaves. the cut outs are layered and painted white. I am using the RGB leds to illuminate the layers different colors. i could use the sketch as is and have static colors but thats no fun, i could just buy the colored leds and make a simple circuit. with the amount of effort im putting into the construction of this sign i want it to do more.

#include <FastLED.h>

#define DATA_PIN 3
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS  20
#define BRIGHTNESS 75
#define FRAMES_PER_SECOND  120

#define UPDATES_PER_SECOND 100



//sections single led strip into an array. add or remove CRBSet's to create or remove sections
//CRGB rawleds[NUM_LEDS]; 
CRGBArray<NUM_LEDS>leds;  
CRGBSet beginning(leds(0,5));
CRGBSet middle(leds(6,12));
CRGBSet ending(leds(11,19));

//set color to each section in the array
CRGB colorB(CRGB::Violet);
CRGB colorM(CRGB::Green);
CRGB colorE(CRGB::Blue);

//struct CRGB * ledarray[] ={beginning, ending};


void setup() {


  

  // put your setup code here, to run once:
 
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

FastLED.setBrightness (BRIGHTNESS);
}



void loop() {
beginning = colorB;
middle = colorM;
ending = colorE;


  

  FastLED.show();  
  FastLED.delay(1000); 

}

All perfectly possible, is just a matter of coding. Every led in the strip can be set to any colour and brightness individually, so any combination of these patterns can be achieved, but it will require more than beginner level coding skills.

I suggest you pick 3 patterns you want to combine on a single strip and post the separate code for all 3. We can have a look at those for you and pinpoint some of the challenges that will need to be dealt with, and guide you through the process. But I suspect you will need to be prepared to level-up your coding skills, which we will be very pleased to assist with as long as you remain patient, willing and motivated to learn. We don't like cry-babies who want everything done for them around here!

Not sure the RGBset feature you found will be useful or not, I never saw it before, but if we see a good use for it, we will try to point it out to you.

The most difficult aspect of getting 3 patterns working together will not be limiting each pattern to it's designated part of the strip, but preventing each pattern's animation code from "blocking" the animation code of the other patterns. The Arduino only has one CPU core and no multi-tasking operating system, so the animation code of each pattern may have to be partially re-written to stop it "hogging" the CPU.

I have no issue with trying learn something and in no way expect anyone to just do it for me. If i can get the desired look out of this project it may become something start making to sell at craft shows or just for fun or friends. I have made a couple signs that just use a simple pattern or static colors and have had people express interest in them. Each sign has been a learning experience both in wood working and coding for arduino using fastled. So it would benefit me greatly to actually know what the hell I am doing here.

I am here to learn, its hard stuff for me to wrap my head around just by reading up. I unfortunately suffer from a bit of dyslexia when it comes to numbers and math and that makes this difficult for me to grasp certain things at first. Ive always been more of a visual learner and most documentation available is not visual. I have always said if you tell me how to do something you will have to tell me at least 3 times, but you only need to show me once.

Im not set on any particular effect or pattern just yet so I have been attempting things using effects available in the demoreel100 example included with the fastled library. fill rainbow or some variation of that will most definitely be used. I have Included 3 examples in different code brackets though.

juggle effect

void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }

sinelon effect

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( gHue, 255, 192);
}

Rainbow

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);

I just copied and pasted these from the example so i know they will have to tweaked to work. hopefully this is what you needed.

It would be better to post complete sketches so we can see how those functions are called and what else the sketch needs to do.

But based on what you posted, it doesn't look too hard. This code does not seem to be the "blocking" type of code I was anticipating, so that will make things a lot easier. All we need to do, hopefully, is restrict which leds each one affects.

Two of them use a FastLED function, beatsin16(). For example:

  int pos = beatsin16( 13, 0, NUM_LEDS-1 );

Here, we can just update the second and third parameters ("0" and "NUM_LEDS-1" above) to the range we want to affect, like this:

  int pos = beatsin16( 13, 6, 11 );

which should only affect leds 6 to 11 instead of all leds in the strip.

However, these two functions are a little more tricky:

  fill_rainbow( leds, NUM_LEDS, gHue, 7);

and

  fadeToBlackBy( leds, NUM_LEDS, 20);

These functions affect all leds in the strip. We need to find a way to restrict them to just parts of the strip.

I got this to compile and have tested it:

#include <FastLED.h>

FASTLED_USING_NAMESPACE

// FastLED "100-lines-of-code" demo reel, showing just a few 
// of the kinds of animation patterns you can quickly and easily 
// compose using FastLED.  
//
// This example also shows one easy way to define multiple 
// animations patterns and have them automatically rotate.
//
// -Mark Kriegsman, December 2014

#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define DATA_PIN    7
//#define CLK_PIN   4
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define NUM_LEDS    60
CRGB leds[NUM_LEDS];

#define BRIGHTNESS          64
#define FRAMES_PER_SECOND  120

void setup() {
  delay(3000); // 3 second delay for recovery
  
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
}


uint8_t gHue = 0; // rotating "base color" used by many of the patterns
  
void loop()
{

  rainbow(0, 19);
  sinelon(20, 39);
  juggle(40, 59);

  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND); 

  // do some periodic updates
  EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
}

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))


void rainbow(int firstLed, int lastLed) 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( &leds[firstLed], lastLed-firstLed+1, gHue, 7);
}


void sinelon(int firstLed, int lastLed)
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( &leds[firstLed], lastLed-firstLed+1, 20);
  int pos = beatsin16( 13, firstLed, lastLed );
  leds[pos] += CHSV( gHue, 255, 192);
}

void juggle(int firstLed, int lastLed) {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( &leds[firstLed], lastLed-firstLed+1, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, firstLed, lastLed )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}
1 Like

that code appears to be working perfectly!!! i had to make adjustments to the led count but it works as expected as far as i can tell. can i just say how frustrating it is to spend days on a problem only to have someone figure it out in a second! my greatest gratitude sir! im sure i will have some follow up questions. Im currently at work and shouldnt even really be messing with this right now but my curiosity gets the better of me usually.

i will go over all this when i get home and try to learn what is making it work. I think i have an idea of whats going on here. Thank you agian for your help!

Don't feel too frustrated. I've been coding for 40 years in many languages.

Please do ask questions. I'm already feeling a little guilty for helping you too much, so it's important to me that you learn and understand what I changed.

dont feel guilty. this sketch works but is not really my end goal. I intend to learn as much as I can. Basically I am making these signs that are using fastled to illuminate zones a different color. I want to add a button function to these signs eventually that cycles the zones from static colors to different effects/ colors/ patters ect. ideally the end result of the sketch will allow me to plug in different effects and colors with just a few minor changes to the code. I decided to start with well known effects available in the fastled library because they're easily accessible to the people who im going to be bugging for questions! I really do want to understand how to code these lights. I have been fascinated with fastled and arduino since i came across some reddit posts a while back.

on to my follow up questions. One of my biggest struggles is trying to learn what all the data values are acutlly representing and how to fill that.

for example

  int pos = beatsin16( 13, 6, 11 );

as I was typing out this response I had and AH-HA! moment. beatsin16(13, start of leds, end of leds)
I never put together that every time i saw that code the 0 referred to the start positon and NUM_LEDS was the end position. Im still not sure what the 13 refers to though.

you stated these parameters needed to be changed to work. but how do i find those parameters are referring to for various fastLED functions. not just beatsin16. also....what does beatsin16 do exactly?

I basically had made a similar sketch using the fill rainbow, but didnt know how to set up the parameters. but i see it was not that easy for fill_rainbow anyhow.

you defined an array size this is where i get confused with your code. i see an array then you created ints for firstled and lastled. im at a loss for how this works

im also confused on what things are built in functions to the fastLED library and whats not. like ghue for example. ive seen that in multiple sketches but never used it myself.

I have many more questions but ill start with this for now.

Good to hear you asking important questions. Too tired tonight. Will try to answer over the weekend.

To find documentation about libraries, use Google. For example search for "FastLED beatsin16".

In C, functions always have brackets after their names, even if they have no parameters. Variables don't. So gHue is a variable.

fadeToBlackBy( leds, NUM_LEDS, 20);

This function needs to be given an array of led "objects" to work on, and the length of the array. The array being given to it is "leds" but in fact what actually happens in C is that, rather than passing a copy of the entire array, a pointer or reference to the first element of the array is passed. The function can then access any other element of the array because they are all stored consecutively in memory, so leds[1] is immediately after leds[0] and so on. When you write "leds" in your code, that's a pointer to the first element. But when you write "leds[20]" that's the value of the 21st element, not a pointer to the 21st element. Array indices start at zero in C, so leds[0] is the first element and leds[1] is the second.

fadeToBlackBy( &leds[firstLed], lastLed-firstLed+1, 20);Here, I'm fooling the function into working on only part of the array. Suppose firstLed is 20 and lastLed is 39. The above becomes
fadeToBlackBy( &leds[20], 39-20+1, 20);The "&" turns the value of the 21st element into a pointer or reference to that 21st element. So the function receives a pointer to an array and is told that the array is 39-20+1=20 elements long. The function does not know or care that the array it has been given is in fact part of a larger array.

1 Like

I think I understand. the code using the actual math makes more sense to me except one thing

39-20+1=20 elements long

and the code is written

fadeToBlackBy( &leds[20], 39-20+1, 20);

is the 20 written at the end of the code the answer to the equation? or another parameter all together?

also when it is written

fadeToBlackBy( &leds[firstLed], lastLed-firstLed+1, 20);

how does the function know what the ints firstLED and lastLED are? Are firstLED and lastLED built in functions to call on or am I missing something?

so far I now understand how to tell a function where to start using &leds[value]

thanks for your help again.

1 Like

is the 20 written at the end of the code the answer to the equation? or another parameter all together?

Its a completely different parameter that just happens to have been given the same value. Go look up the function using Google.

how does the function know what the ints firstLED and lastLED are? Are firstLED and lastLED built in functions to call

You can tell that firstLed and lastLed are not functions, as I explained in post #9. They are parameters I added to the function:

void sinelon(int firstLed, int lastLed)

If you check the original version, you'll see that it had no parameters. Parameters are given values when a function is called, like this:

sinelon(20, 39);
1 Like

so if im understanding, in the code

void sinelon(int firstLed, int lastLed)

firstLED and lastLED are getting the values from

sinelon(20, 39);

that was set up in the void loop?

Its a completely different parameter that just happens to have been given the same value. Go look up the function using Google.

I did end up finding out what the end parameter is representing. it fades the led by an amount of 20/256th. according to a reddit post I found. The wiki did not specify what the parameters are for fadeToBlackBy(). at least not that I could find.

1 Like

Correct about the parameters.

fadeToBlackBy() is listed in this page but there's no description. The parameter names are shown, but you could have got that from the .h file (which is what the page is auto-generated from).

1 Like

PaulRB:
Correct about the parameters.

fadeToBlackBy() is listed in this page but there's no description. The parameter names are shown, but you could have got that from the .h file (which is what the page is auto-generated from).

Thank you so much for your help PaulRB! I feel I have a much better understanding on how to work with fastLED and coding arduino in general now. I've been to that page before and it is all very confusing considering I didnt know what to look for, but I am much better informed now thanks to you. I looked that page over again and it makes more sense to me now that I have a better understanding of functions and how to call on those functions.

Last night I finished wiring up my string of leds to my project and tested them out. I successfully separated the strip into 7 segments totaling 53 LEDs. so far i only used a static color for each segment but instead of setting it up using CRGBset like I was initially I now have it set up they way you have showed me.

The next challenge for me will be to set it up on a button to switch it from static colors to effects. Considering my initial question on this post has been answered I will make a new topic if I run into any problems I cannot figure out on my own. Im feeling much more confident than before though.

1 Like