Problem with fading LEDs and a randomization question

So I'm building my first Arduino project, and I'm attempting to use addressable LEDs to run a number of different light patterns at the same time. Basically, a couple of buttons control which LEDs are on, and which pattern certain LEDs are doing. The different patterns are each individual parts of a larger project, so I guess the key distinction is that when searching for information, a lot of things I came across were simply how to make an LED strip do one thing, whereas some of these LEDs are going to be over here flickering like candles, others are going to be pulsing like glowing eyes, etc.

Basically, the fade is where I'm having the problem. I've been getting a number of strange outcomes with it. Sometimes it will just stay 100% solid on, sometimes it will do completely random colors, other times it will fade on and off by at, for lack of a better term, a much slower frame rate than it should be.

The issue is exacerbated by the amount of LEDs in use. The first fade() function only used two, but when I tried the larger ones later (frame_blood(), etc.) I noticed the issues above. I retroactively increased the LED count in fade() and it did similar things. But the more LEDs it needs, the slower things get. Like, you can see the LEDs "run" as they turn on and then do whatever wrong thing they are going to do, mentioned above.

The thing that gets me is that the code is simple, and the candle flickering parts, to me, seem more computationally demanding than "increment this fade value by one and use it for all of the LEDs in question." I eventually swapped over to a sinusoidal function to cut down on extraneous if statements and it made no difference.

So here's ALL my code, but the areas that are the problem are fade(), fade_sin(), frame_blood(), and frame_blood_sin(). Any suggestions would be wonderful. And I apologize that my code isn't super clean - it's the result of a ton of experimentation and I'm going to revamp it once I get the actual hardware solidified more.

// ---------- EYES ----------

unsigned long fade() {
  unsigned long currentFadeMillis = millis();
  if (currentFadeMillis - previousFadeMillis >= 35) {
    previousFadeMillis = currentFadeMillis;
    for (int i = CANDLE_LEDS; i <= CANDLE_LEDS + EYES_LEDS - 1; i++){
     
      if (fadeInFlag == 0 && fadeValue < 150) {
        leds[i] = CRGB(fadeValue, 0, 0);
        fadeValue++;
      }
      else if (fadeInFlag == 0 && fadeValue == 150) {
        fadeInFlag = 1;
      }
      else if (fadeInFlag == 1 && fadeValue > 0) {
        leds[i] = CRGB(fadeValue, 0, 0);
        fadeValue--;
      }
      else if (fadeInFlag == 1 && fadeValue == 0) {
        fadeInFlag = 0;
      }
      else{
      }
      FastLED.show();
    }
  return previousFadeMillis;   
  }
}

unsigned long fade_sin() {
  unsigned long currentFadeMillis = millis();
  if (currentFadeMillis - previousFadeMillis >= 20) {
    previousFadeMillis = currentFadeMillis;
     timer = millis(); // updating time 
     int ledValue = OFFSET + AMPLITUDE*(cos(OMEGA*timer)+PHASE);
      for (int i = 0; i <= CANDLE_LEDS + EYES_LEDS - 1; i++){
      leds[i] = CHSV(0, 255, ledValue);
    FastLED.show();}
    return previousCandleMillis;  
  }
}



unsigned long frame_blood_sin() {
  unsigned long currentFadeMillis = millis();
  if (currentFadeMillis - previousFadeMillis >= 20) {
    previousFadeMillis = currentFadeMillis;
     timer = millis(); // updating time 
     int ledValue = OFFSET + AMPLITUDE*(cos(OMEGA*timer)+PHASE);
      for (int i = 30; i < 64; i++) {
      leds[i] = CHSV(0, 255, ledValue);
    FastLED.show();}
    return previousCandleMillis;  
  }
}

unsigned long frame_blood() {
  unsigned long currentFadeMillis2 = millis();
  if (currentFadeMillis2 - previousFadeMillis2 >= 20) {
    previousFadeMillis2 = currentFadeMillis2;
    
   
     
      if (fadeInFlag2 == 0 && fadeValue2 < 150) {
       
        fadeValue++;
      }
      else if (fadeInFlag2 == 0 && fadeValue2 == 150) {
        fadeInFlag2 = 1;
      }
      else if (fadeInFlag2 == 1 && fadeValue2 > 0) {
        
        fadeValue--;
      }
      else if (fadeInFlag2 == 1 && fadeValue2 == 0) {
        fadeInFlag2 = 0;
      }
      else{
      }

//  for (int i = CANDLE_LEDS + EYES_LEDS + BLOOD_LEDS; i < CANDLE_LEDS + EYES_LEDS + BLOOD_LEDS + FRAME_LEDS; i++) {
       for (int i = 30; i < 64; i++) {
        leds[i] = CHSV(50, 255, fadeValue2);
    FastLED.show();        
    }

  return previousFadeMillis2;   
  }
}

One other question: in my candle functions you can see me using random(#, #) in the CHSV command to change the brightness and the hue values. I'm wondering if there is a way I can introduce a bias? For instance, I want the candles to be primarily red, but I want hints of orange in there, but not with equal probability. Or I want a range of brightnesses, but every once in a while, I want it to spark up a little brighter. What is the easiest way to achieve something like this?

Thank you in advance for any help you can provide!

One thing I notice is that you call FastLed.show() in your for loops. E.g.

unsigned long fade_sin()
{
  unsigned long currentFadeMillis = millis();
  if (currentFadeMillis - previousFadeMillis >= 20)
  {
    previousFadeMillis = currentFadeMillis;
    timer = millis(); // updating time
    int ledValue = OFFSET + AMPLITUDE * (cos(OMEGA * timer) + PHASE);
    for (int i = 0; i <= CANDLE_LEDS + EYES_LEDS - 1; i++)
    {
      leds[i] = CHSV(0, 255, ledValue);
      FastLED.show();
    }
    return previousCandleMillis;
  }
}

If you move the FastLed.show() to after the for loop, it should speed up your process.

unsigned long fade_sin()
{
  unsigned long currentFadeMillis = millis();
  if (currentFadeMillis - previousFadeMillis >= 20)
  {
    previousFadeMillis = currentFadeMillis;
    timer = millis(); // updating time
    int ledValue = OFFSET + AMPLITUDE * (cos(OMEGA * timer) + PHASE);
    for (int i = 0; i <= CANDLE_LEDS + EYES_LEDS - 1; i++)
    {
      leds[i] = CHSV(0, 255, ledValue);
    }
    FastLED.show();
    return previousCandleMillis;
  }
}

This might not be the cause of your problem, no idea.

PS
only looked at the code in your post, not at the github link.

That was something I tried to change up in a few attempts to solve the problem and it never made any difference, unfortunately.

First you should try to only call "FastLED.show()" once for each "loop()". Second, you could try to avoid the use of "cos()" - either find another approach or use a cosine table instead.

Something that may help is a brief understanding of the eye.
The human eye is much more sensitive to changes in low light levels than high. Assuming the brightness is controlled by PWM the range is 0-255. Starting from zero, people will notice a continuing increase in brightness up until about 160-170. From that point on to 255 there is little 'perceived' increase. So, one way to speed up a random display would be to limit your range. It doesn't actually speed anything up but the brightness will no longer be perceived to be full on 25% of the time.

As for 'sparking' a bit, if you follow what I just said but reduce your range even further, say 0 - 120, you can reserve a band within that range to flash bright. As an example, sacrifice some of the lower levels, maybe 0 - 5, and when one of these numbers pops up make it 200 (or so). In that way about 5% of the time you'll get that 'spark'.

I've tried sin and cos (apparently the code I posted is actually cos, I completely forgot that I changed it. And as with the other suggestion, again in the code I posted was the original way I did it - counting using ledValue++ from 0-255, tripping a flag, and counting back down. All versions, including moving fastLED.show to every possible place in the code it could go, never once showed any improvement.

As for the human eye thing, it's 100% not that. I get what you are saying about the brightness, but even when I reduce the brightness to go from 0-150 or some other range, you can very clearly see that the code is not running every 20 ms like it should. And this is even more obvious when I activate it and it slows down all the other code.

Like, I'm flickering the first 24 LEDs at 20 ms, and I can see the pattern they are changing at, and then I hit the button a few more times, adding more features to more sections of the LED strip, and then I get to the fade at the end, and it slows EVERYTHING before it to like 10% of the original speed, while barely working itself.

All I am asking for is how to fade an individual section of an addressable LED strip in and out and I have Googled for weeks and cannot find anything close to how to do this. Again, I can apply multiple random value calculations to multiple LEDs at once without any sort of performance issue, but I can't apply a single fade value to a range of LEDs over 5-10 without it slowing to a crawl? I don't understand how that's possible.

quadnine_damage:
All I am asking for is how to fade an individual section of an addressable LED strip in and out

Basically as you do at this moment in fade() in the github code (keeping my earlier remark in mind).

The fade() code (on github) sets the 'intensity' of one led to X, of the next led to X+1, the next one to X+2 etc if fadeInFlag equals 0; so both eye leds will never have the same intensity.

I see a remark in your github code that frame_blood_sin() is slow 'compared to above code'. If that's what you actually have a problem with, the calculation of ledValue takes roughly 150 microSeconds. Floating point calculations are slow; a simple increment/decrement takes a fraction of that.

You might have another problem. Are you using pullup or pulldown resistors for your buttons? If not, your debounce can introduce significant delays and might also affect the pattern because your pushButtonCounters can unexpectedly change. Do you observe any unexpected output from the debounce function?