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);
}
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.
#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;
}
}
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.
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.
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.
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).
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.