How to stop if command layering?

I have some addressable LED lights and a Bluetooth module and I am trying to control them remotely from my phone. I have an app created which sends a letter to the Arduino to display a certain pattern.

The only way I know how to do this is by using if statements with the stored letter. The only problem with this is when another pattern is selected, it doesn't remove the previous pattern and leads to them all being layered on top of one another and I don't know how to stop this.

Any help would be greatly appreciated :slight_smile:

char color = 0; //store the received byte here

#include <FastLED.h>

#define DATA_PIN    6
//#define CLK_PIN   4
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    240
#define BRIGHTNESS  80

CRGB leds[NUM_LEDS];

CRGBPalette16 currentPalette = LavaColors_p;
CRGBPalette16 targetPalette = LavaColors_p;
TBlendType    currentBlending = LINEARBLEND;

char received;

void setup()  {
  Serial.begin(9600);     //Start the serial comunication for the bluetooth module


  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS)
  .setCorrection(TypicalLEDStrip)
  .setDither(BRIGHTNESS < 255);

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

void loop()  {

  if (Serial.available() > 0) {
    // read the bluetoot data and store it
    color = Serial.read();
    char Rec = char(color);
    if (Rec != '0')
    {
      Serial.println(Rec); //This is to visualise the received character on the serial monitor
    }
  }

  //LEDs off
  if (color == 'o')
  {
    fill_solid(leds, NUM_LEDS, CRGB::Black);                    // Just to be sure, let's really make it BLACK.
    FastLED.show();                         // Power managed display
  }

  //Pride
  if (color == 'r')
  
   void pride();
    {
      static uint16_t sPseudotime = 0;
      static uint16_t sLastMillis = 0;
      static uint16_t sHue16 = 0;

      uint8_t sat8 = beatsin88( 87, 220, 250);
      uint8_t brightdepth = beatsin88( 341, 96, 224);
      uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
      uint8_t msmultiplier = beatsin88(147, 23, 60);

      uint16_t hue16 = sHue16;//gHue * 256;
      uint16_t hueinc16 = beatsin88(113, 1, 3000);

      uint16_t ms = millis();
      uint16_t deltams = ms - sLastMillis ;
      sLastMillis  = ms;
      sPseudotime += deltams * msmultiplier;
      sHue16 += deltams * beatsin88( 400, 5, 9);
      uint16_t brightnesstheta16 = sPseudotime;

      for ( uint16_t i = 0 ; i < NUM_LEDS; i++) {
        hue16 += hueinc16;
        uint8_t hue8 = hue16 / 256;

        brightnesstheta16  += brightnessthetainc16;
        uint16_t b16 = sin16( brightnesstheta16  ) + 32768;

        uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
        uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
        bri8 += (255 - brightdepth);

        CRGB newcolor = CHSV( hue8, sat8, bri8);

        uint16_t pixelnumber = i;
        pixelnumber = (NUM_LEDS - 1) - pixelnumber;

        nblend( leds[pixelnumber], newcolor, 64);
      }
    }
  



  //Blur
  if (color == 'b')
  
    void blur();
    {
      uint8_t blurAmount = dim8_raw( beatsin8(3, 64, 192) );      // A sinewave at 3 Hz with values ranging from 64 to 192.
      blur1d( leds, NUM_LEDS, blurAmount);                        // Apply some blurring to whatever's already on the strip, which will eventually go black.

      uint8_t  i = beatsin8(  9, 0, NUM_LEDS);
      uint8_t  j = beatsin8( 7, 0, NUM_LEDS);
      uint8_t  k = beatsin8(  5, 0, NUM_LEDS);

      // The color of each point shifts over time, each at a different speed.
      uint16_t ms = millis();
      leds[(i + j) / 2] = CHSV( ms / 29, 200, 255);
      leds[(j + k) / 2] = CHSV( ms / 41, 200, 255);
      leds[(k + i) / 2] = CHSV( ms / 73, 200, 255);
      leds[(k + i + j) / 3] = CHSV( ms / 53, 200, 255);

      FastLED.show();
    }
  


//Beatwave
if (color == 'g')

 void beatwave();
{
  EVERY_N_MILLISECONDS(100) {
    uint8_t maxChanges = 24; 
    nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges);   // AWESOME palette blending capability.
  }

  EVERY_N_SECONDS(5) {                                        // Change the target palette to a random one every 5 seconds.
    targetPalette = CRGBPalette16(CHSV(random8(), 255, random8(128,255)), CHSV(random8(), 255, random8(128,255)), CHSV(random8(), 192, random8(128,255)), CHSV(random8(), 255, random8(128,255)));
  }

  FastLED.show();
}


  if (color == 'y')
  {

int   thisdelay =   10;                                       // A delay value for the sequence(s)
uint8_t   count =   0;                                        // Count up to 255 and then reverts to 0
uint8_t fadeval = 224;                                        // Trail behind the LED's. Lower => faster fade.

uint8_t bpm = 30;
    
void dot_beat(); {

  uint8_t inner = beatsin8(bpm, NUM_LEDS/4, NUM_LEDS/4*3);    // Move 1/4 to 3/4
  uint8_t outer = beatsin8(bpm, 0, NUM_LEDS-1);               // Move entire length
  uint8_t middle = beatsin8(bpm, NUM_LEDS/3, NUM_LEDS/3*2);   // Move 1/3 to 2/3

  leds[middle] = CRGB::Purple;
  leds[inner] = CRGB::Blue;
  leds[outer] = CRGB::Aqua;

  nscale8(leds,NUM_LEDS,fadeval);                             // Fade the entire array. Or for just a few LED's, use  nscale8(&leds[2], 5, fadeval);

}
  }

  if (color == 'c')
  {
void noise16_1(); {                                            // moves a noise up and down while slowly shifting to the side

uint8_t maxChanges = 24;
  EVERY_N_MILLISECONDS(50) {
    nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges);  // Blend towards the target palette
  }

  EVERY_N_SECONDS(5) {             // Change the target palette to a random one every 5 seconds.
    targetPalette = CRGBPalette16(CHSV(random8(), 255, random8(128,255)), CHSV(random8(), 255, random8(128,255)), CHSV(random8(), 192, random8(128,255)), CHSV(random8(), 255, random8(128,255)));
  }

  uint16_t scale = 1000;                                      // the "zoom factor" for the noise

  for (uint16_t i = 0; i < NUM_LEDS; i++) {

    uint16_t shift_x = beatsin8(5);                           // the x position of the noise field swings @ 17 bpm
    uint16_t shift_y = millis() / 100;                        // the y position becomes slowly incremented
    

    uint16_t real_x = (i + shift_x)*scale;                    // the x position of the noise field swings @ 17 bpm
    uint16_t real_y = (i + shift_y)*scale;                    // the y position becomes slowly incremented
    uint32_t real_z = millis() * 20;                          // the z position becomes quickly incremented
    
    uint8_t noise = inoise16(real_x, real_y, real_z) >> 8;   // get the noise data and scale it down

    uint8_t index = sin8(noise*3);                           // map LED color based on noise data
    uint8_t bri   = noise;

    leds[i] = ColorFromPalette(currentPalette, index, bri, LINEARBLEND);   // With that value, look up the 8 bit colour palette value and assign it to the current LED.
  }
  }

}
}

How about turning off all of the LEDs before starting a new effect ?

This looks very odd

  if (color == 'r')
    void pride();
etc, etc

What do you think the second line above does ?

It looks like you are trying to call a function named pride() but have made a mess of doing it

I am quite new to Arduino code so the different patterns are just pre-set FastLED code which I am trying to add a Bluetooth selection method to

So the void pride is part of the old code which I have kept in and just put the if function before, if that makes sense

I suggest that either you remove the function declarations, which are doing nothing, or create the functions and call them from your if tests

ok I'll have a go at that

Thank you

Hi, @hart-y
You might have better control if you use the swtich.. case statement.
https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/

This may be what you are looking for.

Tom... :smiley: :+1: :coffee: :australia:

There is a side effect to that

  if (color == 'r')

    void pride();
  {
    static uint16_t sPseudotime = 0;
    ...
    ...

The code after void pride() is executed unconditionally (so always). Below would solve that problem.

  if (color == 'r')
  {
    void pride();
    static uint16_t sPseudotime = 0;
    ...
    ...

Also be aware that void pride() is a function prototype as mentioned earlier in reply #5 and not a call of the function.