cookbook/basic-patterns/rainbow.md
Difficulty Level: ⭐ Beginner Time to Complete: 30-35 minutes Prerequisites:
You'll Learn:
fill_rainbow() to create smooth rainbow gradients across your LED stripRainbow effects showcase the power of HSV color space for creating smooth, natural color transitions. These patterns are visually striking and demonstrate essential color cycling techniques.
Create a rainbow that spans your entire LED strip:
void rainbow() {
fill_rainbow(leds, NUM_LEDS, 0, 255 / NUM_LEDS);
}
leds: Your LED arrayNUM_LEDS: Number of LEDs to fill0: Starting hue (0-255)255 / NUM_LEDS: Hue increment per LEDThis distributes all 256 hue values evenly across your strip.
Animate the rainbow by cycling the starting hue:
void movingRainbow() {
static uint8_t hue = 0;
fill_rainbow(leds, NUM_LEDS, hue, 255 / NUM_LEDS);
hue++;
}
The rainbow appears to move along the strip as the starting hue increments each frame.
#include <FastLED.h>
#define LED_PIN 5
#define NUM_LEDS 60
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(50);
}
void movingRainbow() {
static uint8_t hue = 0;
fill_rainbow(leds, NUM_LEDS, hue, 255 / NUM_LEDS);
hue++;
}
void loop() {
movingRainbow();
FastLED.show();
delay(20);
}
HSV uses three components:
CHSV color = CHSV(hue, 255, 255); // Full saturation and brightness
Create multiple rainbow cycles across the strip:
void tightRainbow() {
static uint8_t hue = 0;
fill_rainbow(leds, NUM_LEDS, hue, 5); // Larger delta = tighter rainbow
hue++;
}
Make the rainbow move backward:
void reverseRainbow() {
static uint8_t hue = 0;
fill_rainbow(leds, NUM_LEDS, hue, 255 / NUM_LEDS);
hue--; // Decrement instead of increment
}
Control rainbow animation speed:
void speedRainbow(uint8_t speed) {
static uint8_t hue = 0;
fill_rainbow(leds, NUM_LEDS, hue, 255 / NUM_LEDS);
hue += speed; // Higher speed = faster movement
}
void loop() {
speedRainbow(3); // 3x faster than normal
FastLED.show();
delay(20);
}
Fill only a portion of the strip:
void partialRainbow() {
static uint8_t hue = 0;
// Rainbow on first half
fill_rainbow(&leds[0], NUM_LEDS / 2, hue, 10);
// Solid color on second half
fill_solid(&leds[NUM_LEDS / 2], NUM_LEDS / 2, CRGB::Black);
hue++;
}
Create a mirrored rainbow effect:
void mirrorRainbow() {
static uint8_t hue = 0;
int half = NUM_LEDS / 2;
fill_rainbow(&leds[0], half, hue, 255 / half);
// Mirror to second half
for (int i = 0; i < half; i++) {
leds[NUM_LEDS - 1 - i] = leds[i];
}
hue++;
}
Combine rainbow with brightness pulsing:
void breathingRainbow() {
static uint8_t hue = 0;
// Create rainbow
fill_rainbow(leds, NUM_LEDS, hue, 255 / NUM_LEDS);
// Pulse brightness
uint8_t brightness = beatsin8(12, 50, 255); // 12 BPM, 50-255 range
FastLED.setBrightness(brightness);
hue++;
}
Create discrete rainbow blocks:
void chunkRainbow() {
static uint8_t hue = 0;
int chunkSize = 5;
for (int i = 0; i < NUM_LEDS; i += chunkSize) {
fill_solid(&leds[i], chunkSize, CHSV(hue + (i * 10), 255, 255));
}
hue++;
}
Two rainbows moving in opposite directions:
void dualRainbow() {
static uint8_t hue1 = 0;
static uint8_t hue2 = 128; // Offset by half
// First rainbow
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(hue1 + (i * 4), 255, 128);
}
// Second rainbow (additive)
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] += CHSV(hue2 - (i * 4), 255, 128);
}
hue1++;
hue2--;
}
fill_rainbow() for efficient rainbow generationbeatsin8() for smooth, automatic speed variationsRGB rainbow requires complex calculations:
// RGB rainbow (complex)
if (hue < 85) {
r = hue * 3;
g = 255 - hue * 3;
b = 0;
} // ... more cases
HSV rainbow is simple:
// HSV rainbow (simple)
CHSV color = CHSV(hue, 255, 255);
hue++;
You've completed the basic patterns! Now explore: