# Advanced Blinking Effects with WS2812 LED
## Project Overview
This project demonstrates advanced lighting effects using the built-in WS2812 RGB LED on the Lonely Binary ESP32-S3. These effects go beyond simple blinking to create smooth, dynamic, and visually appealing lighting patterns that can be used for user feedback, ambient lighting, or artistic expression.
### Learning Objectives
- Understand color theory and RGB color mixing
- Learn about timing and animation in embedded systems
- Master smooth transitions and brightness control
- Explore random effects and creative programming
- Develop efficient code for real-time LED control
## Understanding Color Theory
### RGB Color Model
The WS2812 LED uses the RGB (Red, Green, Blue) color model where:
- **Red (R)**: Controls red light intensity (0-255)
- **Green (G)**: Controls green light intensity (0-255)
- **Blue (B)**: Controls blue light intensity (0-255)
### Color Mixing Examples
```python
# Primary Colors
RED = (255, 0, 0) # Pure red
GREEN = (0, 255, 0) # Pure green
BLUE = (0, 0, 255) # Pure blue
# Secondary Colors
YELLOW = (255, 255, 0) # Red + Green
MAGENTA = (255, 0, 255) # Red + Blue
CYAN = (0, 255, 255) # Green + Blue
# Special Colors
WHITE = (255, 255, 255) # All colors at maximum
BLACK = (0, 0, 0) # All colors off
```
### Brightness Control
Brightness is controlled by scaling RGB values:
```python
# 50% brightness red
dim_red = (127, 0, 0) # 255 * 0.5 = 127
# 25% brightness white
dim_white = (63, 63, 63) # 255 * 0.25 = 63
```
## Advanced Effects
### Rainbow Effect
The rainbow effect creates a smooth transition through the entire color spectrum, simulating a real rainbow. This effect is commonly used in decorative lighting and status indicators.
#### How It Works
The rainbow effect uses mathematical formulas to generate colors that smoothly transition from red through yellow, green, cyan, blue, magenta, and back to red.
#### Code Explanation
```python
# rainbow_effect.py - Smooth rainbow color transition
import machine
import neopixel
import time
# Configure WS2812 LED on pin IO48
# neopixel.NeoPixel(pin, number_of_leds, bpp=3, timing=1)
np = neopixel.NeoPixel(machine.Pin(48), 1)
def set_color(r, g, b):
"""Set LED to specific RGB color"""
np[0] = (r, g, b) # Set the first (and only) LED
np.write() # Send the color data to the LED
def rainbow_effect(duration=10):
"""Create a smooth rainbow effect"""
print("Creating rainbow effect...")
start_time = time.time()
while time.time() - start_time < duration:
for i in range(256): # 256 steps for complete color cycle
# Generate rainbow colors using mathematical formulas
# Phase 1: Red to Green (0-85)
if i < 85:
r = 255 - i * 3 # Red decreases from 255 to 0
g = i * 3 # Green increases from 0 to 255
b = 0 # Blue stays at 0
# Phase 2: Green to Blue (85-170)
elif i < 170:
i -= 85 # Reset counter for this phase
r = 0 # Red stays at 0
g = 255 - i * 3 # Green decreases from 255 to 0
b = i * 3 # Blue increases from 0 to 255
# Phase 3: Blue to Red (170-255)
else:
i -= 170 # Reset counter for this phase
r = i * 3 # Red increases from 0 to 255
g = 0 # Green stays at 0
b = 255 - i * 3 # Blue decreases from 255 to 0
set_color(r, g, b)
time.sleep(0.02) # 20ms delay for smooth animation
# Turn off LED when effect is complete
set_color(0, 0, 0)
print("Rainbow effect complete!")
# Run rainbow effect for 5 seconds
rainbow_effect(5)
```
#### Mathematical Breakdown
The rainbow effect divides the color spectrum into three phases:
1. **Red to Green (0-85)**: Red decreases while green increases
2. **Green to Blue (85-170)**: Green decreases while blue increases
3. **Blue to Red (170-255)**: Blue decreases while red increases
The multiplier `* 3` ensures smooth transitions: `255 ÷ 85 = 3`
### Breathing Effect
The breathing effect creates a smooth fade in and out of brightness, simulating the natural breathing pattern. This effect is popular for ambient lighting and status indicators.
#### How It Works
The breathing effect gradually increases brightness from 0% to 100%, then decreases back to 0%, creating a "breathing" pattern. The color remains constant while only the brightness changes.
#### Code Explanation
```python
# breathing_effect.py - Smooth brightness transitions
import machine
import neopixel
import time
# Configure WS2812 LED
np = neopixel.NeoPixel(machine.Pin(48), 1)
def set_color(r, g, b):
"""Set LED to specific RGB color"""
np[0] = (r, g, b)
np.write()
def breathing_effect(color=(255, 0, 0), cycles=3):
"""Create a breathing effect with specified color"""
print(f"Breathing effect with color RGB{color}")
for cycle in range(cycles): # Repeat for specified number of cycles
# Fade in: Increase brightness from 0 to 255
for brightness in range(0, 256, 2): # Step by 2 for smooth transition
# Scale each color component by brightness
r = int(color[0] * brightness / 255) # Scale red component
g = int(color[1] * brightness / 255) # Scale green component
b = int(color[2] * brightness / 255) # Scale blue component
set_color(r, g, b)
time.sleep(0.01) # 10ms delay for smooth fade
# Fade out: Decrease brightness from 255 to 0
for brightness in range(255, -1, -2): # Step by -2 for smooth transition
# Scale each color component by brightness
r = int(color[0] * brightness / 255)
g = int(color[1] * brightness / 255)
b = int(color[2] * brightness / 255)
set_color(r, g, b)
time.sleep(0.01) # 10ms delay for smooth fade
# Turn off LED when effect is complete
set_color(0, 0, 0)
# Test different colors
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] # Red, Green, Blue
for color in colors:
breathing_effect(color, 2) # 2 cycles per color
time.sleep(1) # 1 second pause between colors
```
#### Brightness Scaling Formula
The key to the breathing effect is the brightness scaling formula:
```python
scaled_color = int(original_color * brightness / 255)
```
**Example**: For red color (255, 0, 0) at 50% brightness:
- `r = int(255 * 127 / 255) = 127`
- `g = int(0 * 127 / 255) = 0`
- `b = int(0 * 127 / 255) = 0`
- Result: `(127, 0, 0)` - dim red
### Random Twinkle Effect
The twinkle effect creates a random, star-like twinkling pattern by randomly changing colors and brightness levels. This effect is perfect for creating ambient lighting or decorative displays.
#### How It Works
The twinkle effect generates random colors and random brightness levels, creating an unpredictable, natural-looking twinkling pattern similar to stars in the night sky.
#### Code Explanation
```python
# twinkle_effect.py - Random twinkling colors
import machine
import neopixel
import time
import random
# Configure WS2812 LED
np = neopixel.NeoPixel(machine.Pin(48), 1)
def set_color(r, g, b):
"""Set LED to specific RGB color"""
np[0] = (r, g, b)
np.write()
def random_color():
"""Generate a random color"""
return (random.randint(0, 255), # Random red (0-255)
random.randint(0, 255), # Random green (0-255)
random.randint(0, 255)) # Random blue (0-255)
def twinkle_effect(duration=10):
"""Create a twinkling effect"""
print("Twinkling effect...")
start_time = time.time()
while time.time() - start_time < duration: # Run for specified duration
# Generate random brightness (0-255)
brightness = random.randint(0, 255)
# Generate random color
color = random_color()
# Apply brightness scaling to random color
r = int(color[0] * brightness / 255) # Scale red component
g = int(color[1] * brightness / 255) # Scale green component
b = int(color[2] * brightness / 255) # Scale blue component
set_color(r, g, b)
# Random delay between 0.1 and 0.5 seconds
time.sleep(random.uniform(0.1, 0.5))
# Turn off LED when effect is complete
set_color(0, 0, 0)
print("Twinkle effect complete!")
# Run twinkle effect for 5 seconds
twinkle_effect(5)
```
#### Random Number Generation
The twinkle effect uses two types of randomness:
1. **Random Colors**: `random.randint(0, 255)` generates values from 0 to 255
2. **Random Brightness**: Controls how bright each twinkle appears
3. **Random Timing**: `random.uniform(0.1, 0.5)` creates natural timing variations
## Conclusion
These advanced blinking effects demonstrate the creative potential of the WS2812 LED. By understanding color theory, timing, and mathematical relationships, you can create sophisticated lighting patterns that enhance user experience and add visual appeal to your projects.
The key to successful effects is balancing performance, memory usage, and visual appeal. Start with simple effects and gradually add complexity as you become more comfortable with the concepts.
Remember to experiment with different timing values, color combinations, and effect parameters to create unique lighting patterns that suit your specific application.
- Choosing a selection results in a full page refresh.