Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is most likely no translated for the post!





LED Effects - Candy...
 
Share:
Notifications
Clear all

LED Effects - Candy Cane  


 Hans
(@hans)
Prominent Member Admin
Joined: 8 years ago
Posts: 901
Topic starter  

Based on a request by James, here two examples of a Candy Cane effect.
Both effects use shifting of LED positions (move each LED color over one position and add a new one at the beginning of the strand).

The first one is the simplest, but you'll have to make sure the the block width * 3 divides nicely with your LED count.
The reason for this is that the last LED will be used to color the first new LED.
So for example with 60 LEDs, we'd like to make 3 blocks of 10, or 3 blocks of 20, which makes it that the last LED indeed is the correct color for the new first LED.

With both you can define your own colors (3), block width, and speed (WaveDelay higher = slower scrolling).

The colors can be predefined FastLED colors, for example CRGB::Black, or a user defined color, for example CRGB(0,0,0).

#include "FastLED.h"
#define NUM_LEDS 60
CRGB leds[NUM_LEDS];
#define PIN 6

#define NumberOfColors 3
void setup() { FastLED.addLeds< WS2811, PIN, GRB >(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); } void loop() { CandyCaneSimple(CRGB::Red, CRGB::White, CRGB::Blue, 10, 100); } void CandyCaneSimple(CRGB Color1, CRGB Color2, CRGB Color3, int BlockWidth, int WaveDelay) { int LedPosition; CRGB lastLedColor; if(Instant) { // Fill initial pattern for(int i=0; i < NUM_LEDS; i=i + (NumberOfColors*BlockWidth) ) { for (int ColorCounter=0; ColorCounter < NumberOfColors; ColorCounter++) { for(int BlockLEDCounter=0; BlockLEDCounter < BlockWidth; BlockLEDCounter++) { LedPosition = i + (ColorCounter*BlockWidth) + BlockLEDCounter; if( LedPosition < NUM_LEDS) { switch (ColorCounter) { case 0: leds[LedPosition] = Color1; break; case 1: leds[LedPosition] = Color2; break; case 2: leds[LedPosition] = Color3; break; } } } } } } else { // Black for all LEDs fill_solid(leds,NUM_LEDS,CRGB::Black); } FastLED.show(); delay(5000); // Scrolling bars while(true) { lastLedColor = leds[NUM_LEDS-1]; memmove( &leds[1], &leds[0], (NUM_LEDS-1) * sizeof(CRGB) ); leds[0] = lastLedColor; FastLED.show(); delay(WaveDelay); } }

 

The second one allows for a little more flexibility, since it will determine what the new first LED should be, and it allows for a slow start (Instant = false) where the color bar slowly build up.
If instant = true then the entire strand is first filled with blocks and after that is starts scrolling.

#include "FastLED.h"
#define NUM_LEDS 60
CRGB leds[NUM_LEDS];
#define PIN 6

void setup()
{
  FastLED.addLeds < WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
}

void loop() {
  //CandyCane(CRGB::Blue, CRGB::White, CRGB::Red, 6, 100, false);
  CandyCane(CRGB::Blue, CRGB::White, CRGB::Red, 8, 100, true); 
}

void CandyCane(CRGB Color1, CRGB Color2, CRGB Color3, int BlockWidth, int WaveDelay, bool Instant) {
  #define NumberOfColors 3
  int BlockLEDCounter;
  int ColorCounter;
  int LedPosition;
  
  if(Instant) {
    // Fill initial pattern
    for(int i=0; i < NUM_LEDS; i=i + (NumberOfColors*BlockWidth) ) 
    {
      for (ColorCounter=0; ColorCounter < NumberOfColors; ColorCounter++) 
      {
        for(BlockLEDCounter=0; BlockLEDCounter < BlockWidth; BlockLEDCounter++) 
        {
          LedPosition = i + (ColorCounter*BlockWidth) + BlockLEDCounter;
          
          if( LedPosition  <  NUM_LEDS) {
            switch (ColorCounter) 
            {
              case 0: leds[LedPosition] = Color1; break;
              case 1: leds[LedPosition] = Color2; break;
              case 2: leds[LedPosition] = Color3; break;
            }
          }
        }
      }
    }
  }
  else
  {
    // Black for all LEDs
    fill_solid(leds,NUM_LEDS,CRGB::Black);
  }

  FastLED.show();
  
  // Scrolling bars
  BlockLEDCounter = 0;
  ColorCounter = 0;
  
  while(true) 
  {
    memmove( &leds[1], &leds[0], (NUM_LEDS-1) * sizeof(CRGB) );

    switch (ColorCounter) 
    {
      case 0: leds[0] = Color3; break;
      case 1: leds[0] = Color2; break;
      case 2: leds[0] = Color1; break;
    }

    FastLED.show();
    
    BlockLEDCounter++;
    
    if (BlockLEDCounter==BlockWidth) 
    {
      BlockLEDCounter = 0;
      ColorCounter++;
      if (ColorCounter==NumberOfColors) {
        ColorCounter = 0;
      }
    }
    
    delay(WaveDelay);
  }
}

 

 


ReplyQuote
Share: