Two effects in one strip using FASTLED in arduino nano

hi, I want to create two effects in the same led strip, is it possible? or do I need to use two strips to control each effect? I just want to use an arduino nano for it.

i wish to combine a lightning effect and a monowave.

#include "FastLED.h"

#define NUM_LEDS      13
#define LED_DT        2
#define LED_CK        11
#define COLOR_ORDER   GRB
#define CHIPSET       WS2812
#define FREQUENCY     20                // controls the interval between strikes
#define FLASHES       8                 // the upper limit of flashes per strike
#define BRIGHTNESS    255

CRGB leds[NUM_LEDS];

unsigned int dimmer = 1;

uint8_t ledstart;                      // Starting location of a flash
uint8_t ledlen;                        // Length of a flash
/* AZUL*/

// the data pin for the NeoPixels
#define DATA_PIN 3

// How many LEDs we will be using, charge according to your needs
#define NUM_LEDS 13

//time for a full loop in milliseconds. e.g : 5000ms is 5s.
#define TIME_LOOP 5500

//size of the wave
//e.g : NUM_LEDS to have a wave of the size of your LED strip that you already defined
//20 (or anything else) to have a shorter wave than the length of your LED strip
#define waveLength 20

/*
 * Define the color of the wave. You can use RGB, HEX or HSV color.
 * Color values must be between 0 & 255.
 * e.g for red color:
 * RGB : const CRGB defaultColor = CRGB(255,0,0);
 * HEX : const CRGB defaultColor = CRGB(0xFF0000);
 * HSV : const CRGB defaultColor = CHSV(0,255,255);
 */
const CRGB defaultColor = CRGB(0, 0, 255);


/********ADVANCED SETTINGS********/

/*
 * HALF_WAVE_SIZE : size ratio of the first part of the wave. Second part would be the remaining space.
 * Used to determine the size and also the easing for the start and the end of the size.
 * Must be between 0 & 1
 */
#define HALF_WAVE_SIZE 0.5

/*
 * Define the Wave shape, choose one of the following choice.
 * SOFT : Smooth wave, recommended
 * HARD : Smooth with a deeper curve
 * LINEAR : Spike effect
 */
#define WAVE_TYPE SOFT


/******************CODE*****************/
/**************DO NOT TOUCH*************/
/*********unless you really need********/


#if WAVE_TYPE == SOFT
  #define WAVE_EASING CubicEaseInOut
#elif WAVE_TYPE == HARD
  #define WAVE_EASING QuinticEaseInOut
#else
  #define WAVE_EASING Linear
#endif

//time variable
unsigned long time;

//half wave size, used for a smooth effect later
const int halfWaveSize = waveLength * HALF_WAVE_SIZE ;



void renderLEDs() {
  time = millis();

  for (int i = 0; i < NUM_LEDS; i++) {
    float delta = ((float)(time % TIME_LOOP) / TIME_LOOP) * NUM_LEDS;
    float v = getPixelValue(i, delta);

    int r = defaultColor.r * v;
    int g = defaultColor.g * v;
    int b = defaultColor.b * v;


    //used to prevent weird corlor variation.
    if (r == 0 && defaultColor.r > 0 && v>0)
      r = 1;
    if (g == 0 && defaultColor.g > 0 && v>0)
      g = 1;
    if (b == 0 && defaultColor.b > 0 && v>0)
      b = 1;

    leds[i] = CRGB(r , g , b);
  }


  FastLED.show();

}
float getPixelValue(int index, float deltaI) {
  float position = (index - deltaI);
  if (position < 0) {
    position = position + NUM_LEDS;
  }
  if (position >= 0 && position < waveLength) {
    if (position < (float)halfWaveSize) {

      float p = position / (halfWaveSize);
      return WAVE_EASING(p);
    }
    else if (position < waveLength) {
      float p = 1 - (position - halfWaveSize) / (halfWaveSize);
      return WAVE_EASING(p);
    }
  }
  else {
    return 0;
  }
}


/******************EASING FUNCTIONS*****************/
float Linear(float p){
  return p;
}
float CubicEaseInOut(float p)
{
  if (p < 0.5)
  {
    return 4 * p * p * p;
  }
  else
  {
    float f = ((2 * p) - 2);
    return 0.5 * f * f * f + 1;
  }
}

float QuinticEaseInOut(float p)
{
  if (p < 0.5)
  {
    return 16 * p * p * p * p * p;
  }
  else
  {
    float f = ((2 * p) - 2);
    return  0.5 * f * f * f * f * f + 1;
  }
}

void setup() {
  delay(1000);                           // allows reprogramming if accidently blowing power w/leds
  LEDS.addLeds<CHIPSET, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);  // Use this for WS2812
//  LEDS.addLeds<CHIPSET, LED_DT, LED_CK, COLOR_ORDER>(leds, NUM_LEDS);  // Use this for WS2801 or APA102
  FastLED.setBrightness(BRIGHTNESS);
    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  //strip.begin();  // initialize the strip
  //strip.show();   // make sure it is visible
  //strip.clear();  // Initialize all pixels to 'off'
  //strip.setBrightness(60);
  //Serial.begin(9600);
} // setup()


void loop() {
  ledstart = random8(NUM_LEDS);           // Determine starting location of flash
  ledlen = random8(NUM_LEDS-ledstart);    // Determine length of flash (not to go beyond NUM_LEDS-1)
  for (int flashCounter = 0; flashCounter < random8(3,FLASHES); flashCounter++) {
    if(flashCounter == 0) dimmer = 5;     // the brightness of the leader is scaled down by a factor of 5
    else dimmer = random8(1,3);           // return strokes are brighter than the leader
    fill_solid(leds+ledstart,ledlen,CHSV(255, 0, 255/dimmer));
    FastLED.show();                       // Show a section of LED's
    delay(random8(4,10));                 // each flash only lasts 4-10 milliseconds
    fill_solid(leds+ledstart,ledlen,CHSV(255,0,0));   // Clear the section of LED's
    FastLED.show();     
    if (flashCounter == 0) delay (150);   // longer delay until next flash after the leader
    delay(50+random8(100));               // shorter delay between strokes  
  } // for()
  delay(random8(FREQUENCY)*100);  
   
} // loop()

and this

#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    5
//#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;
  }
}

thanks!

By "combine" do you mean, different effects on different segments of the strip?

Hello thanks for answering, what I want is the monowave effect and the lightning effect at the same time, but I don't know if it is possible in the same strip or I have to do it in two different strips
Thank you!

You didn't answer my question.

sorry, i mean different effects on same segment of the strip
:slight_smile:

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

That is 3 effects on the same 60 LED strip. 3 x 20 LEDs for each effect. Though I see no lightning effect in that code.

Hi!, I almost have it, I manage to send the two effects to each strip, but one of them does not work well, the loop gets stuck, I imagine it conflicts with something?

#include <FastLED.h>


// How many LEDs we will be using, charge according to your needs
#define NUM_LEDS1 90
#define NUM_LEDS2 13
#define TIME_LOOP 5500
#define COLOR_ORDER   GRB
#define CHIPSET       WS2812
#define FREQUENCY     20                // controls the interval between strikes
#define FLASHES       8                 // the upper limit of flashes per strike
#define BRIGHTNESS    255

//size of the wave
//e.g : NUM_LEDS to have a wave of the size of your LED strip that you already defined
//20 (or anything else) to have a shorter wave than the length of your LED strip
#define waveLength 20

const CRGB defaultColor = CRGB(0, 0, 255);
unsigned int dimmer = 1;

uint8_t ledstart;                      // Starting location of a flash
uint8_t ledlen;                        // Length of a flash

#define HALF_WAVE_SIZE 0.5

#define WAVE_TYPE SOFT


#if WAVE_TYPE == SOFT
  #define WAVE_EASING CubicEaseInOut
#elif WAVE_TYPE == HARD
  #define WAVE_EASING QuinticEaseInOut
#else
  #define WAVE_EASING Linear
#endif

//time variable
unsigned long time;

//half wave size, used for a smooth effect later
const int halfWaveSize = waveLength * HALF_WAVE_SIZE ;

CRGB leds1[NUM_LEDS1];
CRGB leds2[NUM_LEDS2];
void setup() {
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.addLeds<WS2812, 2>(leds1, NUM_LEDS1);
  FastLED.addLeds<WS2812, 4>(leds2, NUM_LEDS2);
 
}

void loop() {
  
  renderLEDs1();
  
   
}

void renderLEDs1() {
  time = millis();

  for (int i = 0; i < NUM_LEDS1; i++) {
    float delta = ((float)(time % TIME_LOOP) / TIME_LOOP) * NUM_LEDS1;
    float v = getPixelValue(i, delta);

    int r = defaultColor.r * v;
    int g = defaultColor.g * v;
    int b = defaultColor.b * v;


    //used to prevent weird corlor variation.
    if (r == 0 && defaultColor.r > 0 && v>0)
      r = 1;
    if (g == 0 && defaultColor.g > 0 && v>0)
      g = 1;
    if (b == 0 && defaultColor.b > 0 && v>0)
      b = 1;

    leds1[i] = CRGB(r , g , b);
  }


  FastLED.show();

}
void renderLEDs2(){
  ledstart = random8(NUM_LEDS2);           // Determine starting location of flash
  ledlen = random8(NUM_LEDS2-ledstart);    // Determine length of flash (not to go beyond NUM_LEDS-1)
  for (int flashCounter = 0; flashCounter < random8(3,FLASHES); flashCounter++) {
    if(flashCounter == 0) dimmer = 5;     // the brightness of the leader is scaled down by a factor of 5
    else dimmer = random8(1,3);           // return strokes are brighter than the leader
    fill_solid(leds2+ledstart,ledlen,CHSV(255, 0, 255/dimmer));
    FastLED.show();                       // Show a section of LED's
    delay(random8(4,10));                 // each flash only lasts 4-10 milliseconds
    fill_solid(leds2+ledstart,ledlen,CHSV(255,0,0));   // Clear the section of LED's
    FastLED.show();     
    if (flashCounter == 0) delay (150);   // longer delay until next flash after the leader
    delay(50+random8(100));               // shorter delay between strokes  
  } // for()
  delay(random8(FREQUENCY)*100);  
 

}
float getPixelValue(int index, float deltaI) {
  float position = (index - deltaI);
  if (position < 0) {
    position = position + NUM_LEDS1;
  }
  if (position >= 0 && position < waveLength) {
    if (position < (float)halfWaveSize) {

      float p = position / (halfWaveSize);
      return WAVE_EASING(p);
    }
    else if (position < waveLength) {
      float p = 1 - (position - halfWaveSize) / (halfWaveSize);
      return WAVE_EASING(p);
    }
  }
  else {
    return 0;
  }
}

/******************EASING FUNCTIONS*****************/
float Linear(float p){
  return p;
}
float CubicEaseInOut(float p)
{
  if (p < 0.5)
  {
    return 4 * p * p * p;
  }
  else
  {
    float f = ((2 * p) - 2);
    return 0.5 * f * f * f + 1;
  }
}

float QuinticEaseInOut(float p)
{
  if (p < 0.5)
  {
    return 16 * p * p * p * p * p;
  }
  else
  {
    float f = ((2 * p) - 2);
    return  0.5 * f * f * f * f * f + 1;
  }
}

How do you define that, exactly? Should the luminance of each effect be added together, or what? That would lead to some pretty weird appearances.

I suggest, understanding and then defining very exactly what it is you want to do, and how you will do it (what algorithms or math), before you set a finger on the keyboard to code.

Especially as, here you are asking people to understand what you want to do...

I have already solved. Two strips, each with a different effect from the same arduino nano board. is the code above, I only had to adjust some small details.
Thanks for the help