How to randomly choose between two functions

How can I randomly choose between meteorRain1 and meteorRain2, in the void loop?
I have spent much time searching and most info deals with random numbers.

#include "FastLED.h"
#define NUM_LEDS 60
CRGB leds[NUM_LEDS];
#define PIN1 2

void setup()
{
  FastLED.addLeds<WS2811, PIN2, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
}
void loop() 
{
  meteorRain1(CRGB(0x80,0x00,0x00),CRGB(0x00,0x80,0x00),random(10,40) ,random(50,70) ,true, random(5,20));
  delay(random(50,200));
  meteorRain2(CRGB(0x80,0x80,0x80), CRGB(0x00,0x00,0x80),random(10,40) ,random(40,50) ,true, random(5,20));
  delay(random(50,200));
} 

void meteorRain1(CRGB ColorBackground, CRGB ColorMeteor, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) 
{  
  // set background color
  fill_solid( leds, NUM_LEDS, ColorBackground );

  for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) 
  {
    // fade color to background color for all LEDs
    for(int j=0; j < NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10) > 5) ) {
        leds[j] = fadeTowardColor(leds[j], ColorBackground, meteorTrailDecay ); 
      }
    }

    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < NUM_LEDS) && (i-j >= 0) ) {
        leds[i-j]= ColorMeteor;
      }
    }
   
    FastLED.show();
    delay(SpeedDelay);
  }

for(int i = NUM_LEDS+NUM_LEDS; i >=0-NUM_LEDS; i--) 
  {
    // fade color to background color for all LEDs
    for(int j=0; j < NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10) > 5) ) {
        leds[j] = fadeTowardColor(leds[j], ColorBackground, meteorTrailDecay ); 
      }
    }

    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < NUM_LEDS) && (i-j >= 0) ) {
        leds[i-j]= ColorMeteor;
      }
    }
   
    FastLED.show();
    delay(SpeedDelay);
  }  
}

void meteorRain2(CRGB ColorBackground, CRGB ColorMeteor, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) 
{  
  // set background color
  fill_solid( leds, NUM_LEDS, ColorBackground );

  for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) 
  {
    // fade color to background color for all LEDs
    for(int j=0; j < NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10) > 5) ) {
        leds[j] = fadeTowardColor(leds[j], ColorBackground, meteorTrailDecay ); 
      }
    }

    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < NUM_LEDS) && (i-j >= 0) ) {
        leds[i-j]= ColorMeteor;
      }
    }
   
    FastLED.show();
    delay(SpeedDelay);
  }

for(int i = NUM_LEDS+NUM_LEDS; i >=0-NUM_LEDS; i--) 
  {
    // fade color to background color for all LEDs
    for(int j=0; j < NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10) > 5) ) {
        leds[j] = fadeTowardColor(leds[j], ColorBackground, meteorTrailDecay ); 
      }
    }

    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < NUM_LEDS) && (i-j >= 0) ) {
        leds[i-j]= ColorMeteor;
      }
    }
   
    FastLED.show();
    delay(SpeedDelay);
  }  
}

//Functions from Kriegsman example
CRGB fadeTowardColor( CRGB& cur, const CRGB& target, uint8_t amount)
{
  nblendU8TowardU8( cur.red,   target.red,   amount);
  nblendU8TowardU8( cur.green, target.green, amount);
  nblendU8TowardU8( cur.blue,  target.blue,  amount);
  return cur;
}

// function used by "fadeTowardColor"
void nblendU8TowardU8( uint8_t& cur, const uint8_t target, uint8_t amount)
{
  if( cur == target) return;
  
  if( cur < target ) {
    uint8_t delta = target - cur;
    delta = scale8_video( delta, amount);
    cur += delta;
  } else {
    uint8_t delta = cur - target;
    delta = scale8_video( delta, amount);
    cur -= delta;
  }
}


Define a 2-element array of function pointers ... one entry for each function. Use the random function to pick an index into that array ... 0 or 1.

So why can't use just use a random number (say 1 to 1000) and an if statement?

If (randomNumber > 500)
function1();
else
function2();

1 Like

Place this in setup(), uses an analog input that has nothing attached to it.

randomSeed(analogRead(0));


void loop()
{
. . .
  //myVa = random(min, max);

 myVar = random(0, 2);

if(myVar == 0)
{
   function 1;
}
else
{
   function 2;
}

}
1 Like

Ok.
What if I now have four functions of meteorRain1 through meteorRain4?

:thinking:

myVar = random(0, 4);

if(myVar == 0)
{
   function1();
}

else if (myVar == 1)
{
   function2();
}

else if (myVar == 2)
{
   function3();
}

else if (myVar == 3)
{
   function4();
}

Would a few 'else if' statements work?.

See post #6

Or

switch case

Any of the several options suggested here are easily scalable to accommodating more functions .... you just need to put a little effort of your own into this.

void function0();
void function1();
void function2();
void function3();
void function4();

using FunctPtr = void (*)();
FunctPtr functionArray[] = {
  function0,
  function1,
  function2,
  function3,
  function4
};

const size_t numFunctions = sizeof(functionArray) / sizeof(functionArray[0]);

void setup() {
}

void loop() {
  size_t randomIndex = random(0, numFunctions);
  functionArray[randomIndex]();
}

void function0() {
}

void function1() {
}

void function2() {
}

void function3() {
}

void function4() {
}

Ended up using switch case.
Seems like a good solution. It works as I hope.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.