FastLED 3.9.7
Loading...
Searching...
No Matches
Pacifica.ino
Go to the documentation of this file.
1
4
5//
6// "Pacifica"
7// Gentle, blue-green ocean waves.
8// December 2019, Mark Kriegsman and Mary Corey March.
9// For Dan.
10//
11
12#define FASTLED_ALLOW_INTERRUPTS 0
13#include <FastLED.h>
15
16#define DATA_PIN 3
17#define NUM_LEDS 60
18#define MAX_POWER_MILLIAMPS 500
19#define LED_TYPE WS2812B
20#define COLOR_ORDER GRB
21
23
24CRGB leds[NUM_LEDS];
25
26void setup() {
27 delay( 3000); // 3 second delay for boot recovery, and a moment of silence
28 FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS)
29 .setCorrection( TypicalLEDStrip );
30 FastLED.setMaxPowerInVoltsAndMilliamps( 5, MAX_POWER_MILLIAMPS);
31}
32
33void loop()
34{
36 pacifica_loop();
37 FastLED.show();
38 }
39}
40
42//
43// The code for this animation is more complicated than other examples, and
44// while it is "ready to run", and documented in general, it is probably not
45// the best starting point for learning. Nevertheless, it does illustrate some
46// useful techniques.
47//
49//
50// In this animation, there are four "layers" of waves of light.
51//
52// Each layer moves independently, and each is scaled separately.
53//
54// All four wave layers are added together on top of each other, and then
55// another filter is applied that adds "whitecaps" of brightness where the
56// waves line up with each other more. Finally, another pass is taken
57// over the led array to 'deepen' (dim) the blues and greens.
58//
59// The speed and scale and motion each layer varies slowly within independent
60// hand-chosen ranges, which is why the code has a lot of low-speed 'beatsin8' functions
61// with a lot of oddly specific numeric ranges.
62//
63// These three custom blue-green color palettes were inspired by the colors found in
64// the waters off the southern coast of California, https://goo.gl/maps/QQgd97jjHesHZVxQ7
65//
66CRGBPalette16 pacifica_palette_1 =
67 { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
68 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
69CRGBPalette16 pacifica_palette_2 =
70 { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
71 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
72CRGBPalette16 pacifica_palette_3 =
73 { 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33,
74 0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF };
75
76
77void pacifica_loop()
78{
79 // Increment the four "color index start" counters, one for each wave layer.
80 // Each is incremented at a different speed, and the speeds vary over time.
81 static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
82 static uint32_t sLastms = 0;
83 uint32_t ms = GET_MILLIS();
84 uint32_t deltams = ms - sLastms;
85 sLastms = ms;
86 uint16_t speedfactor1 = beatsin16(3, 179, 269);
87 uint16_t speedfactor2 = beatsin16(4, 179, 269);
88 uint32_t deltams1 = (deltams * speedfactor1) / 256;
89 uint32_t deltams2 = (deltams * speedfactor2) / 256;
90 uint32_t deltams21 = (deltams1 + deltams2) / 2;
91 sCIStart1 += (deltams1 * beatsin88(1011,10,13));
92 sCIStart2 -= (deltams21 * beatsin88(777,8,11));
93 sCIStart3 -= (deltams1 * beatsin88(501,5,7));
94 sCIStart4 -= (deltams2 * beatsin88(257,4,6));
95
96 // Clear out the LED array to a dim background blue-green
97 fill_solid( leds, NUM_LEDS, CRGB( 2, 6, 10));
98
99 // Render each of four layers, with different scales and speeds, that vary over time
100 pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0-beat16( 301) );
101 pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4, 6 * 256, 9 * 256), beatsin8( 17, 40, 80), beat16( 401) );
102 pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10,38), 0-beat16(503));
103 pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10,28), beat16(601));
104
105 // Add brighter 'whitecaps' where the waves lines up more
106 pacifica_add_whitecaps();
107
108 // Deepen the blues and greens a bit
109 pacifica_deepen_colors();
110}
111
112// Add one layer of waves into the led array
113void pacifica_one_layer( CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff)
114{
115 uint16_t ci = cistart;
116 uint16_t waveangle = ioff;
117 uint16_t wavescale_half = (wavescale / 2) + 20;
118 for( uint16_t i = 0; i < NUM_LEDS; i++) {
119 waveangle += 250;
120 uint16_t s16 = sin16( waveangle ) + 32768;
121 uint16_t cs = scale16( s16 , wavescale_half ) + wavescale_half;
122 ci += cs;
123 uint16_t sindex16 = sin16( ci) + 32768;
124 uint8_t sindex8 = scale16( sindex16, 240);
125 CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND);
126 leds[i] += c;
127 }
128}
129
130// Add extra 'white' to areas where the four layers of light have lined up brightly
131void pacifica_add_whitecaps()
132{
133 uint8_t basethreshold = beatsin8( 9, 55, 65);
134 uint8_t wave = beat8( 7 );
135
136 for( uint16_t i = 0; i < NUM_LEDS; i++) {
137 uint8_t threshold = scale8( sin8( wave), 20) + basethreshold;
138 wave += 7;
139 uint8_t l = leds[i].getAverageLight();
140 if( l > threshold) {
141 uint8_t overage = l - threshold;
142 uint8_t overage2 = qadd8( overage, overage);
143 leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2));
144 }
145 }
146}
147
148// Deepen the blues and greens
149void pacifica_deepen_colors()
150{
151 for( uint16_t i = 0; i < NUM_LEDS; i++) {
152 leds[i].blue = scale8( leds[i].blue, 145);
153 leds[i].green= scale8( leds[i].green, 200);
154 leds[i] |= CRGB( 2, 5, 7);
155 }
156}
CFastLED FastLED
Global LED strip management instance.
Definition FastLED.cpp:45
central include file for FastLED, defines the CFastLED class/object
void show(uint8_t scale)
Update all our controllers with the current led colors, using the passed in brightness.
Definition FastLED.cpp:94
void setMaxPowerInVoltsAndMilliamps(uint8_t volts, uint32_t milliamps)
Set the maximum power to be used, given in volts and milliamps.
Definition FastLED.h:732
static CLEDController & addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset=0)
Add a CLEDController instance to the world.
Definition FastLED.cpp:79
RGB color palette with 16 discrete values.
Definition colorutils.h:997
LIB8STATIC uint8_t beat8(accum88 beats_per_minute, uint32_t timebase=0)
Generates an 8-bit "sawtooth" wave at a given BPM.
Definition lib8tion.h:923
LIB8STATIC uint16_t beatsin16(accum88 beats_per_minute, uint16_t lowest=0, uint16_t highest=65535, uint32_t timebase=0, uint16_t phase_offset=0)
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:957
LIB8STATIC uint16_t beat16(accum88 beats_per_minute, uint32_t timebase=0)
Generates a 16-bit "sawtooth" wave at a given BPM.
Definition lib8tion.h:913
LIB8STATIC uint8_t beatsin8(accum88 beats_per_minute, uint8_t lowest=0, uint8_t highest=255, uint32_t timebase=0, uint8_t phase_offset=0)
Generates an 8-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:975
LIB8STATIC uint16_t beatsin88(accum88 beats_per_minute_88, uint16_t lowest=0, uint16_t highest=65535, uint32_t timebase=0, uint16_t phase_offset=0)
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:939
@ TypicalLEDStrip
Typical values for SMD5050 LEDs.
Definition color.h:19
void fill_solid(struct CRGB *targetArray, int numToFill, const struct CRGB &color)
Fill a range of LEDs with a solid color.
LIB8STATIC_ALWAYS_INLINE uint8_t qadd8(uint8_t i, uint8_t j)
Add one byte to another, saturating at 0xFF.
Definition math8.h:31
CRGB ColorFromPalette(const CRGBPalette16 &pal, uint8_t index, uint8_t brightness, TBlendType blendType)
Get a color from a palette.
@ LINEARBLEND
Linear interpolation between palette entries, with wrap-around from end to the beginning again.
LIB8STATIC uint16_t scale16(uint16_t i, fract16 scale)
Scale a 16-bit unsigned value by an 16-bit value, which is treated as the numerator of a fraction who...
Definition scale8.h:540
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Definition scale8.h:34
#define GET_MILLIS
The a number of functions need access to a millisecond counter in order to keep time.
Definition lib8tion.h:837
#define EVERY_N_MILLISECONDS(N)
Alias for EVERY_N_MILLIS.
Definition lib8tion.h:1318
#define sin16
Platform-independent alias of the fast sin implementation.
Definition trig8.h:91
#define sin8
Platform-independent alias of the fast sin implementation.
Definition trig8.h:207
#define FASTLED_USING_NAMESPACE
"Using" directive for the namespace
Definition namespace.h:18
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:54
uint8_t blue
Blue channel value.
Definition crgb.h:67
FASTLED_FORCE_INLINE uint8_t getAverageLight() const
Get the average of the R, G, and B values.
Definition crgb.hpp:168
uint8_t green
Green channel value.
Definition crgb.h:63