Advertisement
pchestna

Arduino Controlled Tree - http://youtu.be/MD3-YBaFQvw

May 10th, 2014
9,872
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.67 KB | None | 0 0
  1. #include<FastLED.h>
  2.  
  3. #define NUM_MODES 12
  4. #define LIGHT_TEST 0
  5.  
  6. #define MAX_BRIGHT 150
  7.  
  8. byte state = 1;
  9. int index = 0;               //-LED INDEX (0 to LED_COUNT-1)
  10.  
  11. byte thisbright = 128;
  12. byte thissat = 255;
  13. int thisdelay = 20;          
  14. byte thisstep = 10;          
  15. byte thishue = 0;
  16.  
  17. byte demoMode = 0;
  18. #define DEMO_COUNT 1600;
  19. int demoStateCountdown;
  20. byte interrupt = 0;
  21.  
  22. // How many leds are in the strip?
  23. // Be careful with the num leds. The animations that make use of the levels
  24. // will walk right off the led array. The numbers are specific to my led
  25. // tree. If you are using less leds or are not interested in the layer animations
  26. // you should remove them from the loop or set USE_LEVEL_ANIMATIONS to 0
  27. //#define NUM_LEDS 30 // LED Strip
  28. //#define LED_TYPE    WS2812B // LED Strip
  29. //#define COLOR_ORDER GRB // LED Strip
  30. #define NUM_LEDS 348 // Tree
  31. #define LED_TYPE    WS2811 // Tree
  32. #define COLOR_ORDER RGB // Tree
  33.  
  34. byte USE_LEVEL_ANIMATIONS = 1; // if 1, will auto advance past level animations
  35. #define NUM_LEVELS 12
  36. const PROGMEM prog_uint16_t levels[NUM_LEVELS] = {58, 108, 149, 187, 224, 264, 292, 309, 321, 327, 336, 348};
  37.  
  38. // Data pin that led data will be written out over
  39. #define DATA_PIN 3
  40. // This is an array of leds.  One item for each led in your strip.
  41. CRGB leds[NUM_LEDS];
  42.  
  43. /////////////////////////////////////////////////////////////////////////
  44. // Setup for danger shield
  45. //
  46. // I used the Danger Shield to play with animation speed, brightness and for initial
  47. // debug. I used it to lock the animation on one type, showed the animation
  48. // number in the LED, etc. I wrote the code to use it or not.
  49. /////////////////////////////////////////////////////////////////////////
  50.  
  51. byte useDSCtrl = 0; // Set to 1 if you want to play with the Danger Shield
  52.  
  53. // Shift register bit values to display 0-9 on the seven-segment display
  54. const PROGMEM prog_uchar ledCharSet[20] = {
  55.   B00111111,B00000110,B01011011,B01001111,B01100110,B01101101,B01111101,B00000111,B01111111,B01101111,
  56.   B10111111,B10000110,B11011011,B11001111,B11100110,B11101101,B11111101,B10000111,B11111111,B11101111
  57. };
  58.  
  59. // Pin definitions
  60. #define SLIDER1  0
  61. #define SLIDER2  1
  62. #define SLIDER3  2
  63.  
  64. #define DATA 4
  65. #define LED1  5
  66. #define LED2  6
  67. #define LATCH 7
  68. #define CLOCK 8
  69. #define BUTTON1  10
  70. #define BUTTON2  11
  71. #define BUTTON3  12
  72.  
  73. /////////////////////////////////////////////////////////////////////////
  74. // End setup for danger shield
  75. /////////////////////////////////////////////////////////////////////////
  76.  
  77. void setup()
  78. {
  79.   // sanity check delay - allows reprogramming if accidently blowing power w/leds
  80.   delay(2000);
  81.  
  82.   initDSCtrls();
  83.  
  84.   FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  85.   FastLED.setBrightness(MAX_BRIGHT);
  86.   one_color_all(0,0,0);
  87.   FastLED.show();
  88.   delay(1000);
  89.   countdown();
  90.   setDemoMode();
  91. }
  92.  
  93. static void initDSCtrls()
  94. {
  95.   if (!useDSCtrl) return;
  96.  
  97.   // Init LED 1
  98.   pinMode(LED1, OUTPUT);
  99.   blinkLED1();
  100.  
  101.   // Init LED 2
  102.   pinMode(LED2, OUTPUT);
  103.   digitalWrite(LED2,LOW);
  104.  
  105.   // Init Digit Display
  106.   pinMode(LATCH, OUTPUT);
  107.   pinMode(CLOCK, OUTPUT);
  108.   pinMode(DATA,OUTPUT);
  109.  
  110.   // Init buttons
  111.   pinMode(BUTTON1,INPUT);
  112.   pinMode(BUTTON2,INPUT);
  113.   pinMode(BUTTON3,INPUT);
  114.  
  115.   digitalWrite(BUTTON1,HIGH);
  116.   digitalWrite(BUTTON2,HIGH);
  117.   digitalWrite(BUTTON3,HIGH);
  118. }
  119.  
  120. void blinkLED1()
  121. {
  122.   if (!useDSCtrl) return;
  123.  
  124.   digitalWrite(LED1, LOW);
  125.   delay(50);
  126.   for (int idx = 0; idx < 3; idx++)
  127.   {
  128.     digitalWrite(LED1, HIGH);
  129.     delay(50);
  130.     digitalWrite(LED1, LOW);
  131.     delay(50);
  132.   }
  133. }
  134.  
  135. void countdown()
  136. {
  137.   if (!useDSCtrl) return;
  138.  
  139.   for (int index=3; index >= 0; index--)
  140.   {
  141.     state = index;
  142.     updateState();
  143.     delay(1000);
  144.   }
  145.   state = 1;
  146.   updateState();
  147. }
  148.  
  149. void one_color_all(int cred, int cgrn, int cblu)
  150. {       //-SET ALL LEDS TO ONE COLOR
  151.     for(int i = 0 ; i < NUM_LEDS; i++ ) {
  152.       leds[i].setRGB( cred, cgrn, cblu).nscale8_video(thisbright);
  153.     }
  154. }
  155.  
  156. void colorTest()
  157. {
  158.   one_color_all(0,0,0);
  159.   FastLED.show();
  160.   delay(1000);
  161.   one_color_all(255,0,0);
  162.   FastLED.show();
  163.   delay(1000);
  164.   one_color_all(0,0,0);
  165.   FastLED.show();
  166.   delay(1000);
  167.   one_color_all(0,255,0);
  168.   FastLED.show();
  169.   delay(1000);
  170.   one_color_all(0,0,0);
  171.   FastLED.show();
  172.   delay(1000);
  173.   one_color_all(0,0,255);
  174.   FastLED.show();
  175.   delay(1000);
  176. }  
  177.  
  178. void dotTest()
  179. {
  180.    // Move a single white led
  181.    for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
  182.       // Turn our current led on to white, then show the leds
  183.       leds[whiteLed] = CRGB::White;
  184.       // Show the leds (only one of which is set to white, from above)
  185.       FastLED.show();
  186.       // Wait a little bit
  187.       delay(10);
  188.       // Turn our current led back to black for the next loop around
  189.       leds[whiteLed] = CRGB::Black;
  190.    }
  191. }
  192.  
  193. void lightTest()
  194. {
  195.   colorTest();
  196.   dotTest();
  197. }
  198.  
  199. void random_burst()
  200. {
  201.   int rndidx = random16(0, NUM_LEDS);
  202.   int rndhue = random8(0, 255);  
  203.   int rndbright = random8(10, thisbright);
  204.   leds[rndidx] = CHSV(rndhue, thissat, rndbright);
  205.   delay(random8(0, thisdelay));
  206. }
  207.  
  208. void rgb_propeller()
  209. {
  210.   thishue = 0;
  211.   index++;
  212.   int ghue = (thishue + 80) % 255;
  213.   int bhue = (thishue + 160) % 255;
  214.   int N3  = int(NUM_LEDS/3);
  215.   int N6  = int(NUM_LEDS/6);  
  216.   int N12 = int(NUM_LEDS/12);  
  217.   for(int i = 0; i < N3; i++ ) {
  218.     int j0 = (index + i + NUM_LEDS - N12) % NUM_LEDS;
  219.     int j1 = (j0+N3) % NUM_LEDS;
  220.     int j2 = (j1+N3) % NUM_LEDS;    
  221.     leds[j0] = CHSV(thishue, thissat, thisbright);
  222.     leds[j1] = CHSV(ghue, thissat, thisbright);
  223.     leds[j2] = CHSV(bhue, thissat, thisbright);    
  224.   }
  225. }
  226.  
  227. void candycane()
  228. {
  229.   index++;
  230.   int N3  = int(NUM_LEDS/3);
  231.   int N6  = int(NUM_LEDS/6);  
  232.   int N12 = int(NUM_LEDS/12);  
  233.   for(int i = 0; i < N6; i++ ) {
  234.     int j0 = (index + i + NUM_LEDS - N12) % NUM_LEDS;
  235.     int j1 = (j0+N6) % NUM_LEDS;
  236.     int j2 = (j1+N6) % NUM_LEDS;
  237.     int j3 = (j2+N6) % NUM_LEDS;
  238.     int j4 = (j3+N6) % NUM_LEDS;
  239.     int j5 = (j4+N6) % NUM_LEDS;
  240.     leds[j0] = CRGB(255, 255, 255).nscale8_video(thisbright*.75);
  241.     leds[j1] = CRGB(255, 0, 0).nscale8_video(thisbright);
  242.     leds[j2] = CRGB(255, 255, 255).nscale8_video(thisbright*.75);
  243.     leds[j3] = CRGB(255, 0, 0).nscale8_video(thisbright);
  244.     leds[j4] = CRGB(255, 255, 255).nscale8_video(thisbright*.75);
  245.     leds[j5] = CRGB(255, 0, 0).nscale8_video(thisbright);
  246.   }
  247. }
  248.  
  249. void rainbow_loop()
  250. {
  251.   index++;
  252.   thishue = thishue + thisstep;
  253.   if (index >= NUM_LEDS) {index = 0;}
  254.   if (thishue > 255) {thishue = 0;}
  255.   leds[index] = CHSV(thishue, thissat, thisbright);
  256. }
  257.  
  258. void fill_rainbow_ctrl( struct CRGB * pFirstLED, int numToFill,
  259.                   uint8_t initialhue,
  260.                   uint8_t deltahue,
  261.           uint8_t saturation,
  262.           uint8_t brightness)
  263. {
  264.     CHSV hsv;
  265.     hsv.hue = initialhue;
  266.     hsv.sat = saturation;
  267.     hsv.val = brightness;
  268.     for( int i = 0; i < numToFill; i++) {
  269.         hsv2rgb_rainbow( hsv, pFirstLED[i]);
  270.         hsv.hue += deltahue;
  271.     }
  272. }
  273.  
  274. void rainbow()
  275. {
  276.   fill_rainbow_ctrl( leds, NUM_LEDS, thishue, thisstep, thissat, thisbright);
  277.   thishue++;
  278. }
  279.  
  280. void clear_all()
  281. {
  282.   one_color_all(0, 0, 0);
  283.   LEDS.show();
  284.   delay(50);
  285. }
  286.  
  287. void clear_level(int level)
  288. {
  289.   int startPxl;
  290.   if (level == 0)
  291.     startPxl = 0;
  292.   else
  293.     startPxl = pgm_read_word(&(levels[level-1]));
  294.  
  295.   for(int i = startPxl; i < pgm_read_word(&(levels[level])); i++)
  296.   {
  297.     leds[i] = CRGB::Black;
  298.   }
  299. }
  300.  
  301. void light_level_random(int level, byte clearall = 1)
  302. {
  303.   if (clearall)
  304.     clear_all();
  305.  
  306.   int startPxl;
  307.   if (level == 0)
  308.     startPxl = 0;
  309.   else
  310.     startPxl = pgm_read_word(&(levels[level-1]));
  311.    
  312.   for(int i = startPxl; i < pgm_read_word(&(levels[level])); i++)
  313.   {
  314.     leds[i] = CHSV(random8(), random8(50, thissat), random8(50, thisbright));
  315.   }
  316. }
  317.  
  318. void quick_random_fill()
  319. {
  320.   for (int i = 0; i < NUM_LEDS; i++)
  321.   {
  322.     leds[i] = CHSV(random8(), random8(), random8(10, thisbright));
  323.   }
  324. }
  325.  
  326. void light_level(int level, byte red, byte green, byte blue, byte clearall = 1)
  327. {
  328.   if (clearall)
  329.     clear_all();
  330.  
  331.   int startPxl;
  332.   if (level == 0)
  333.     startPxl = 0;
  334.   else
  335.     startPxl = pgm_read_word(&(levels[level-1]));
  336.  
  337.   for(int i = startPxl; i < pgm_read_word(&(levels[level])); i++)
  338.   {
  339.     leds[i].setRGB(red, green, blue).nscale8_video(thisbright);
  340.   }
  341. }
  342.  
  343. void drain()
  344. {
  345.   for (int pancakeLevel = 0; pancakeLevel < NUM_LEVELS; pancakeLevel++)
  346.   {
  347.     updateControlVars();    
  348.     if (interrupt) return;
  349.     for (int level = pancakeLevel; level >= 0; level--)
  350.     {
  351.       updateControlVars();    
  352.       if (interrupt) return;
  353.       clear_level(level);
  354.       if (level >= 1) light_level_random(level-1, 0);
  355.            
  356.       LEDS.show();
  357.       delay(75);
  358.     }
  359.   }
  360. }
  361.  
  362. void pancake()
  363. {
  364.   for (int pancakeLevel = 0; pancakeLevel < NUM_LEVELS; pancakeLevel++)
  365.   {
  366.     updateControlVars();    
  367.     if (interrupt) return;
  368.     for (int level = NUM_LEVELS-1; level >= pancakeLevel; level--)
  369.     {
  370.       updateControlVars();    
  371.       if (interrupt) return;
  372.       if (level < NUM_LEVELS-1) clear_level(level+1);
  373.       light_level_random(level, 0);
  374.            
  375.       LEDS.show();
  376.       delay(75);
  377.     }
  378.   }
  379. }
  380.  
  381. void alternate_levels()
  382. {
  383.   static int level = 0;
  384.   light_level(level, dim8_video(random8()), dim8_video(random8()), dim8_video(random8()));
  385.   level++;
  386.   if (level == NUM_LEVELS) level = 0;
  387. }
  388.  
  389. void random_levels()
  390. {
  391.   int level = random(NUM_LEVELS);
  392.   if (NUM_LEVELS == level) level = 0;
  393.   light_level_random(level, 1);
  394. }
  395.  
  396. void rainbow_fade()
  397. {
  398.     thishue++;
  399.     if (thishue > 255) {thishue = 0;}
  400.     for(int idex = 0 ; idex < NUM_LEDS; idex++ ) {
  401.       leds[idex] = CHSV(thishue, thissat, thisbright);
  402.     }
  403. }
  404.  
  405. void twinkle( CRGB* L ) {
  406.   static byte huebase = 0;
  407.  
  408.   //slowly rotate huebase
  409.   if( random8(4) == 0) huebase--;
  410.  
  411.   for( int whichPixel = 0; whichPixel < NUM_LEDS; whichPixel++) {  
  412.     int hue = random8(32) + huebase;
  413.     int saturation = 255;    // richest color
  414.     int brightness = dim8_video( dim8_video( dim8_video( random8())));
  415.    
  416.     L[whichPixel] = CHSV( hue, saturation, brightness);
  417.   }
  418. }
  419.  
  420. void matrix()
  421. {
  422.   int rand = random8(0, 100);
  423.   if (rand > 90) {
  424.     leds[0] = CHSV(random8(), thissat, thisbright);
  425.   }
  426.   else {
  427.     leds[0] = CHSV(0, thissat, 0);
  428.   }
  429.  
  430.   for(int i = NUM_LEDS-1; i > 0; i--)
  431.   {
  432.     leds[i] = leds[i-1];
  433.   }
  434. }
  435.  
  436. void correct_color_balance()
  437. {
  438.   for( int i = 0; i < NUM_LEDS; i++) {
  439.     leds[i].g = scale8_video( leds[i].g, 192);
  440.   }
  441. }
  442.  
  443.  
  444. CHSV sv_ramp( uint8_t hue, uint8_t ramp) {
  445.   uint8_t brightness;
  446.   uint8_t saturation;
  447.   if( ramp < 128) {
  448.     // fade toward black
  449.     brightness = ramp * 2;
  450.     brightness = dim8_video( brightness);
  451. //    uint8_t global_brightness = FastLED.getBrightness();
  452. //    uint8_t min_step = 256 / global_brightness;
  453. //    brightness = qadd8( min_step * 16, brightness);
  454.     saturation = 255;
  455.   } else {
  456.     // desaturate toward white
  457.     brightness = 255;
  458.     saturation = 255 - ((ramp - 128) * 2);
  459.     saturation = 255 - dim8_video( 255 - saturation);
  460.   }
  461.   return CHSV( hue, saturation, brightness); }
  462.  
  463. void loop5( CRGB* L )
  464. {
  465.   uint8_t GB = FastLED.getBrightness();
  466.   uint8_t boost = 0;
  467. //  if( GB < 65) boost += 8;
  468. //  if( GB < 33) boost += 8;
  469.  
  470.   uint8_t N = 2;
  471.  
  472.   static uint16_t starttheta = 0;
  473.   starttheta += 100 / N;
  474.  
  475.   static uint16_t starthue16 = 0;
  476.   starthue16 += 20 / N;
  477.  
  478.  
  479.   uint16_t hue16 = starthue16;
  480.   uint16_t theta = starttheta;
  481.   for( int i = 0; i < NUM_LEDS; i++) {
  482.     uint8_t frac = (sin16( theta) + 32768) / 256;
  483.     frac = scale8(frac,160) + 32;
  484.     theta += 3700;
  485.  
  486.     hue16 += 2000;
  487.     uint8_t hue = hue16 / 256;
  488.     L[i] = sv_ramp( hue, frac + boost);
  489.   }
  490. }
  491.  
  492. //---FIND ADJACENT INDEX CLOCKWISE
  493. int adjacent_cw(int i) {
  494.   int r;
  495.   if (i < NUM_LEDS - 1) {r = i + 1;}
  496.   else {r = 0;}
  497.   return r;
  498. }
  499.  
  500. //---FIND ADJACENT INDEX COUNTER-CLOCKWISE
  501. int adjacent_ccw(int i) {
  502.   int r;
  503.   if (i > 0) {r = i - 1;}
  504.   else {r = NUM_LEDS - 1;}
  505.   return r;
  506. }
  507.  
  508. void random_march()
  509. {
  510.   int iCCW;
  511.   for(int idex = 0; idex < NUM_LEDS; idex++ ) {
  512.     iCCW = adjacent_ccw(idex);
  513.     leds[idex] = leds[idex+1];
  514.   }
  515.   leds[NUM_LEDS-1] = CHSV(random8(), thissat, thisbright);
  516. }
  517.  
  518. void updateState()
  519. {
  520.   if (!useDSCtrl) return;
  521.  
  522.   if (interrupt)
  523.   {
  524.     interrupt = 0;
  525.   }
  526.  
  527.   // Numeric display
  528.   digitalWrite(LATCH,LOW);
  529.   shiftOut(DATA,CLOCK,MSBFIRST,~(pgm_read_word(&(ledCharSet[state]))));
  530.   digitalWrite(LATCH,HIGH);
  531.   // Reset LED1
  532.   digitalWrite(LED1, LOW);
  533. }
  534.  
  535. void incrementState()
  536. {
  537.   state++;
  538.   if(state > NUM_MODES){
  539.     state = 1;
  540.   }
  541. }
  542.  
  543. void readForStateChange()
  544. {
  545.   if (!useDSCtrl) return;
  546.  
  547.   if(!(digitalRead(BUTTON1))) // Change state
  548.   {
  549.     delay(1); // Debounce
  550.     incrementState();
  551.     interrupt = 1;
  552.     while(!(digitalRead(BUTTON1)));
  553.   }
  554. }
  555.  
  556. void readForInterrupt()
  557. {
  558.   if(!(digitalRead(BUTTON2))) // Change state
  559.   {
  560.     delay(1); // Debounce
  561.     interrupt = 1;
  562.     demoMode = 0;
  563.     digitalWrite(LED1,HIGH);
  564.     digitalWrite(LED2,LOW);
  565.   }
  566. }
  567.  
  568. void setDemoMode()
  569. {
  570.     demoMode = 1;
  571.     demoStateCountdown = DEMO_COUNT;
  572.     digitalWrite(LED2,HIGH);
  573. }
  574.  
  575. void readForDemo()
  576. {
  577.   if(!(digitalRead(BUTTON3))) // Change state
  578.   {
  579.     delay(1); // Debounce
  580.     setDemoMode();
  581.   }
  582. }
  583.  
  584. void updateControlVars()
  585. {
  586.   if (useDSCtrl)
  587.   {
  588.     int s1Val = analogRead(SLIDER1);
  589.     int s2Val = analogRead(SLIDER2);
  590.     int s3Val = analogRead(SLIDER3);
  591.    
  592.     thissat = (s2Val/4 < 50) ? 50 : s2Val/4;
  593.     thisdelay = s3Val*2;
  594.     thisbright = (s1Val/4 < 20) ? 20 : s1Val/4;
  595.  
  596.     readForStateChange();
  597.     readForInterrupt();
  598.     readForDemo();
  599.   }
  600.   else
  601.   {
  602.   }
  603. }
  604.  
  605. byte alt = 0;
  606. void loop() {
  607.   if (LIGHT_TEST)
  608.   {
  609.     lightTest();
  610.     return;
  611.   }
  612.  
  613.   demoStateCountdown = (demoStateCountdown < 0) ? 0 : demoStateCountdown;
  614.  
  615.   if (useDSCtrl)
  616.   {
  617.     if (alt < 10) {  
  618.       digitalWrite(LED1, HIGH);
  619.       alt++;
  620.     } else {
  621.       digitalWrite(LED1, LOW);
  622.       alt++;
  623.       if (alt == 20) alt=0;
  624.     }
  625.   }
  626.  
  627.   if (demoMode)
  628.   {
  629.     demoStateCountdown--;
  630.     if (demoStateCountdown <= 0)
  631.     {
  632.       blinkLED1();
  633.       incrementState();
  634.       demoStateCountdown = DEMO_COUNT;
  635.     }
  636.   }
  637.  
  638.   updateControlVars();
  639.   int adjdelay = thisdelay;
  640.   updateState();
  641.  
  642.   switch (state)
  643.   {
  644.     case 1:
  645.       random_burst();
  646.     break;
  647.     case 2:
  648.       rgb_propeller();
  649.     break;
  650.     case 3:
  651.       rainbow();
  652.     break;
  653.     case 4:
  654.       rainbow_fade();
  655.       if ((demoMode) && !(demoStateCountdown%5)) demoStateCountdown-=2;
  656.       adjdelay = (adjdelay < 30) ? 30 : adjdelay;
  657.     break;
  658.     case 5:
  659.       rainbow_loop();
  660.     break;
  661.     case 6:
  662.       if ((demoMode) && !(demoStateCountdown%5)) demoStateCountdown-=2;
  663.       adjdelay = (adjdelay < 50) ? 50 : adjdelay;
  664.       matrix();
  665.     break;
  666.     case 7:
  667.       demoStateCountdown -= 2;
  668.       adjdelay = (adjdelay < 120) ? 120 : adjdelay;
  669.       random_march();
  670.     break;
  671.     case 8:
  672.       loop5(leds);
  673.       adjdelay = adjdelay/3;
  674.     break;
  675.     case 9:
  676.       twinkle(leds);
  677.     break;
  678.     case 10:
  679.       candycane();
  680.     break;
  681.     case 11:
  682.       if (!USE_LEVEL_ANIMATIONS) incrementState();
  683.       adjdelay = (adjdelay < 100) ? 100 : adjdelay;
  684.       demoStateCountdown -= 15;
  685.       random_levels();
  686.     break;
  687.     case 12:
  688.       if (!USE_LEVEL_ANIMATIONS) incrementState();
  689.       rainbow();
  690.       adjdelay = (adjdelay < 50) ? 50 : adjdelay;
  691.       if (demoMode) demoStateCountdown -= 600;
  692.       drain();
  693.       pancake();
  694.     break;
  695.     default:
  696.       random_burst();
  697.     break;
  698.   }
  699.   FastLED.show();  
  700.   delay(adjdelay);
  701. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement