Program storage is not the problem; RAM usage might be.
OP's code
#include "FastLED.h"
#define DATA_PIN 0
#define MIC_PIN A1
#define DC_OFFSET 0
#define NOISE 50
#define SAMPLES 60
#define TOP (NUM_LEDS +2) // Allow dot to go slightly off scale
#define PEAK_FALL 20
#define BUTTON_LEAD 4
#define NUMBER_OF_MODES 6
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS 21
CRGB leds[NUM_LEDS];
#define BRIGHTNESS 64
#define FRAMES_PER_SECOND 120
//The following constant is the delay between each pixel flash
const int interval = 25;
unsigned long previousMillis = millis();
int mode = 1; //Default mode is one.
byte
peak = 0, // Used for falling dot
dotCount = 0, // Frame counter for delaying dot-falling speed
volCount = 0; // Frame counter for storing past volume data
int
vol[SAMPLES], // Collection of prior volume samples
lvl = 10, // Current "dampened" audio level
minLvlAvg = 0, // For dynamic adjustment of graph low & high
maxLvlAvg = 512;
bool buttonState = LOW;
bool lastButtonState = LOW;
bool gReverseDirection = false;
CRGBPalette16 gPal;
void setup(){
pinMode(BUTTON_LEAD, INPUT_PULLUP);
memset(vol,0,sizeof(int)*SAMPLES);//Thanks Neil!
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
gPal = CRGBPalette16( CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White);
}
uint8_t gHue = 0;
void loop() {
switch (mode) {
case 1:
sinelon();
break;
case 2:
vuscanner();
break;
case 3:
confetti();
break;
case 4:
juggle();
break;
case 5:
Fire2012WithPalette();
break;
default:
mode = 1;
break;
}
FastLED.show();
EVERY_N_MILLISECONDS( 20 ) { gHue++; }
}
//COOLING: How much does the air cool as it rises?
//Less cooling = taller flames. More cooling = shorter flames.
//Default 55, suggested range 20-100.
#define COOLING 55
//SPARKING: What chance (out of 255) is there that a new spark will be lit?
//Higher chance = more roaring fire. Lower chance = more flickery fire.
//Default 120, suggested range 50-200.
#define SPARKING 120
/* monitor button press */
bool buttonListener() {
bool modeChanged = false;
buttonState = digitalRead(BUTTON_LEAD);
if (buttonState != lastButtonState) {
if (buttonState == LOW) {
mode++;
modeChanged = true;
delay(250); // Debounce delay. I checked the best parameter and 250 was it.
}
}
lastButtonState = buttonState;
return modeChanged;
}
void sinelon() {
if(buttonListener()) { return; }
if(millis() - previousMillis >= interval) {
previousMillis = millis();
fadeToBlackBy(leds, NUM_LEDS, 20);
int pos = beatsin16(13,0,NUM_LEDS);
leds[pos] += CHSV(gHue, 255, 192);
}
}
void confetti() {
if(buttonListener()) { return; }
if(millis() - previousMillis >= interval) {
previousMillis = millis();
fadeToBlackBy(leds, NUM_LEDS, 10);
int pos = random16(NUM_LEDS);
leds[pos] += CHSV( gHue + random8(64), 200, 255);
}
}
void juggle() {
if(buttonListener()) { return; }
if(millis() - previousMillis >= interval) {
previousMillis = millis();
fadeToBlackBy(leds, NUM_LEDS, 20);
byte dothue = 0;
for(int i = 0; i < 8; i++) {
leds[beatsin16(i+7,0,NUM_LEDS)] |= CHSV(dothue, 200, 255);
dothue += 32;
}
}
}
void vuscanner() {
if(buttonListener()) { return; }
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN); // Raw reading from mic
n = abs(n - 512 - DC_OFFSET); // Center on zero
n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum
lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy)
// Calculate bar height based on dynamic min/max levels (fixed point):
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0; // Clip output
else if (height > TOP) height = TOP;
if (height > peak) peak = height; // Keep 'peak' dot at top
// Color pixels based on rainbow gradient
for (i=0; i<NUM_LEDS; i++) {
if (i >= height) leds[i].setRGB( 0, 0,0);
//uncomment one of the following lines to set strip effect
//else leds[i] = CHSV(map(i,0,NUM_LEDS-1,0,255), 255, 255); //CHSV values set for rainbow
else leds[i] = CHSV(gHue, 255, 255); //CHSV values set to fade rgb
}
// Draw peak dot
if (peak > 0 && peak <= NUM_LEDS-1) leds[peak] = CHSV(map(peak,0,NUM_LEDS-1,0,255), 255, 255);
// Every few frames, make the peak pixel drop by 1:
if (++dotCount >= PEAK_FALL) { // fall rate
if(peak > 0) peak--;
dotCount = 0;
}
vol[volCount] = n; // Save sample for dynamic leveling
if (++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter
// Get volume range of prior frames
minLvl = maxLvl = vol[0];
for (i=1; i<SAMPLES; i++) {
if (vol[i] < minLvl) minLvl = vol[i];
else if (vol[i] > maxLvl) maxLvl = vol[i];
}
// minLvl and maxLvl indicate the volume range over prior frames, used
// for vertically scaling the output graph (so it looks interesting
// regardless of volume level). If they're too close together though
// (e.g. at very low volume levels) the graph becomes super coarse
// and 'jumpy'...so keep some minimum distance between them (this
// also lets the graph go to zero when no sound is playing):
if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}
void Fire2012WithPalette(){
if(buttonListener()) { return; }
if(millis() - previousMillis >= interval) {
previousMillis = millis();
// Array of temperature readings at each simulation cell
static byte heat[NUM_LEDS];
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) {
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for( int k= NUM_LEDS - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
}
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
if( random8() < SPARKING ) {
int y = random8(7);
heat[y] = qadd8( heat[y], random8(160,255) );
}
// Step 4. Map from heat cells to LED colors
for( int j = 0; j < NUM_LEDS; j++) {
// Scale the heat value from 0-255 down to 0-240
// for best results with color palettes.
byte colorindex = scale8( heat[j], 240);
CRGB color = ColorFromPalette( gPal, colorindex);
int pixelnumber;
if( gReverseDirection ) {
pixelnumber = (NUM_LEDS-1) - j;
} else {
pixelnumber = j;
}
leds[pixelnumber] = color;
}
}
}