Go Down

Topic: duplicating colour on three grouped led's (Read 201 times) previous topic - next topic

superspeedkings

Oct 15, 2020, 05:57 pm Last Edit: Oct 15, 2020, 08:39 pm by superspeedkings
I'm using a string of 50 pre-wired WS2811's running the excellent library-program 'DemoReel100'.
It produces a perfect display but now need to group the led's in clusters-of-three (for increased periphery brightness within acrylic pendants) with each groups 3 led's giving he same colour, as such, what changes do I need to make to the program, or are the changes required actually within the pattern-routines this program calls?


Here is the program:
----------------------------------------------------------------
Code: [Select]

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    3
//#define CLK_PIN   4
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    50
CRGB leds[NUM_LEDS];

#define BRIGHTNESS          96
#define FRAMES_PER_SECOND  30

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


// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void loop()
{
  // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();

  // 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
  }
  EVERY_N_SECONDS( 10 ) {
    nextPattern();  // change patterns periodically
  }
}

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

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

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

void rainbowWithGlitter()
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter)
{
  if ( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void confetti()
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

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

void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for ( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
  }
}

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;
  }
}

J-M-L

Please correct your post above and add code tags around your code:
[code] // your code is here [/code].

It should look like this:
Code: [Select]
// your code is here
(Also press ctrl-T (PC) or cmd-T (Mac) in the IDE before copying to indent your code properly)

-----

the changes are needed within the pattern-routines.
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

blh64

#2
Oct 15, 2020, 09:08 pm Last Edit: Oct 15, 2020, 09:29 pm by blh64
It really depends on what you mean by "clusters of 3" and how they are wired together

choices
1. You have 3 strands of LEDS, each with 50 leds.  Each strand has it's own data pin connection
2. You have 1 strand of  150 LEDS, arranged such that the first 50 leds should match the next 50, etc.

if #1, then look for the example of how to handle multiple strands and you will have to modify your pattern routines to do the same thing for all 3 strands

if #2, then you have to modify your pattern routines to do the same pattern for the first 50, second 50, last 50 like this
Code: [Select]

#define NUM_LEDS 150
void rainbow()
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS/3, gHue, 7);
  fill_rainbow( &(leds[50]), NUM_LEDS/3, gHue, 7);
  fill_rainbow( &(leds[100]), NUM_LEDS/3, gHue, 7);
}

superspeedkings

Hi.
My string is just 50 led's, wired sequentially (as bought), Data out to Data in over the entire string). Lets call them LED1, LED2 . . . LED50, although it will only go to LED48 (48 / 3 = 16 pendants).

I'd like to control them such that the first 'cluster' is [LED1, LED2, LED3], second cluster [LED4, LED5, LED6] ,repeat, up to LED48]. All three led's in the cluster I want to show exactly the same colour, ie, basically increasing the brightness at each pendant as there will be three led's.
 
As an electronics hardware engineer & assembly language programmer (PIC, Z80, 6800, 8085) I'd like to learn to use C programming, therefore do not want to solve this by simply re-wiring them, which is simple enough.


Mark.

J-M-L

#4
Oct 17, 2020, 07:01 pm Last Edit: Oct 17, 2020, 07:03 pm by J-M-L
as discussed you need to modify he original version in the library.

Indeed your code calls
Code: [Select]
void rainbow()
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}
so it's basically a wrapper for the fill_rainbow() function which is pretty easy to read, here is what it looks like. first an HSV (color) is created and then there is a for loop going through every pixels setting the hue to an increasing value.
Code: [Select]
void fill_rainbow( struct CRGB * pFirstLED, int numToFill,
                  uint8_t initialhue,
                  uint8_t deltahue )
{
    CHSV hsv;
    hsv.hue = initialhue;
    hsv.val = 255;
    hsv.sat = 240;
    for( int i = 0; i < numToFill; i++) {
        pFirstLED[i] = hsv;
        hsv.hue += deltahue;
    }
}


That the for loop to change
Code: [Select]
    for( int i = 0; i < numToFill; i++) {
        pFirstLED[i] = hsv;
        hsv.hue += deltahue;
    }
just use the same hue for 3 adjacent pixels (make sure not to overflow) and increase the hue (a bit faster)
Code: [Select]
    for( int i = 0; i <= numToFill-2; i+=3) {
        pFirstLED[i] = hsv;
        pFirstLED[i+1] = hsv;
        pFirstLED[i+2] = hsv;
        hsv.hue += 3*deltahue;
    }


(typed here, untested)

of course you should create a new function in the library so that you don't modify the original fill_rainbow() function
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Deva_Rishi

Quote
as discussed you need to modify he original version in the library.
Since these effects are not blocking in nature (as far as i can tell) you can let the effect create a pattern within 50 leds. create the buffer for 150 leds and copy every pixel into 3 other pixels
Code: [Select]
CRGB leds[NUM_LEDS*3];
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS * 3).setCorrection(TypicalLEDStrip);
and within loop
Code: [Select]
// send the 'leds' array out to the actual LED strip
  uint8_t i = NUM_LEDS;
  while (i > 0) {
    i--;   
    leds[i * 3] = leds[i];
    leds[i * 3 + 1] = leds[i];
    leds[i * 3 + 2] = leds[i];
  }
  FastLED.show();
Simply like this, just before the call to .show() you copy each pixel 3 times, and if you do this in reverse you don't need a separate buffer to do this. (i think i did it right with 'i' but check just in case. It's 11 p.m. over here, but i'm sure you get the jist. )
To 'Correct' you have to be Correct. (and not be condescending..)

Deva_Rishi

Code: [Select]
// insert a delay to keep the framerate modest
  FastLED.delay(1000 / FRAMES_PER_SECOND);
Oh yeah, this is nonsense, FastLED.delay() calls .show() until the time expires, it's is just pointless. a normal delay at least allows for interrupts to be executed. And this actually increases the framerate although you are sending the same frames over and over again.
To 'Correct' you have to be Correct. (and not be condescending..)

blh64

Since these effects are not blocking in nature (as far as i can tell) you can let the effect create a pattern within 50 leds. create the buffer for 150 leds and copy every pixel into 3 other pixels
Code: [Select]
CRGB leds[NUM_LEDS*3];
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS * 3).setCorrection(TypicalLEDStrip);

and within loop
Code: [Select]
// send the 'leds' array out to the actual LED strip
  uint8_t i = NUM_LEDS;
  while (i > 0) {
    i--;    
    leds[i * 3] = leds[i];
    leds[i * 3 + 1] = leds[i];
    leds[i * 3 + 2] = leds[i];
  }
  FastLED.show();

Simply like this, just before the call to .show() you copy each pixel 3 times, and if you do this in reverse you don't need a separate buffer to do this. (i think i did it right with 'i' but check just in case. It's 11 p.m. over here, but i'm sure you get the jist. )
The OP stated there are only 50 LEDs, not 150.  They will need to create an LED array of size 16, fill it with the desired pattern, and then copy it out to the 48 actual LEDs

Deva_Rishi

Quote
The OP stated there are only 50 LEDs, not 150.  They will need to create an LED array of size 16, fill it with the desired pattern, and then copy it out to the 48 actual LEDs
If you would have read and understood the code, you would see that NUM_LEDS can be any value. 16 or 50 doesn't matter.
To 'Correct' you have to be Correct. (and not be condescending..)

J-M-L

If you would have read and understood the code, you would see that NUM_LEDS can be any value. 16 or 50 doesn't matter.
Sure if you read the code and get it the. It's obvious.

But I would say It does matter for clarity for the OP as NUM_LEDS was his total number of individual LEDS and in your code it's just a third of the number of LEDS.

Hence the confusion probably

That being said smart way for doing this.
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

blh64

If you would have read and understood the code, you would see that NUM_LEDS can be any value. 16 or 50 doesn't matter.
I did. And I did but the OP may not.

Deva_Rishi

when i read about his experience with programming, i am quite confident he'll get it.
Quote
As an electronics hardware engineer & assembly language programmer (PIC, Z80, 6800, 8085) I'd like to learn to use C programming, therefore do not want to solve this by simply re-wiring them, which is simple enough.
To 'Correct' you have to be Correct. (and not be condescending..)

Go Up