terrag42

Halloween Pumpkin Face

Oct 14th, 2016
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.12 KB | None | 0 0
  1. //***************************************************************
  2. //  halloween_pumpkin_vg
  3. //
  4. //  Setup to work with a 9 pixel LED strip or string
  5. //    Eyes are pixels 5,6,7,8 and the mouth are pixels 0,1,2,3,4
  6. // Garrett Durland, Oct 2016
  7. // Modified from the program by Marc Miller, Oct 2016
  8. //***************************************************************
  9. #include "FastLED.h"
  10.  
  11. #define LED_TYPE WS2812B
  12. #define DATA_PIN 7
  13. #define NUM_LEDS 9
  14. #define COLOR_ORDER GRB  // GRB for Neopixel
  15. #define BRIGHTNESS 254
  16.  
  17. //CRGB leds[NUM_LEDS];  // Not using this.  Using CRGBArray instead.
  18. CRGBArray<NUM_LEDS> leds;
  19. CRGBSet eyeL(leds(6,7));  // Define custom group for left eye
  20. CRGBSet eyeR(leds(8,9));  // Define custom group for right eye
  21. CRGBSet mouth(leds(1,5));  // Define custom group for mouth
  22.  
  23. #define FRAMES_PER_SECOND  100
  24.  
  25.  
  26.  
  27. boolean firstRun = true;  // used to run a startup check only once.
  28. uint8_t gHue = 0;  // Rotating "base color" used by many of the patterns.
  29. uint8_t gCurrentPatternNumber = 0;  // Index number of which pattern is current.
  30.  
  31. // ****SET HOW LONG EACH PATTERN RUNS FOR HERE****
  32. uint8_t cycleTime = 30;  // Number of seconds before next pattern.
  33.  
  34. //-----------------rainbow variables-----------------
  35. uint8_t rainbowSpeed;  // (used with rainbow)
  36. uint8_t breakup = 4 ;  // (used with rainbow)
  37. int8_t heading = random8(0,2);  // (used with rainbow for direction)
  38.  
  39. //------------------breath variables-----------------
  40. static float pulseSpeed = 0.8;  // Larger value gives faster pulse.   0.9
  41. uint8_t hueA = random8(185);  // Start hue at valueMin.
  42. uint8_t satA = 190;  // Start saturation at valueMin.
  43. float valueMin = 90.0;  // Pulse minimum value (Should be less then valueMax).
  44. uint8_t hueB = hueA+27;  // End hue at valueMax.
  45. uint8_t satB = 240;  // End saturation at valueMax.
  46. float valueMax = 254.0;  // Pulse maximum value (Should be larger then valueMin).
  47. uint8_t hueBreath = hueA;  // Do Not Edit
  48. uint8_t satBreath = satA;  // Do Not Edit
  49. float val = valueMin;  // Do Not Edit
  50. uint8_t hueDelta = hueA - hueB;  // Do Not Edit
  51. static float deltaBreath = (valueMax - valueMin) / 2.35040238;  // Do Not Edit
  52.  
  53. //----------------breathFire variables---------------
  54. static float pulseSpeedF = 0.3;  // Larger value gives faster pulse.   0.9
  55. uint8_t hueAF = 46;  // Start hue at valueMin.
  56. uint8_t satAF = 240;  // Start saturation at valueMin.
  57. float valueMinF = 110.0;  // Pulse minimum value (Should be less then valueMax).
  58. uint8_t hueBF = 22;  // End hue at valueMax.
  59. uint8_t satBF = 255;  // End saturation at valueMax.
  60. float valueMaxF = 254.0;  // Pulse maximum value (Should be larger then valueMin).
  61. uint8_t hueBreathF = hueAF;  // Do Not Edit
  62. uint8_t satBreathF = satAF;  // Do Not Edit
  63. float valF = valueMinF;  // Do Not Edit
  64. uint8_t hueDeltaF = hueAF - hueBF;  // Do Not Edit
  65. static float deltaBreathF = (valueMaxF - valueMinF) / 2.35040238;  // Do Not Edit
  66.  
  67.  
  68. //------------------TwinkleFOX variables-----------------
  69. #define TWINKLE_SPEED 6  // Overall speed.  0=slow to 8=fast, default is 5.
  70. #define TWINKLE_DENSITY 4  // Overall twinkle density.  0=none lit to 8=all lit, default is 5.
  71. CRGB gBackgroundColor = CRGB(3,0,6);  // Background color for 'unlit' pixels.  (Can also be CRGB::Black)
  72. #define SECONDS_PER_PALETTE  23  // How often to change color palettes.
  73. CRGBPalette16 gCurrentPalette;
  74. CRGBPalette16 gTargetPalette;
  75.  
  76.  
  77.  
  78.  
  79. //===============================================================
  80. void setup() {
  81.   Serial.begin(115200);  // Allows serial monitor output (check baud rate)
  82.   delay(3000);  // 3 second startup delay
  83.   FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  84.   FastLED.setBrightness(BRIGHTNESS);
  85.   if (heading == 0) { heading = -1; }
  86. }
  87.  
  88.  
  89. //----------***********PATTERNS*****-----------------------------------------------------
  90. // List of ***********PATTERNS***** to cycle through.  Each is defined as a separate function below.
  91. typedef void (*SimplePatternList[])();
  92. SimplePatternList gPatterns = {
  93.   faceTest,  //0 USED ONLY FOR TESTING
  94.   rainbow, //1
  95.   breath, //2, ,
  96.   breathFire,//3
  97.   twinkleFOX, twinkleFOX //4, 5
  98. };
  99.  
  100.  
  101. //===============================================================
  102. void loop()
  103. {
  104.   random16_add_entropy( random());  // Add entropy to random number generator.
  105.  
  106.   // Do a bunch of periodic updates below.
  107.   // Also, set cycleTime super short just for the startup.
  108.  
  109.   if (firstRun == true) {  // This bit will only run one time at startup.
  110.     Serial.print("gCurrentPatternNumber = "); Serial.println(gCurrentPatternNumber);
  111.     nextPattern();
  112.     gPatterns[gCurrentPatternNumber](); // Call the current pattern function once, updating the 'leds' array
  113.     FastLED.show();
  114.     firstRun = false;
  115.     Serial.println("firstRun done."); Serial.println(" ");
  116.   } else {
  117.     EVERY_N_SECONDS( cycleTime ) { nextPattern(); }  // Change patterns periodically.  [*SET TIME UP ABOVE*]
  118.   }
  119.  
  120.   EVERY_N_MILLISECONDS( 20 ) {  // Slowly cycle the "base color" through the rainbow
  121.     gHue++;
  122.     if (gHue == 200) { gHue+50; }  // Skip past pinkish hue
  123.   }
  124.  
  125.   EVERY_N_SECONDS( 20 ) {  // (used with rainbow)
  126.     uint8_t percentage = random8(101);
  127.     if (percentage > 15) { rainbowSpeed = 40; }
  128.     if (percentage > 70) { rainbowSpeed = 120; }
  129.     else { rainbowSpeed = 4; }
  130.     percentage = random8(101);
  131.     if (percentage > 10) { breakup = 4; }
  132.     if (percentage > 60) { breakup = 8; }
  133.     else { breakup = 1; }
  134.     heading = random8(0,2);
  135.     if (heading == 0) { heading = -1; }
  136.   }
  137.  
  138.   EVERY_N_SECONDS( 40 ) {  // (used with breath)
  139.     hueA = random8(185);  // Start hue @ valueMin.
  140.     if (hueA > 128 && hueA < 150) {  // Avoid aqua colors
  141.       hueA = hueA + random(25,128);
  142.     }
  143.     hueB = hueA+27;  // End hue at valueMax.
  144.   }
  145.  
  146.   EVERY_N_SECONDS( SECONDS_PER_PALETTE ) {  // (used with twinkleFOX)
  147.     chooseNextColorPalette( gTargetPalette );
  148.   }
  149.   EVERY_N_MILLISECONDS( 10 ) {  // (used with twinkleFOX)
  150.     nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12);
  151.   }
  152.   gPatterns[gCurrentPatternNumber](); // Call the current pattern function once, updating the 'leds' array
  153.  
  154.  // preShow();  // Run before displaying pixels
  155.   //FastLED.show();  // Display the pixels.
  156.   FastLED.delay(1000/FRAMES_PER_SECOND);  // Insert a delay to keep the framerate modest.
  157.  
  158. } //end main loop
  159.  
  160.  
  161. //---------------------------------------------------------------
  162. #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
  163. void nextPattern()  // Select next pattern number.
  164. {
  165.  //gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);  // Just cycle through patterns
  166.   gCurrentPatternNumber = random8( ARRAY_SIZE(gPatterns) );  // Randomly pick a new pattern
  167.   ////gCurrentPatternNumber = 0;  // Use to lock to a specific pattern [FOR TSETING ONLY]
  168.   Serial.print("gCurrentPatternNumber = "); Serial.print(gCurrentPatternNumber);
  169.   Serial.print("        cycleTime = "); Serial.println(cycleTime);
  170. }
  171.  
  172.  
  173. //===============================================================
  174. // The different patterns to choose from...
  175. //===============================================================
  176. //---------------------------------------------------------------
  177. void rainbow()
  178. {
  179.   FastLED.setBrightness(BRIGHTNESS-30);
  180.   // FastLED's built-in rainbow generator
  181.   fill_rainbow( leds, NUM_LEDS, gHue+rainbowSpeed, (breakup*heading) );
  182.   // match eye color and shift the hue from the mouth
  183.   leds[2] = leds[10] = CHSV(gHue+rainbowSpeed-50, 255, 255);
  184.   leds[1] = leds[11] = CHSV(gHue+rainbowSpeed-50, 235, 225);
  185. }
  186.  
  187. //---------------------------------------------------------------
  188. void breath()
  189. {
  190.   EVERY_N_MILLISECONDS(40){
  191.     FastLED.setBrightness(BRIGHTNESS);
  192.     float dV = ((exp(sin(pulseSpeed * millis()/2000.0*PI)) -0.36787944) * deltaBreath);
  193.     val = valueMin + dV;
  194.     hueBreath = map(val, valueMin, valueMax, hueA, hueB);  // Map hue based on current val
  195.     satBreath = map(val, valueMin, valueMax, satA, satB);  // Map sat based on current val
  196.     for (int i = 0; i < NUM_LEDS; i++) {
  197.       leds[i] = CHSV(hueBreath, satBreath, val);
  198.     }
  199.    
  200.     for (uint8_t i=0; i<5; i++){
  201.       leds[i].fadeToBlackBy(210);  // darken down the mouth
  202.     }
  203.  //   preShow();  // Run before displaying pixels
  204.     //FastLED.show();
  205.     //delay(40);
  206.   }
  207. }
  208.  
  209. //---------------------------------------------------------------
  210. void breathFire()  // Has a fixed glowy fire hue.
  211. {
  212.   EVERY_N_MILLISECONDS(40){
  213.     FastLED.setBrightness(BRIGHTNESS);
  214.     float dVF = ((exp(sin(pulseSpeed * millis()/2000.0*PI)) -0.36787944) * deltaBreathF);
  215.     valF = valueMinF + dVF;
  216.     hueBreathF = map(valF, valueMinF, valueMaxF, hueAF, hueBF);  // Map hue based on current val
  217.     satBreathF = map(valF, valueMinF, valueMaxF, satAF, satBF);  // Map sat based on current val
  218.  
  219.     for (uint8_t i = 0; i < NUM_LEDS; i++) {
  220.       if (i >=0 && i <= 4) {
  221.         leds[i] = CHSV(hueBreathF+47, satBreathF-11, valF);  // make mouth less red
  222.       } else {
  223.         leds[i] = CHSV(hueBreathF, satBreathF, valF);
  224.       }
  225.     }
  226.     for (uint8_t i = 0; i < 5; i++){
  227.       leds[i].fadeToBlackBy(120);  // darken down the mouth
  228.     }
  229. //    preShow();  // Run before displaying pixels
  230.   }
  231. }
  232.  
  233. //---------------------------------------------------------------
  234. void twinkleFOX()
  235. {
  236.   FastLED.setBrightness(BRIGHTNESS);
  237.   drawTwinkles( leds, NUM_LEDS);
  238.   leds[5] = leds[8];  // make right eye pixels match left
  239.   leds[6] = leds[7];  // make right eye pixels match left
  240. }
  241.  
  242. void drawTwinkles( CRGB* L, uint16_t N)  // (part of twinkleFOX)
  243. {
  244.   // "PRNG16" is the pseudorandom number generator
  245.   // It MUST be reset to the same starting value each time
  246.   // this function is called, so that the sequence of 'random'
  247.   // numbers that it generates is (paradoxically) stable.
  248.   uint16_t PRNG16 = 11337;
  249.  
  250.   uint32_t clock32 = millis();
  251.  
  252.   uint8_t backgroundBrightness = gBackgroundColor.getAverageLight();
  253.  
  254.   for( uint16_t i = 0; i < N; i++) {
  255.     PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
  256.     uint16_t myclockoffset16= PRNG16; // use that number as clock offset
  257.     PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
  258.     // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths)
  259.     uint8_t myspeedmultiplierQ5_3 =  ((((PRNG16 & 0xFF)>>4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08;
  260.     uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
  261.     uint8_t  myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel
  262.  
  263.     // We now have the adjusted 'clock' for this pixel, now we call
  264.     // the function that computes what color the pixel should be based
  265.     // on the "brightness = f( time )" idea.
  266.     CRGB c = computeOneTwinkle( myclock30, myunique8);
  267.  
  268.     // If the new pixel is brighter than the background color, use it.
  269.     if( c.getAverageLight() > backgroundBrightness) {
  270.       L[i] = c;
  271.     } else {
  272.       L[i] = gBackgroundColor;
  273.     }
  274.   }
  275. }
  276.  
  277. CRGB computeOneTwinkle( uint32_t ms, uint8_t salt)  // (part of twinkleFOX)
  278. {
  279.   uint16_t ticks = ms >> (8-TWINKLE_SPEED);
  280.   uint8_t fastcycle8 = ticks;
  281.   uint8_t slowcycle8 = (ticks >> 8) ^ salt;
  282.  
  283.   uint8_t bright = 0;
  284.   if( ((slowcycle8 & 0x0E)/2) < TWINKLE_DENSITY) {
  285.     bright = triwave8( fastcycle8);
  286.   }
  287.  
  288.   uint8_t hue = (slowcycle8 * 16) + salt;
  289.   return ColorFromPalette( gCurrentPalette, hue, bright, NOBLEND);
  290. }
  291.  
  292.  
  293. // ----Palette definitions for twinkleFOX----
  294. // A mostly red palette with green accents.
  295. // "CRGB::Gray" is used instead of white to keep the brightness more uniform.
  296. const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM =
  297. {  CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  298.    CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
  299.    CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
  300.    CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green };
  301.  
  302. // A red and white striped palette
  303. // "CRGB::Gray" is used instead of white.
  304. const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM =
  305. {  CRGB::Red,  CRGB::Red,  CRGB::Red,  CRGB::Red,
  306.    CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray,
  307.    CRGB::Red,  CRGB::Red,  CRGB::Red,  CRGB::Red,
  308.    CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray };
  309.  
  310. // A mostly blue palette with white accents.
  311. // "CRGB::Gray" is used instead of white.
  312. const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM =
  313. {  CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  314.    CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  315.    CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue,
  316.    CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray };
  317.  
  318. // A pure "fairy light" palette with some brightness variations
  319. #define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2)
  320. #define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4)
  321. const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM =
  322. {  CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight,
  323.    HALFFAIRY,        HALFFAIRY,        CRGB::FairyLight, CRGB::FairyLight,
  324.    QUARTERFAIRY,     QUARTERFAIRY,     CRGB::FairyLight, CRGB::FairyLight,
  325.    CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight };
  326.  
  327. // A palette of soft snowflakes with the occasional bright one
  328. const TProgmemRGBPalette16 Snow_p FL_PROGMEM =
  329. {  0x404040, 0x404040, 0x404040, 0x404040,
  330.    0x404040, 0x404040, 0x404040, 0x404040,
  331.    0x404040, 0x404040, 0x404040, 0x404040,
  332.    0x404040, 0x404040, 0x404040, 0xFFFFFF };
  333.  
  334.  
  335. // ----Palettes to be used when running twinkleFOX----
  336. // Add or remove or comment out palette names from this list to control
  337. // which color palettes are used, and in what order.
  338. const TProgmemRGBPalette16* ActivePaletteList[] = {
  339.   &RedGreenWhite_p,
  340.   &BlueWhite_p,
  341.   &PartyColors_p,
  342.   &RainbowColors_p,
  343.   &FairyLight_p,
  344.   &RedWhite_p,
  345.   &PartyColors_p,
  346.   &Snow_p
  347. };
  348.  
  349.  
  350. // Advance to the next color palette in the list (above).
  351. void chooseNextColorPalette( CRGBPalette16& pal)
  352. {
  353.   const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]);
  354.   static uint8_t whichPalette = -1;
  355.   whichPalette = addmod8( whichPalette, 1, numberOfPalettes);
  356.   pal = *(ActivePaletteList[whichPalette]);
  357. }
  358.  
  359.  
  360. //---------------------------------------------------------------
  361. void faceTest()  //ONLY USED FOR TESTING
  362. {
  363.   EVERY_N_MILLISECONDS(80){ leds[5] = leds[6] = CRGB::Black;  // left eye off
  364.   }
  365.   EVERY_N_MILLISECONDS(160){ leds[5] = leds[6] = CRGB::Green;  // left eye on
  366.   }
  367.   EVERY_N_MILLISECONDS(60){     leds[7] = leds[8] = CRGB::Black;  // right eye off
  368.   }
  369.   EVERY_N_MILLISECONDS(120){     leds[7] = leds[8] = CRGB::Red;  // right eye on
  370.   }
  371.   EVERY_N_MILLISECONDS(30){leds[0] = leds[1] = leds[2] = leds[3] = leds[4] = CRGB::Black;  // mouth
  372.   }
  373.   EVERY_N_MILLISECONDS(60){leds[0] = leds[1] = leds[2] = leds[3] = leds[4] = CRGB::Blue;  // mouth
  374.   }
  375. }
  376.  
  377. //---------------------------------------------------------------
  378. /* Adjust some pixels before showing.
  379. void preShow()
  380. {
  381.   // Turn off the gap pixels between the eyes and mouth zones
  382.   leds[0] = leds[3] = leds[9] = CRGB::Black;
  383.  
  384.   leds[1].fadeToBlackBy(195);  // fade the top of right eye a bit
  385.   leds[11].fadeToBlackBy(195);  // fade the top of left eye a bit
  386. }
  387.  
  388. */
  389. //---------------------------------------------------------------
  390. //EOF
Advertisement
Add Comment
Please, Sign In to add comment