hi all,
I’m creating a natural light simulation from sunrise > daytime
> sunset, and figured out how to use self-made FastLED palettes
animating over very long timeframes, a whole day in this case. Below,
for practical testing reasons, squeezed into 10 minutes with the sunrise
part only. The total duration is divided into 256 intervals, so the
strip updates every 2.3 seconds over 10 minutes. Later, the update
intervals will lengthen, with the sunrise duration stretched over 3
hours. So far, so good.
But for good realism, I need to introduce the effect of light passing
through long grass, shrubs, foliage or clouds. That means that while
the palette transitions do their thing, random LEDs have to randomly
“shimmer” and very slowly at that, meaning dimming down and up again
just about 10%.
In other words, while with every interval all LEDs of the strip
receive new colour values from the active palette in skyEffect() and
then the result is displayed with FastLED.show() in loop(), a clouds()
function somehow needs to modify these colour values, before the “final
result” (palette transition of all LEDs in unison + changed brightness
of random LEDs randomly) is displayed.
Maybe you or any of the resident effect wizards has an idea how that shimmering effect can be “overlaid”?
Any suggestions very much appreciated!
/**** Skylight */
/* Adafruit Metro Mini, 1m APA102C LED strip */
/* LIBRARIES */
#include "FastLED.h"
/* VARIABLES */
const byte pinData = 3;
const byte pinClock = 4;
const byte ledCount = 144; // Standard number for 1m APA102C LED strip
byte maxBrightness = 128; // Values from 0 - 255, can be changed interactively with a potentiometer
DEFINE_GRADIENT_PALETTE(testPalette) {
0, 255, 0, 0,
128, 0, 255, 0,
255, 0, 0, 255
}; // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png .index.html
DEFINE_GRADIENT_PALETTE(sunsetSky) {
0, 10, 62, 123,
36, 56, 130, 103,
87, 153, 225, 85,
100, 199, 217, 68,
107, 255, 207, 54,
115, 247, 152, 57,
120, 239, 107, 61,
128, 247, 152, 57,
180, 255, 207, 54,
223, 255, 227, 48,
255, 255, 248, 42
};
DEFINE_GRADIENT_PALETTE(midsummerSky) { // Only this one is used for this 10 minute demo
0, 33, 55, 153,
25, 80, 119, 197,
89, 153, 215, 250,
95, 199, 233, 252,
102, 255, 255, 255,
120, 197, 219, 240,
147, 150, 187, 223,
200, 159, 171, 172,
255, 169, 154, 128
};
DEFINE_GRADIENT_PALETTE(cloudySky) {
0, 152, 164, 155,
30, 139, 152, 140,
64, 126, 141, 128,
92, 80, 95, 82,
107, 46, 59, 47,
114, 74, 88, 71,
123, 110, 124, 102,
196, 46, 58, 39,
255, 11, 18, 8
};
CRGBPalette16 activePalette = midsummerSky;
struct CRGB leds[ledCount];
/* FUNCTIONS ****/
void setup() {
LEDS.addLeds<APA102, pinData, pinClock, BGR>(leds, ledCount); // BGR for APA102C LED strips
LEDS.setCorrection(Candle); // Or Tungsten40W
// LEDS.setCorrection(UncorrectedColor);
} // End of setup
void loop() {
skyEffect();
FastLED.show();
} // End of loop
void skyEffect() {
static const float transitionDuration = 10; // Minutes (10 minutes: one step = 2343.75 milliseconds ~ 2.3 seconds)
static const float interval = ((float)(transitionDuration * 60) / 256) * 1000; // Steps in milliseconds
static uint8_t paletteIndex = 0; // Current gradient palette colour
CRGB colour = ColorFromPalette(activePalette, paletteIndex, maxBrightness, LINEARBLEND); // Or use a built-in palette
fill_solid(leds, ledCount, colour); // Light the whole strip with the colour fetched from the palette
EVERY_N_MILLISECONDS(interval) { // Traverse the palette
if (paletteIndex < 240) { // Don't use 255, see https://github.com/FastLED/FastLED/issues/515#issuecomment-340627525
paletteIndex++;
}
}
} // End of skyEffect