Advertisement
pchestna

L3D Cube Twinkle Demo

Dec 26th, 2014
613
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.34 KB | None | 0 0
  1. // Credit Mark Kriegsman, by permission
  2. // Disclaimer: this code is intended to be exploratory, not exemplary
  3. #include "FastLED.h"
  4.  
  5. #define LED_PIN     2
  6. #define LED_TYPE    WS2811
  7. #define COLOR_ORDER GRB
  8. #define NUM_LEDS    512
  9. CRGB leds[NUM_LEDS];
  10.  
  11. //  Twinkling lights that fade up and down in brightness.
  12. //  Colors are chosen from a palette; a few palettes are provided.
  13. //
  14. //  The basic operation is that all pixels stay black until they
  15. //  are 'seeded' with a relatively dim color.  The dim colors
  16. //  are repeatedly brightened until they reach full brightness, then
  17. //  are darkened repeatedly until they are fully black again.
  18. //
  19. //  A set of 'directionFlags' is used to track whether a given
  20. //  pixel is presently brightening up or darkening down.
  21. //
  22. //  For illustration purposes, two implementations of directionFlags
  23. //  are provided: a simple one-byte-per-pixel flag, and a more
  24. //  complicated, more compact one-BIT-per-pixel flag.
  25. //
  26. //  Darkening colors accurately is relatively easy: scale down the
  27. //  existing color channel values.  Brightening colors is a bit more
  28. //  error prone, as there's some loss of precision.  If your colors
  29. //  aren't coming our 'right' at full brightness, try increasing the
  30. //  STARTING_BRIGHTNESS value.
  31. //
  32. //  -Mark Kriegsman, December 2014
  33.  
  34. #define MASTER_BRIGHTNESS   255
  35.  
  36. #define STARTING_BRIGHTNESS 64
  37. #define FADE_IN_SPEED       32
  38. #define FADE_OUT_SPEED      20
  39. #define DENSITY            255
  40.  
  41. void setup() {
  42.   delay(3000);
  43.   FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  44.   FastLED.setBrightness(MASTER_BRIGHTNESS);
  45. }
  46.  
  47. void loop()
  48. {
  49.   chooseColorPalette();
  50.   colortwinkles();
  51.   FastLED.show();  
  52.   FastLED.delay(1);
  53. }
  54.  
  55.  
  56. CRGBPalette16 gPalette;
  57.  
  58. void chooseColorPalette()
  59. {
  60.   uint8_t numberOfPalettes = 9;
  61.   uint8_t secondsPerPalette = 10;
  62.   uint8_t whichPalette = (millis()/(1000*secondsPerPalette)) % numberOfPalettes;
  63.  
  64.   CRGB r(CRGB::Red), b(CRGB::Blue), w(85,85,85), g(CRGB::Green), W(CRGB::White), l(CRGB::FairyLight);
  65.  
  66.   switch( whichPalette) {  
  67.     case 0: // Red, Green, and White
  68.       gPalette = CRGBPalette16( r,r,r,r, r,r,r,r, g,g,g,g, w,w,w,w );
  69.       break;
  70.     case 1: // Blue and White
  71.       //gPalette = CRGBPalette16( b,b,b,b, b,b,b,b, w,w,w,w, w,w,w,w );
  72.       gPalette = CloudColors_p; // Blues and whites!
  73.       break;
  74.     case 2: // Rainbow of colors
  75.       gPalette = RainbowColors_p;
  76.       break;
  77.     case 3: // Incandescent "fairy lights"
  78.       gPalette = CRGBPalette16( l,l,l,l, l,l,l,l, l,l,l,l, l,l,l,l );
  79.       break;
  80.     case 4: // Snow
  81.       gPalette = CRGBPalette16( W,W,W,W, w,w,w,w, w,w,w,w, w,w,w,w );
  82.       break;
  83.     case 5:
  84.       gPalette = LavaColors_p;
  85.       break;
  86.     case 6:
  87.       gPalette = ForestColors_p;
  88.       break;
  89.     case 7:
  90.       gPalette = PartyColors_p;
  91.       break;
  92.     case 8:
  93.       uint8_t h = random8();
  94.       gPalette = CHSVPalette16( CHSV(h,255,255), CHSV(h+32, 255,255));
  95.       break;
  96.   }
  97. }
  98.  
  99. enum { GETTING_DARKER = 0, GETTING_BRIGHTER = 1 };
  100.  
  101. void colortwinkles()
  102. {
  103.   // Make each pixel brighter or darker, depending on
  104.   // its 'direction' flag.
  105.   brightenOrDarkenEachPixel( FADE_IN_SPEED, FADE_OUT_SPEED);
  106.  
  107.   // Now consider adding a new random twinkle
  108.   if( random8() < DENSITY ) {
  109.     int pos = random16(NUM_LEDS);
  110.     if( leds[pos] ) pos = random16(NUM_LEDS);
  111.     if( !leds[pos]) {
  112.       leds[pos] = ColorFromPalette( gPalette, random8(), STARTING_BRIGHTNESS, NOBLEND);
  113.       setPixelDirection(pos, GETTING_BRIGHTER);
  114.     }
  115.   }
  116. }
  117.  
  118. void brightenOrDarkenEachPixel( fract8 fadeUpAmount, fract8 fadeDownAmount)
  119. {
  120. for( uint16_t i = 0; i < NUM_LEDS; i++) {
  121.     if( getPixelDirection(i) == GETTING_DARKER) {
  122.       // This pixel is getting darker
  123.       leds[i] = makeDarker( leds[i], fadeDownAmount);
  124.     } else {
  125.       // This pixel is getting brighter
  126.       leds[i] = makeBrighter( leds[i], fadeUpAmount);
  127.       // now check to see if we've maxxed out the brightness
  128.       if( leds[i].r == 255 || leds[i].g == 255 || leds[i].b == 255) {
  129.         // if so, turn around and start getting darker
  130.         setPixelDirection(i, GETTING_DARKER);
  131.       }
  132.     }
  133.   }
  134. }
  135.  
  136. CRGB makeBrighter( const CRGB& color, fract8 howMuchBrighter)
  137. {
  138.   CRGB incrementalColor = color;
  139.   incrementalColor.nscale8( howMuchBrighter);
  140.  return color + incrementalColor;
  141. }
  142.  
  143. CRGB makeDarker( const CRGB& color, fract8 howMuchDarker)
  144. {
  145.   CRGB newcolor = color;
  146.   newcolor.nscale8( 255 - howMuchDarker);
  147.   return newcolor;
  148. }
  149.  
  150.  
  151. // For illustration purposes, there are two separate implementations
  152. // provided here for the array of 'directionFlags':
  153. // - a simple one, which uses one byte (8 bits) of RAM for each pixel, and
  154. // - a compact one, which uses just one BIT of RAM for each pixel.
  155.  
  156. // Set this to 1 or 8 to select which implementation
  157. // of directionFlags is used.  1=more compact, 8=simpler.
  158. #define BITS_PER_DIRECTION_FLAG 1
  159.  
  160.  
  161. #if BITS_PER_DIRECTION_FLAG == 8
  162. // Simple implementation of the directionFlags array,
  163. // which takes up one byte (eight bits) per pixel.
  164. uint8_t directionFlags[NUM_LEDS];
  165.  
  166. bool getPixelDirection( uint16_t i) {
  167.   return directionFlags[i];
  168. }
  169.  
  170. void setPixelDirection( uint16_t i, bool dir) {
  171.   directionFlags[i] = dir;
  172. }
  173. #endif
  174.  
  175.  
  176. #if BITS_PER_DIRECTION_FLAG == 1
  177. // Compact (but more complicated) implementation of
  178. // the directionFlags array, using just one BIT of RAM
  179. // per pixel.  This requires a bunch of bit wrangling,
  180. // but conserves precious RAM.  The cost is a few
  181. // cycles and about 100 bytes of flash program memory.
  182. uint8_t  directionFlags[ (NUM_LEDS+7) / 8];
  183.  
  184. bool getPixelDirection( uint16_t i) {
  185.   uint16_t index = i / 8;
  186.   uint8_t  bitNum = i & 0x07;
  187.   // using Arduino 'bitRead' function; expanded code below
  188.   return bitRead( directionFlags[index], bitNum);
  189.   // uint8_t  andMask = 1 << bitNum;
  190.   // return (directionFlags[index] & andMask) != 0;
  191. }
  192.  
  193. void setPixelDirection( uint16_t i, bool dir) {
  194.   uint16_t index = i / 8;
  195.   uint8_t  bitNum = i & 0x07;
  196.   // using Arduino 'bitWrite' function; expanded code below
  197.   bitWrite( directionFlags[index], bitNum, dir);
  198.   //  uint8_t  orMask = 1 << bitNum;
  199.   //  uint8_t andMask = 255 - orMask;
  200.   //  uint8_t value = directionFlags[index] & andMask;
  201.   //  if( dir ) {
  202.   //    value += orMask;
  203.   //  }
  204.   //  directionFlags[index] = value;
  205. }
  206. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement