cookbook/recipes/breathing.md
Difficulty Level: ⭐⭐ Intermediate Time to Complete: 30-40 minutes Prerequisites:
You'll Learn:
Smooth pulsing/breathing animations.
Basic breathing effect with a solid color:
void breathe(CRGB color) {
// Use beatsin8 for smooth sine wave (0-255)
uint8_t brightness = beatsin8(12); // 12 BPM
// Set all LEDs to color with varying brightness
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = color;
leds[i].fadeToBlackBy(255 - brightness);
}
}
Breathing effect with slowly changing colors:
void colorBreathe() {
static uint8_t hue = 0;
// Brightness oscillates
uint8_t brightness = beatsin8(10, 50, 255);
// Hue slowly changes
EVERY_N_MILLISECONDS(50) {
hue++;
}
fill_solid(leds, NUM_LEDS, CHSV(hue, 255, brightness));
}
LEDs breathe in sequence, creating a wave effect:
void phasedBreathe() {
for (int i = 0; i < NUM_LEDS; i++) {
// Each LED has a phase offset
uint8_t brightness = beatsin8(
15, // Speed
50, // Minimum brightness
255, // Maximum brightness
0, // Time offset
i * (255 / NUM_LEDS) // Phase per LED
);
leds[i] = CHSV(160, 255, brightness);
}
}
Two colors alternating, breathing in opposite phases:
void dualBreathe() {
uint8_t brightness1 = beatsin8(8);
uint8_t brightness2 = 255 - brightness1; // Inverse
for (int i = 0; i < NUM_LEDS; i++) {
CRGB color1 = CRGB::Blue;
CRGB color2 = CRGB::Purple;
color1.fadeToBlackBy(255 - brightness1);
color2.fadeToBlackBy(255 - brightness2);
leds[i] = color1 + color2; // Blend both colors
}
}
The breathing effect uses sine wave functions to create smooth oscillations:
beatsin8(bpm, min, max, timebase, phase_offset)
bpm (beats per minute): Controls breathing speed
min/max: Brightness range
phase_offset: Staggers timing across LEDs
i * (255 / NUM_LEDS) = smooth wave across stripRelaxing meditation lights:
void loop() {
uint8_t brightness = beatsin8(6, 30, 200); // Slow, never too dim
fill_solid(leds, NUM_LEDS, CHSV(160, 180, brightness)); // Soft blue
FastLED.show();
}
Alert indicator:
void loop() {
uint8_t brightness = beatsin8(30); // Fast breathing
fill_solid(leds, NUM_LEDS, CRGB::Red);
FastLED.setBrightness(brightness);
FastLED.show();
}
Ocean waves:
void loop() {
for (int i = 0; i < NUM_LEDS; i++) {
uint8_t brightness = beatsin8(8, 50, 255, 0, i * 4);
leds[i] = CHSV(160, 255, brightness); // Blue
}
FastLED.show();
}
Rainbow Breathing:
void rainbowBreathe() {
static uint8_t hue = 0;
uint8_t brightness = beatsin8(12);
fill_rainbow(leds, NUM_LEDS, hue, 255 / NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i].fadeToBlackBy(255 - brightness);
}
EVERY_N_MILLISECONDS(20) { hue++; }
}
Sectioned Breathing:
void sectionBreathe() {
int section1 = NUM_LEDS / 3;
int section2 = (NUM_LEDS * 2) / 3;
uint8_t b1 = beatsin8(10);
uint8_t b2 = beatsin8(10, 0, 255, 0, 85); // 1/3 phase shift
uint8_t b3 = beatsin8(10, 0, 255, 0, 170); // 2/3 phase shift
fill_solid(&leds[0], section1, CHSV(0, 255, b1));
fill_solid(&leds[section1], section2 - section1, CHSV(96, 255, b2));
fill_solid(&leds[section2], NUM_LEDS - section2, CHSV(160, 255, b3));
}
Heartbeat:
void heartbeat() {
// Quick double-beat pattern
static uint16_t beatTimer = 0;
uint8_t brightness = 0;
uint16_t beatPhase = beatTimer % 1000;
if (beatPhase < 100) {
brightness = map(beatPhase, 0, 100, 0, 255);
} else if (beatPhase < 200) {
brightness = map(beatPhase, 100, 200, 255, 0);
} else if (beatPhase < 300) {
brightness = map(beatPhase, 200, 300, 0, 255);
} else if (beatPhase < 400) {
brightness = map(beatPhase, 300, 400, 255, 0);
}
fill_solid(leds, NUM_LEDS, CRGB::Red);
FastLED.setBrightness(brightness);
FastLED.show();
beatTimer += 20;
delay(20);
}