Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <FastLED.h>
- #define LED_TYPE WS2812B
- #define COLOR_ORDER GRB
- //bussard setup
- #define DATA_PIN1 3
- #define NUM_LEDS1 8
- CRGBArray<NUM_LEDS1> leds1;
- #define TWINKLE_SPEED 5
- #define TWINKLE_DENSITY 8
- #define SECONDS_PER_PALETTE 30
- CRGB gBackgroundColor = CRGB::Black;
- #define AUTO_SELECT_BACKGROUND_COLOR 0
- #define COOL_LIKE_INCANDESCENT 1
- CRGBPalette16 gCurrentPalette;
- CRGBPalette16 gTargetPalette;
- //warp setup
- #define DATA_PIN2 5
- #define NUM_LEDS2 30
- #define MAX_POWER_MILLIAMPS 500
- #define FASTLED_ALLOW_INTERRUPTS 0
- FASTLED_USING_NAMESPACE
- //deflector setup
- //////////////////////////////////////////////////////////////////////////
- CRGB leds2[NUM_LEDS2];
- void setup() {
- //bussard
- delay(3000); //safety startup delay
- FastLED.addLeds<LED_TYPE, DATA_PIN1, COLOR_ORDER>(leds1, NUM_LEDS1)
- .setCorrection(TypicalLEDStrip);
- chooseNextColorPalette(gTargetPalette);
- //warp
- FastLED.addLeds<LED_TYPE, DATA_PIN2, COLOR_ORDER>(leds2, NUM_LEDS2)
- .setCorrection(TypicalLEDStrip);
- FastLED.setMaxPowerInVoltsAndMilliamps(5, MAX_POWER_MILLIAMPS);
- }
- void loop()
- {
- EVERY_N_SECONDS(SECONDS_PER_PALETTE) {
- chooseNextColorPalette(gTargetPalette);
- }
- EVERY_N_MILLISECONDS(10) {
- nblendPaletteTowardPalette(gCurrentPalette, gTargetPalette, 12);
- }
- drawTwinkles(leds1);
- FastLED.show();
- }
- void drawTwinkles(CRGBSet& L) {
- uint16_t PRNG16 = 11337;
- uint32_t clock32 = millis();
- CRGB bg;
- if ((AUTO_SELECT_BACKGROUND_COLOR == 1) && (gCurrentPalette[0] == gCurrentPalette[1])) {
- bg = gCurrentPalette[0];
- uint8_t bglight = bg.getAverageLight();
- if (bglight > 64) {
- bg.nscale8_video(16); // very bright, so scale to 1/16th
- } else if (bglight > 16) {
- bg.nscale8_video(64); // not that bright, so scale to 1/4th
- } else {
- bg.nscale8_video(86); // dim, scale to 1/3rd.
- }
- } else {
- bg = gBackgroundColor; // just use the explicitly defined background color
- }
- uint8_t backgroundBrightness = bg.getAverageLight();
- for (CRGB& pixel : L) {
- PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
- uint16_t myclockoffset16 = PRNG16; // use that number as clock offset
- PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
- // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths)
- uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF) >> 4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08;
- uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
- uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel
- // We now have the adjusted 'clock' for this pixel, now we call
- // the function that computes what color the pixel should be based
- // on the "brightness = f( time )" idea.
- CRGB c = computeOneTwinkle(myclock30, myunique8);
- uint8_t cbright = c.getAverageLight();
- int16_t deltabright = cbright - backgroundBrightness;
- if (deltabright >= 32 || (!bg)) {
- // If the new pixel is significantly brighter than the background color,
- // use the new color.
- pixel = c;
- } else if (deltabright > 0) {
- // If the new pixel is just slightly brighter than the background color,
- // mix a blend of the new color and the background color
- pixel = blend(bg, c, deltabright * 8);
- } else {
- // if the new pixel is not at all brighter than the background color,
- // just use the background color.
- pixel = bg;
- }
- }
- }
- CRGB computeOneTwinkle(uint32_t ms, uint8_t salt) {
- uint16_t ticks = ms >> (8 - TWINKLE_SPEED);
- uint8_t fastcycle8 = ticks;
- uint16_t slowcycle16 = (ticks >> 8) + salt;
- slowcycle16 += sin8(slowcycle16);
- slowcycle16 = (slowcycle16 * 2053) + 1384;
- uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8);
- uint8_t bright = 0;
- if (((slowcycle8 & 0x0E) / 2) < TWINKLE_DENSITY) {
- bright = attackDecayWave8(fastcycle8);
- }
- uint8_t hue = slowcycle8 - salt;
- CRGB c;
- if (bright > 0) {
- c = ColorFromPalette(gCurrentPalette, hue, bright, NOBLEND);
- if (COOL_LIKE_INCANDESCENT == 1) {
- coolLikeIncandescent(c, fastcycle8);
- }
- } else {
- c = CRGB::Black;
- }
- return c;
- }
- uint8_t attackDecayWave8(uint8_t i) {
- if (i < 86) {
- return i * 3;
- } else {
- i -= 86;
- return 255 - (i + (i / 2));
- }
- }
- void coolLikeIncandescent(CRGB& c, uint8_t phase) {
- if (phase < 128) return;
- uint8_t cooling = (phase - 128) >> 4;
- c.g = qsub8(c.g, cooling);
- c.b = qsub8(c.b, cooling * 2);
- }
- // A mostly red palette with green accents and white trim.
- // "CRGB::Gray" is used as white to keep the brightness more uniform.
- const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
- CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
- CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
- CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green };
- // A mostly (dark) green palette with red berries.
- #define Holly_Green 0x00580c
- #define Holly_Red 0xB00402
- const TProgmemRGBPalette16 Holly_p FL_PROGMEM = { Holly_Green, Holly_Green, Holly_Green, Holly_Green,
- Holly_Green, Holly_Green, Holly_Green, Holly_Green,
- Holly_Green, Holly_Green, Holly_Green, Holly_Green,
- Holly_Green, Holly_Green, Holly_Green, Holly_Red };
- // A red and white striped palette
- // "CRGB::Gray" is used as white to keep the brightness more uniform.
- const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
- CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray,
- CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
- CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray };
- // A mostly blue palette with white accents.
- // "CRGB::Gray" is used as white to keep the brightness more uniform.
- const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM = { CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
- CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
- CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
- CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray };
- // A pure "fairy light" palette with some brightness variations
- #define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2)
- #define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4)
- const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM = { CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight,
- HALFFAIRY, HALFFAIRY, CRGB::FairyLight, CRGB::FairyLight,
- QUARTERFAIRY, QUARTERFAIRY, CRGB::FairyLight, CRGB::FairyLight,
- CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight };
- // A palette of soft snowflakes with the occasional bright one
- const TProgmemRGBPalette16 Snow_p FL_PROGMEM = { 0x304048, 0x304048, 0x304048, 0x304048,
- 0x304048, 0x304048, 0x304048, 0x304048,
- 0x304048, 0x304048, 0x304048, 0x304048,
- 0x304048, 0x304048, 0x304048, 0xE0F0FF };
- // A palette reminiscent of large 'old-school' C9-size tree lights
- // in the five classic colors: red, orange, green, blue, and white.
- #define C9_Red 0xB80400
- #define C9_Orange 0x902C02
- #define C9_Green 0x046002
- #define C9_Blue 0x070758
- #define C9_White 0x606820
- const TProgmemRGBPalette16 RetroC9_p FL_PROGMEM = { C9_Red, C9_Orange, C9_Red, C9_Orange,
- C9_Orange, C9_Red, C9_Orange, C9_Red,
- C9_Green, C9_Green, C9_Green, C9_Green,
- C9_Blue, C9_Blue, C9_Blue,
- C9_White };
- // A cold, icy pale blue palette
- #define Ice_Blue1 0x0C1040
- #define Ice_Blue2 0x182080
- #define Ice_Blue3 0x5080C0
- const TProgmemRGBPalette16 Ice_p FL_PROGMEM = {
- Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
- Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
- Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
- Ice_Blue2, Ice_Blue2, Ice_Blue2, Ice_Blue3
- };
- // Add or remove palette names from this list to control which color
- // palettes are used, and in what order.
- const TProgmemRGBPalette16* ActivePaletteList[] = {
- &FairyLight_p,
- };
- // Advance to the next color palette in the list (above).
- void chooseNextColorPalette(CRGBPalette16& pal) {
- const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]);
- static uint8_t whichPalette = -1;
- whichPalette = addmod8(whichPalette, 1, numberOfPalettes);
- pal = *(ActivePaletteList[whichPalette]);
- }
- //warp
- EVERY_N_MILLISECONDS(20) {
- pacifica_loop();
- FastLED.show();
- }
- CRGBPalette16 pacifica_palette_1 = { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
- 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
- CRGBPalette16 pacifica_palette_2 = { 0x000007, 0x000009, 0x00000B, 0x00000D, 0x000010, 0x000012, 0x000014, 0x000017,
- 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
- CRGBPalette16 pacifica_palette_3 = { 0x010018, 0x030025, 0x020014, 0x03001A, 0x100020, 0x050027, 0x010020, 0x010030,
- 0x090039, 0x030040, 0x050050, 0x000060, 0x000070, 0x030380, 0x101010, 0x100510 };
- void pacifica_loop() {
- // Increment the four "color index start" counters, one for each wave layer.
- // Each is incremented at a different speed, and the speeds vary over time.
- static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
- static uint32_t sLastms = 0;
- uint32_t ms = GET_MILLIS();
- uint32_t deltams = ms - sLastms;
- sLastms = ms;
- uint16_t speedfactor1 = beatsin16(3, 179, 269);
- uint16_t speedfactor2 = beatsin16(4, 179, 269);
- uint32_t deltams1 = (deltams * speedfactor1) / 256;
- uint32_t deltams2 = (deltams * speedfactor2) / 256;
- uint32_t deltams21 = (deltams1 + deltams2) / 2;
- sCIStart1 += (deltams1 * beatsin88(1011, 10, 13));
- sCIStart2 -= (deltams21 * beatsin88(777, 8, 11));
- sCIStart3 -= (deltams1 * beatsin88(501, 5, 7));
- sCIStart4 -= (deltams2 * beatsin88(257, 4, 6));
- // Clear out the LED array to a dim background blue-green
- fill_solid(leds2, NUM_LEDS2, CRGB(2, 6, 10));
- // Render each of four layers, with different scales and speeds, that vary over time
- pacifica_one_layer(pacifica_palette_1, sCIStart1, beatsin16(3, 11 * 256, 14 * 256), beatsin8(10, 70, 130), 0 - beat16(301));
- pacifica_one_layer(pacifica_palette_2, sCIStart2, beatsin16(4, 6 * 256, 9 * 256), beatsin8(17, 40, 80), beat16(401));
- pacifica_one_layer(pacifica_palette_3, sCIStart3, 6 * 256, beatsin8(9, 10, 38), 0 - beat16(503));
- pacifica_one_layer(pacifica_palette_3, sCIStart4, 5 * 256, beatsin8(8, 10, 28), beat16(601));
- // Add brighter 'whitecaps' where the waves lines up more
- pacifica_add_whitecaps();
- // Deepen the blues and greens a bit
- pacifica_deepen_colors();
- }
- // Add one layer of waves into the led array
- void pacifica_one_layer(CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) {
- uint16_t ci = cistart;
- uint16_t waveangle = ioff;
- uint16_t wavescale_half = (wavescale / 2) + 20;
- for (uint16_t i = 0; i < NUM_LEDS2; i++) {
- waveangle += 250;
- uint16_t s16 = sin16(waveangle) + 32768;
- uint16_t cs = scale16(s16, wavescale_half) + wavescale_half;
- ci += cs;
- uint16_t sindex16 = sin16(ci) + 32768;
- uint8_t sindex8 = scale16(sindex16, 240);
- CRGB c = ColorFromPalette(p, sindex8, bri, LINEARBLEND);
- leds2[i] += c;
- }
- }
- // Add extra 'white' to areas where the four layers of light have lined up brightly
- void pacifica_add_whitecaps() {
- uint8_t basethreshold = beatsin8(9, 55, 65);
- uint8_t wave = beat8(7);
- for (uint16_t i = 0; i < NUM_LEDS2; i++) {
- uint8_t threshold = scale8(sin8(wave), 20) + basethreshold;
- wave += 7;
- uint8_t l = leds2[i].getAverageLight();
- if (l > threshold) {
- uint8_t overage = l - threshold;
- uint8_t overage2 = qadd8(overage, overage);
- leds2[i] += CRGB(overage, overage2, qadd8(overage2, overage2));
- }
- }
- }
- // Deepen the blues and greens
- void pacifica_deepen_colors() {
- for (uint16_t i = 0; i < NUM_LEDS2; i++) {
- leds2[i].blue = scale8(leds2[i].blue, 200);
- leds2[i].green = scale8(leds2[i].green, 100);
- leds2[i] |= CRGB(5, 0, 15);
- }
- }
Add Comment
Please, Sign In to add comment