Advertisement
Guest User

TwinkeFOXServer

a guest
Dec 22nd, 2015
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.10 KB | None | 0 0
  1. #include "FastLED.h"
  2.  
  3. #if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
  4. #warning "Requires FastLED 3.1 or later; check github for latest code."
  5. #endif
  6.  
  7.  
  8. #define NUM_LEDS      60
  9. #define LED_TYPE   WS2811
  10. #define COLOR_ORDER   GRB
  11. #define DATA_PIN        13
  12. //#define CLK_PIN       4
  13. #define VOLTS          5
  14. #define MAX_MA       1000
  15.  
  16.  
  17.  
  18. // Modified version of TwinkleFOX -- the server version.
  19. //
  20. // + TWINKLE_DENSITY now ranges 0..16 (instead of 0..8)
  21. // + Average speed of twinkles is faster now even at the same TWINKLE_SPEED
  22. // + Small change to pattern-breaking use of salt
  23.  
  24.  
  25. CRGBArray<NUM_LEDS> leds;
  26.  
  27. // Overall twinkle speed.
  28. // 0 (VERY slow) to 8 (VERY fast).  
  29. #define TWINKLE_SPEED 5
  30.  
  31. // Overall twinkle density.
  32. // 0 (NONE lit) to 16 (ALL lit at once).  
  33. #define TWINKLE_DENSITY 10
  34.  
  35. // How often to change color palettes.
  36. #define SECONDS_PER_PALETTE  30
  37. // Also: toward the bottom of the file is an array
  38. // called "ActivePaletteList" which controls which color
  39. // palettes are used; you can add or remove color palettes
  40. // from there freely.
  41.  
  42. // Background color for 'unlit' pixels
  43. // Can be set to CRGB::Black if desired.
  44. CRGB gBackgroundColor = CRGB::Black;
  45. // Example of dim incandescent fairy light background color
  46. // CRGB gBackgroundColor = CRGB(CRGB::FairyLight).nscale8_video(16);
  47.  
  48. // If AUTO_SELECT_BACKGROUND_COLOR is set to 1,
  49. // then for any palette where the first two entries
  50. // are the same, a dimmed version of that color will
  51. // automatically be used as the background color.
  52. #define AUTO_SELECT_BACKGROUND_COLOR 0
  53.  
  54. // If COOL_LIKE_INCANDESCENT is set to 1, colors will
  55. // fade out slighted 'reddened', similar to how
  56. // incandescent bulbs change color as they get dim down.
  57. #define COOL_LIKE_INCANDESCENT 1
  58.  
  59.  
  60. CRGBPalette16 gCurrentPalette;
  61. CRGBPalette16 gTargetPalette;
  62.  
  63. void setup() {
  64.   delay( 3000 ); //safety startup delay
  65.   FastLED.setMaxPowerInVoltsAndMilliamps( VOLTS, MAX_MA);
  66.   FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS)
  67.     .setCorrection(TypicalLEDStrip);
  68.  
  69.   chooseNextColorPalette(gTargetPalette);
  70. }
  71.  
  72.  
  73. void loop()
  74. {
  75.   EVERY_N_SECONDS( SECONDS_PER_PALETTE ) {
  76.     chooseNextColorPalette( gTargetPalette );
  77.   }
  78.  
  79.   EVERY_N_MILLISECONDS( 10 ) {
  80.     nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12);
  81.   }
  82.  
  83.   drawTwinkles( leds);
  84.  
  85.   FastLED.show();
  86. }
  87.  
  88.  
  89. //  This function loops over each pixel, calculates the
  90. //  adjusted 'clock' that this pixel should use, and calls
  91. //  "CalculateOneTwinkle" on each pixel.  It then displays
  92. //  either the twinkle color of the background color,
  93. //  whichever is brighter.
  94. void drawTwinkles( CRGBSet& L)
  95. {
  96.   // "PRNG16" is the pseudorandom number generator
  97.   // It MUST be reset to the same starting value each time
  98.   // this function is called, so that the sequence of 'random'
  99.   // numbers that it generates is (paradoxically) stable.
  100.   uint16_t PRNG16 = 11337;
  101.  
  102.   uint32_t clock32 = millis();
  103.  
  104.   // Set up the background color, "bg".
  105.   // if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of
  106.   // the current palette are identical, then a deeply faded version of
  107.   // that color is used for the background color
  108.   CRGB bg;
  109.   if( (AUTO_SELECT_BACKGROUND_COLOR == 1) &&
  110.       (gCurrentPalette[0] == gCurrentPalette[1] )) {
  111.     bg = gCurrentPalette[0];
  112.     uint8_t bglight = bg.getAverageLight();
  113.     if( bglight > 64) {
  114.       bg.nscale8_video( 16); // very bright, so scale to 1/16th
  115.     } else if( bglight > 16) {
  116.       bg.nscale8_video( 64); // not that bright, so scale to 1/4th
  117.     } else {
  118.       bg.nscale8_video( 86); // dim, scale to 1/3rd.
  119.     }
  120.   } else {
  121.     bg = gBackgroundColor; // just use the explicitly defined background color
  122.   }
  123.  
  124.   uint8_t backgroundBrightness = bg.getAverageLight();
  125.  
  126.   for( CRGB& pixel: L) {
  127.     PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
  128.     uint16_t myclockoffset16= PRNG16; // use that number as clock offset
  129.     PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
  130.     // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths)
  131.     uint8_t myspeedmultiplierQ5_3 =  ((((PRNG16 & 0xFF)>>3) + (PRNG16 & 0x1F)) & 0x1F) + 0x10;
  132.     //uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
  133.     uint32_t myclock30 = (uint32_t)((((uint32_t)(clock32) + myclockoffset16) * myspeedmultiplierQ5_3) >> 3);
  134.     uint8_t  myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel
  135.    
  136.     // We now have the adjusted 'clock' for this pixel, now we call
  137.     // the function that computes what color the pixel should be based
  138.     // on the "brightness = f( time )" idea.
  139.     CRGB c = computeOneTwinkle( myclock30, myunique8);
  140.  
  141.     uint8_t cbright = c.getAverageLight();
  142.     int16_t deltabright = cbright - backgroundBrightness;
  143.     if( deltabright >= 32 || (!bg)) {
  144.       // If the new pixel is significantly brighter than the background color,
  145.       // use the new color.
  146.       pixel = c;
  147.     } else if( deltabright > 0 ) {
  148.       // If the new pixel is just slightly brighter than the background color,
  149.       // mix a blend of the new color and the background color
  150.       pixel = blend( bg, c, deltabright * 8);
  151.     } else {
  152.       // if the new pixel is not at all brighter than the background color,
  153.       // just use the background color.
  154.       pixel = bg;
  155.     }
  156.   }
  157. }
  158.  
  159.  
  160. //  This function takes a time in pseudo-milliseconds,
  161. //  figures out brightness = f( time ), and also hue = f( time )
  162. //  The 'low digits' of the millisecond time are used as
  163. //  input to the brightness wave function.  
  164. //  The 'high digits' are used to select a color, so that the color
  165. //  does not change over the course of the fade-in, fade-out
  166. //  of one cycle of the brightness wave function.
  167. //  The 'high digits' are also used to determine whether this pixel
  168. //  should light at all during this cycle, based on the TWINKLE_DENSITY.
  169. CRGB computeOneTwinkle( uint32_t ms, uint8_t salt)
  170. {
  171.   uint16_t ticks = ms >> (8-TWINKLE_SPEED);
  172.   uint8_t fastcycle8 = ticks;
  173.   uint8_t slowcycle8 = (ticks >> 8) + salt;
  174.  
  175.   uint8_t bright = 0;
  176.   if( ((slowcycle8 & 0x0F)) < TWINKLE_DENSITY) {
  177.     bright = attackDecayWave8( fastcycle8);
  178.   }
  179.  
  180.   uint8_t hue = (slowcycle8 * 16) + salt;
  181.   CRGB c = ColorFromPalette( gCurrentPalette, hue, bright, NOBLEND);
  182.   if( COOL_LIKE_INCANDESCENT == 1 ) {
  183.     coolLikeIncandescent( c, fastcycle8);
  184.   }
  185.   return c;
  186. }
  187.  
  188.  
  189. // This function is like 'triwave8', which produces a
  190. // symmetrical up-and-down triangle sawtooth waveform, except that this
  191. // function produces a triangle wave with a faster attack and a slower decay:
  192. //
  193. //     / \
  194. //    /     \
  195. //   /         \
  196. //  /             \
  197. //
  198.  
  199. uint8_t attackDecayWave8( uint8_t i)
  200. {
  201.   if( i < 86) {
  202.     return i * 3;
  203.   } else {
  204.     i -= 86;
  205.     return 255 - (i + (i/2));
  206.   }
  207. }
  208.  
  209. // This function takes a pixel, and if its in the 'fading down'
  210. // part of the cycle, it adjusts the color a little bit like the
  211. // way that incandescent bulbs fade toward 'red' as they dim.
  212. void coolLikeIncandescent( CRGB& c, uint8_t phase)
  213. {
  214.   if( phase < 128) return;
  215.  
  216.   uint8_t cooling = (phase - 128) >> 4;
  217.   c.g = qsub8( c.g, cooling);
  218.   c.b = qsub8( c.b, cooling * 2);
  219. }
  220.  
  221. // A mostly red palette with green accents and white trim.
  222. // "CRGB::Gray" is used as white to keep the brightness more uniform.
  223. const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM =
  224. {  CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  225.    CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  226.    CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
  227.    CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green };
  228.  
  229. // A mostly (dark) green palette with red berries.
  230. #define Holly_Green 0x00580c
  231. #define Holly_Red   0xB00402
  232. const TProgmemRGBPalette16 Holly_p FL_PROGMEM =
  233. {  Holly_Green, Holly_Green, Holly_Green, Holly_Green,
  234.    Holly_Green, Holly_Green, Holly_Green, Holly_Green,
  235.    Holly_Green, Holly_Green, Holly_Green, Holly_Green,
  236.    Holly_Green, Holly_Green, Holly_Green, Holly_Red
  237. };
  238.  
  239. // A red and white striped palette
  240. // "CRGB::Gray" is used as white to keep the brightness more uniform.
  241. const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM =
  242. {  CRGB::Red,  CRGB::Red,  CRGB::Red,  CRGB::Red,
  243.    CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray,
  244.    CRGB::Red,  CRGB::Red,  CRGB::Red,  CRGB::Red,
  245.    CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray };
  246.  
  247. // A mostly blue palette with white accents.
  248. // "CRGB::Gray" is used as white to keep the brightness more uniform.
  249. const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM =
  250. {  CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  251.    CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  252.    CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  253.    CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray };
  254.  
  255. // A pure "fairy light" palette with some brightness variations
  256. #define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2)
  257. #define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4)
  258. const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM =
  259. {  CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight,
  260.    HALFFAIRY,        HALFFAIRY,        CRGB::FairyLight, CRGB::FairyLight,
  261.    QUARTERFAIRY,     QUARTERFAIRY,     CRGB::FairyLight, CRGB::FairyLight,
  262.    CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight };
  263.  
  264. // A palette of soft snowflakes with the occasional bright one
  265. const TProgmemRGBPalette16 Snow_p FL_PROGMEM =
  266. {  0x304048, 0x304048, 0x304048, 0x304048,
  267.    0x304048, 0x304048, 0x304048, 0x304048,
  268.    0x304048, 0x304048, 0x304048, 0x304048,
  269.    0x304048, 0x304048, 0x304048, 0xE0F0FF };
  270.  
  271. // A palette reminiscent of large 'old-school' C9-size tree lights
  272. // in the five classic colors: red, orange, green, blue, and white.
  273. #define C9_Red    0xB80400
  274. #define C9_Orange 0x902C02
  275. #define C9_Green  0x046002
  276. #define C9_Blue   0x070758
  277. #define C9_White  0x606820
  278. const TProgmemRGBPalette16 RetroC9_p FL_PROGMEM =
  279. {  C9_Red,    C9_Orange, C9_Red,    C9_Orange,
  280.    C9_Orange, C9_Red,    C9_Orange, C9_Red,
  281.    C9_Green,  C9_Green,  C9_Green,  C9_Green,
  282.    C9_Blue,   C9_Blue,   C9_Blue,
  283.    C9_White
  284. };
  285.  
  286. // A cold, icy pale blue palette
  287. #define Ice_Blue1 0x0C1040
  288. #define Ice_Blue2 0x182080
  289. #define Ice_Blue3 0x5080C0
  290. const TProgmemRGBPalette16 Ice_p FL_PROGMEM =
  291. {
  292.   Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
  293.   Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
  294.   Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1,
  295.   Ice_Blue2, Ice_Blue2, Ice_Blue2, Ice_Blue3
  296. };
  297.  
  298.  
  299. // Add or remove palette names from this list to control which color
  300. // palettes are used, and in what order.
  301. const TProgmemRGBPalette16* ActivePaletteList[] = {
  302.   &RetroC9_p,
  303.   &BlueWhite_p,
  304.   &RainbowColors_p,
  305.   &FairyLight_p,
  306.   &RedGreenWhite_p,
  307.   &PartyColors_p,
  308.   &RedWhite_p,
  309.   &Snow_p,
  310.   &Holly_p,
  311.   &Ice_p  
  312. };
  313.  
  314.  
  315. // Advance to the next color palette in the list (above).
  316. void chooseNextColorPalette( CRGBPalette16& pal)
  317. {
  318.   const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]);
  319.   static uint8_t whichPalette = -1;
  320.   whichPalette = addmod8( whichPalette, 1, numberOfPalettes);
  321.  
  322.   pal = *(ActivePaletteList[whichPalette]);
  323. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement