【花雕体验】19 合宙ESP32_C3点亮WS2812B硬屏 
  实验程序五:TwinkleFOX:淡入淡出的闪烁“节日灯“ 
 
			
			
			- /*
 -   【花雕体验】19 合宙ESP32_C3点亮WS2812B硬屏
 -   实验程序五:TwinkleFOX:淡入淡出的闪烁“节日灯“
 - */
 - 
 - #include "FastLED.h"
 - 
 - #define NUM_LEDS      256
 - #define LED_TYPE   WS2811
 - #define COLOR_ORDER   GRB
 - #define DATA_PIN        9
 - //#define CLK_PIN       4
 - #define VOLTS          12
 - #define MAX_MA       4000
 - 
 - //  TwinkleFOX: Twinkling 'holiday' lights that fade in and out.
 - //  Colors are chosen from a palette; a few palettes are provided.
 - //
 - //  This December 2015 implementation improves on the December 2014 version
 - //  in several ways:
 - //  - smoother fading, compatible with any colors and any palettes
 - //  - easier control of twinkle speed and twinkle density
 - //  - supports an optional 'background color'
 - //  - takes even less RAM: zero RAM overhead per pixel
 - //  - illustrates a couple of interesting techniques (uh oh...)
 - //
 - //  The idea behind this (new) implementation is that there's one
 - //  basic, repeating pattern that each pixel follows like a waveform:
 - //  The brightness rises from 0..255 and then falls back down to 0.
 - //  The brightness at any given point in time can be determined as
 - //  as a function of time, for example:
 - //    brightness = sine( time ); // a sine wave of brightness over time
 - //
 - //  So the way this implementation works is that every pixel follows
 - //  the exact same wave function over time.  In this particular case,
 - //  I chose a sawtooth triangle wave (triwave8) rather than a sine wave,
 - //  but the idea is the same: brightness = triwave8( time ).
 - //
 - //  Of course, if all the pixels used the exact same wave form, and
 - //  if they all used the exact same 'clock' for their 'time base', all
 - //  the pixels would brighten and dim at once -- which does not look
 - //  like twinkling at all.
 - //
 - //  So to achieve random-looking twinkling, each pixel is given a
 - //  slightly different 'clock' signal.  Some of the clocks run faster,
 - //  some run slower, and each 'clock' also has a random offset from zero.
 - //  The net result is that the 'clocks' for all the pixels are always out
 - //  of sync from each other, producing a nice random distribution
 - //  of twinkles.
 - //
 - //  The 'clock speed adjustment' and 'time offset' for each pixel
 - //  are generated randomly.  One (normal) approach to implementing that
 - //  would be to randomly generate the clock parameters for each pixel
 - //  at startup, and store them in some arrays.  However, that consumes
 - //  a great deal of precious RAM, and it turns out to be totally
 - //  unnessary!  If the random number generate is 'seeded' with the
 - //  same starting value every time, it will generate the same sequence
 - //  of values every time.  So the clock adjustment parameters for each
 - //  pixel are 'stored' in a pseudo-random number generator!  The PRNG
 - //  is reset, and then the first numbers out of it are the clock
 - //  adjustment parameters for the first pixel, the second numbers out
 - //  of it are the parameters for the second pixel, and so on.
 - //  In this way, we can 'store' a stable sequence of thousands of
 - //  random clock adjustment parameters in literally two bytes of RAM.
 - //
 - //  There's a little bit of fixed-point math involved in applying the
 - //  clock speed adjustments, which are expressed in eighths.  Each pixel's
 - //  clock speed ranges from 8/8ths of the system clock (i.e. 1x) to
 - //  23/8ths of the system clock (i.e. nearly 3x).
 - //
 - //  On a basic Arduino Uno or Leonardo, this code can twinkle 300+ pixels
 - //  smoothly at over 50 updates per seond.
 - //
 - //  -Mark Kriegsman, December 2015
 - 
 - CRGBArray<NUM_LEDS> leds;
 - 
 - // Overall twinkle speed.
 - // 0 (VERY slow) to 8 (VERY fast).
 - // 4, 5, and 6 are recommended, default is 4.
 - #define TWINKLE_SPEED 8
 - 
 - // Overall twinkle density.
 - // 0 (NONE lit) to 8 (ALL lit at once).
 - // Default is 5.
 - #define TWINKLE_DENSITY 5
 - 
 - // How often to change color palettes.
 - #define SECONDS_PER_PALETTE  10
 - // Also: toward the bottom of the file is an array
 - // called "ActivePaletteList" which controls which color
 - // palettes are used; you can add or remove color palettes
 - // from there freely.
 - 
 - // Background color for 'unlit' pixels
 - // Can be set to CRGB::Black if desired.
 - CRGB gBackgroundColor = CRGB::Black;
 - // Example of dim incandescent fairy light background color
 - // CRGB gBackgroundColor = CRGB(CRGB::FairyLight).nscale8_video(16);
 - 
 - // If AUTO_SELECT_BACKGROUND_COLOR is set to 1,
 - // then for any palette where the first two entries
 - // are the same, a dimmed version of that color will
 - // automatically be used as the background color.
 - #define AUTO_SELECT_BACKGROUND_COLOR 0
 - 
 - // If COOL_LIKE_INCANDESCENT is set to 1, colors will
 - // fade out slighted 'reddened', similar to how
 - // incandescent bulbs change color as they get dim down.
 - #define COOL_LIKE_INCANDESCENT 1
 - 
 - 
 - CRGBPalette16 gCurrentPalette;
 - CRGBPalette16 gTargetPalette;
 - 
 - void setup() {
 -   delay( 2000 ); //safety startup delay
 -   FastLED.setMaxPowerInVoltsAndMilliamps( VOLTS, MAX_MA);
 -   FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS)
 -   .setCorrection(TypicalLEDStrip);
 -   FastLED.setBrightness(22);
 - 
 -   chooseNextColorPalette(gTargetPalette);
 - }
 - 
 - 
 - void loop(){
 -   EVERY_N_SECONDS( SECONDS_PER_PALETTE ) {
 -     chooseNextColorPalette( gTargetPalette );
 -   }
 - 
 -   EVERY_N_MILLISECONDS( 10 ) {
 -     nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12);
 -   }
 - 
 -   drawTwinkles( leds);
 - 
 -   FastLED.show();
 - }
 - 
 - 
 - //  This function loops over each pixel, calculates the
 - //  adjusted 'clock' that this pixel should use, and calls
 - //  "CalculateOneTwinkle" on each pixel.  It then displays
 - //  either the twinkle color of the background color,
 - //  whichever is brighter.
 - void drawTwinkles( CRGBSet& L)
 - {
 -   // "PRNG16" is the pseudorandom number generator
 -   // It MUST be reset to the same starting value each time
 -   // this function is called, so that the sequence of 'random'
 -   // numbers that it generates is (paradoxically) stable.
 -   uint16_t PRNG16 = 11337;
 - 
 -   uint32_t clock32 = millis();
 - 
 -   // Set up the background color, "bg".
 -   // if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of
 -   // the current palette are identical, then a deeply faded version of
 -   // that color is used for the background color
 -   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;
 -     }
 -   }
 - }
 - 
 - 
 - //  This function takes a time in pseudo-milliseconds,
 - //  figures out brightness = f( time ), and also hue = f( time )
 - //  The 'low digits' of the millisecond time are used as
 - //  input to the brightness wave function.
 - //  The 'high digits' are used to select a color, so that the color
 - //  does not change over the course of the fade-in, fade-out
 - //  of one cycle of the brightness wave function.
 - //  The 'high digits' are also used to determine whether this pixel
 - //  should light at all during this cycle, based on the TWINKLE_DENSITY.
 - 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;
 - }
 - 
 - 
 - // This function is like 'triwave8', which produces a
 - // symmetrical up-and-down triangle sawtooth waveform, except that this
 - // function produces a triangle wave with a faster attack and a slower decay:
 - //
 - //     / \
 - //    /     \
 - //   /         \
 - //  /             \
 - //
 - 
 - uint8_t attackDecayWave8( uint8_t i)
 - {
 -   if ( i < 86) {
 -     return i * 3;
 -   } else {
 -     i -= 86;
 -     return 255 - (i + (i / 2));
 -   }
 - }
 - 
 - // This function takes a pixel, and if its in the 'fading down'
 - // part of the cycle, it adjusts the color a little bit like the
 - // way that incandescent bulbs fade toward 'red' as they dim.
 - 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[] = {
 -   &RetroC9_p,
 -   &BlueWhite_p,
 -   &RainbowColors_p,
 -   &FairyLight_p,
 -   &RedGreenWhite_p,
 -   &PartyColors_p,
 -   &RedWhite_p,
 -   &Snow_p,
 -   &Holly_p,
 -   &Ice_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]);
 - }
 
  复制代码
  
 
 |