Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //***************************************************************
- // halloween_pumpkin_vg
- //
- // Setup to work with a 9 pixel LED strip or string
- // Eyes are pixels 5,6,7,8 and the mouth are pixels 0,1,2,3,4
- // Garrett Durland, Oct 2016
- // Modified from the program by Marc Miller, Oct 2016
- //***************************************************************
- #include "FastLED.h"
- #define LED_TYPE WS2812B
- #define DATA_PIN 7
- #define NUM_LEDS 9
- #define COLOR_ORDER GRB // GRB for Neopixel
- #define BRIGHTNESS 254
- //CRGB leds[NUM_LEDS]; // Not using this. Using CRGBArray instead.
- CRGBArray<NUM_LEDS> leds;
- CRGBSet eyeL(leds(6,7)); // Define custom group for left eye
- CRGBSet eyeR(leds(8,9)); // Define custom group for right eye
- CRGBSet mouth(leds(1,5)); // Define custom group for mouth
- #define FRAMES_PER_SECOND 100
- boolean firstRun = true; // used to run a startup check only once.
- uint8_t gHue = 0; // Rotating "base color" used by many of the patterns.
- uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current.
- // ****SET HOW LONG EACH PATTERN RUNS FOR HERE****
- uint8_t cycleTime = 30; // Number of seconds before next pattern.
- //-----------------rainbow variables-----------------
- uint8_t rainbowSpeed; // (used with rainbow)
- uint8_t breakup = 4 ; // (used with rainbow)
- int8_t heading = random8(0,2); // (used with rainbow for direction)
- //------------------breath variables-----------------
- static float pulseSpeed = 0.8; // Larger value gives faster pulse. 0.9
- uint8_t hueA = random8(185); // Start hue at valueMin.
- uint8_t satA = 190; // Start saturation at valueMin.
- float valueMin = 90.0; // Pulse minimum value (Should be less then valueMax).
- uint8_t hueB = hueA+27; // End hue at valueMax.
- uint8_t satB = 240; // End saturation at valueMax.
- float valueMax = 254.0; // Pulse maximum value (Should be larger then valueMin).
- uint8_t hueBreath = hueA; // Do Not Edit
- uint8_t satBreath = satA; // Do Not Edit
- float val = valueMin; // Do Not Edit
- uint8_t hueDelta = hueA - hueB; // Do Not Edit
- static float deltaBreath = (valueMax - valueMin) / 2.35040238; // Do Not Edit
- //----------------breathFire variables---------------
- static float pulseSpeedF = 0.3; // Larger value gives faster pulse. 0.9
- uint8_t hueAF = 46; // Start hue at valueMin.
- uint8_t satAF = 240; // Start saturation at valueMin.
- float valueMinF = 110.0; // Pulse minimum value (Should be less then valueMax).
- uint8_t hueBF = 22; // End hue at valueMax.
- uint8_t satBF = 255; // End saturation at valueMax.
- float valueMaxF = 254.0; // Pulse maximum value (Should be larger then valueMin).
- uint8_t hueBreathF = hueAF; // Do Not Edit
- uint8_t satBreathF = satAF; // Do Not Edit
- float valF = valueMinF; // Do Not Edit
- uint8_t hueDeltaF = hueAF - hueBF; // Do Not Edit
- static float deltaBreathF = (valueMaxF - valueMinF) / 2.35040238; // Do Not Edit
- //------------------TwinkleFOX variables-----------------
- #define TWINKLE_SPEED 6 // Overall speed. 0=slow to 8=fast, default is 5.
- #define TWINKLE_DENSITY 4 // Overall twinkle density. 0=none lit to 8=all lit, default is 5.
- CRGB gBackgroundColor = CRGB(3,0,6); // Background color for 'unlit' pixels. (Can also be CRGB::Black)
- #define SECONDS_PER_PALETTE 23 // How often to change color palettes.
- CRGBPalette16 gCurrentPalette;
- CRGBPalette16 gTargetPalette;
- //===============================================================
- void setup() {
- Serial.begin(115200); // Allows serial monitor output (check baud rate)
- delay(3000); // 3 second startup delay
- FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
- FastLED.setBrightness(BRIGHTNESS);
- if (heading == 0) { heading = -1; }
- }
- //----------***********PATTERNS*****-----------------------------------------------------
- // List of ***********PATTERNS***** to cycle through. Each is defined as a separate function below.
- typedef void (*SimplePatternList[])();
- SimplePatternList gPatterns = {
- faceTest, //0 USED ONLY FOR TESTING
- rainbow, //1
- breath, //2, ,
- breathFire,//3
- twinkleFOX, twinkleFOX //4, 5
- };
- //===============================================================
- void loop()
- {
- random16_add_entropy( random()); // Add entropy to random number generator.
- // Do a bunch of periodic updates below.
- // Also, set cycleTime super short just for the startup.
- if (firstRun == true) { // This bit will only run one time at startup.
- Serial.print("gCurrentPatternNumber = "); Serial.println(gCurrentPatternNumber);
- nextPattern();
- gPatterns[gCurrentPatternNumber](); // Call the current pattern function once, updating the 'leds' array
- FastLED.show();
- firstRun = false;
- Serial.println("firstRun done."); Serial.println(" ");
- } else {
- EVERY_N_SECONDS( cycleTime ) { nextPattern(); } // Change patterns periodically. [*SET TIME UP ABOVE*]
- }
- EVERY_N_MILLISECONDS( 20 ) { // Slowly cycle the "base color" through the rainbow
- gHue++;
- if (gHue == 200) { gHue+50; } // Skip past pinkish hue
- }
- EVERY_N_SECONDS( 20 ) { // (used with rainbow)
- uint8_t percentage = random8(101);
- if (percentage > 15) { rainbowSpeed = 40; }
- if (percentage > 70) { rainbowSpeed = 120; }
- else { rainbowSpeed = 4; }
- percentage = random8(101);
- if (percentage > 10) { breakup = 4; }
- if (percentage > 60) { breakup = 8; }
- else { breakup = 1; }
- heading = random8(0,2);
- if (heading == 0) { heading = -1; }
- }
- EVERY_N_SECONDS( 40 ) { // (used with breath)
- hueA = random8(185); // Start hue @ valueMin.
- if (hueA > 128 && hueA < 150) { // Avoid aqua colors
- hueA = hueA + random(25,128);
- }
- hueB = hueA+27; // End hue at valueMax.
- }
- EVERY_N_SECONDS( SECONDS_PER_PALETTE ) { // (used with twinkleFOX)
- chooseNextColorPalette( gTargetPalette );
- }
- EVERY_N_MILLISECONDS( 10 ) { // (used with twinkleFOX)
- nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12);
- }
- gPatterns[gCurrentPatternNumber](); // Call the current pattern function once, updating the 'leds' array
- // preShow(); // Run before displaying pixels
- //FastLED.show(); // Display the pixels.
- FastLED.delay(1000/FRAMES_PER_SECOND); // Insert a delay to keep the framerate modest.
- } //end main loop
- //---------------------------------------------------------------
- #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
- void nextPattern() // Select next pattern number.
- {
- //gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); // Just cycle through patterns
- gCurrentPatternNumber = random8( ARRAY_SIZE(gPatterns) ); // Randomly pick a new pattern
- ////gCurrentPatternNumber = 0; // Use to lock to a specific pattern [FOR TSETING ONLY]
- Serial.print("gCurrentPatternNumber = "); Serial.print(gCurrentPatternNumber);
- Serial.print(" cycleTime = "); Serial.println(cycleTime);
- }
- //===============================================================
- // The different patterns to choose from...
- //===============================================================
- //---------------------------------------------------------------
- void rainbow()
- {
- FastLED.setBrightness(BRIGHTNESS-30);
- // FastLED's built-in rainbow generator
- fill_rainbow( leds, NUM_LEDS, gHue+rainbowSpeed, (breakup*heading) );
- // match eye color and shift the hue from the mouth
- leds[2] = leds[10] = CHSV(gHue+rainbowSpeed-50, 255, 255);
- leds[1] = leds[11] = CHSV(gHue+rainbowSpeed-50, 235, 225);
- }
- //---------------------------------------------------------------
- void breath()
- {
- EVERY_N_MILLISECONDS(40){
- FastLED.setBrightness(BRIGHTNESS);
- float dV = ((exp(sin(pulseSpeed * millis()/2000.0*PI)) -0.36787944) * deltaBreath);
- val = valueMin + dV;
- hueBreath = map(val, valueMin, valueMax, hueA, hueB); // Map hue based on current val
- satBreath = map(val, valueMin, valueMax, satA, satB); // Map sat based on current val
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV(hueBreath, satBreath, val);
- }
- for (uint8_t i=0; i<5; i++){
- leds[i].fadeToBlackBy(210); // darken down the mouth
- }
- // preShow(); // Run before displaying pixels
- //FastLED.show();
- //delay(40);
- }
- }
- //---------------------------------------------------------------
- void breathFire() // Has a fixed glowy fire hue.
- {
- EVERY_N_MILLISECONDS(40){
- FastLED.setBrightness(BRIGHTNESS);
- float dVF = ((exp(sin(pulseSpeed * millis()/2000.0*PI)) -0.36787944) * deltaBreathF);
- valF = valueMinF + dVF;
- hueBreathF = map(valF, valueMinF, valueMaxF, hueAF, hueBF); // Map hue based on current val
- satBreathF = map(valF, valueMinF, valueMaxF, satAF, satBF); // Map sat based on current val
- for (uint8_t i = 0; i < NUM_LEDS; i++) {
- if (i >=0 && i <= 4) {
- leds[i] = CHSV(hueBreathF+47, satBreathF-11, valF); // make mouth less red
- } else {
- leds[i] = CHSV(hueBreathF, satBreathF, valF);
- }
- }
- for (uint8_t i = 0; i < 5; i++){
- leds[i].fadeToBlackBy(120); // darken down the mouth
- }
- // preShow(); // Run before displaying pixels
- }
- }
- //---------------------------------------------------------------
- void twinkleFOX()
- {
- FastLED.setBrightness(BRIGHTNESS);
- drawTwinkles( leds, NUM_LEDS);
- leds[5] = leds[8]; // make right eye pixels match left
- leds[6] = leds[7]; // make right eye pixels match left
- }
- void drawTwinkles( CRGB* L, uint16_t N) // (part of twinkleFOX)
- {
- // "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();
- uint8_t backgroundBrightness = gBackgroundColor.getAverageLight();
- for( uint16_t i = 0; i < N; i++) {
- 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);
- // If the new pixel is brighter than the background color, use it.
- if( c.getAverageLight() > backgroundBrightness) {
- L[i] = c;
- } else {
- L[i] = gBackgroundColor;
- }
- }
- }
- CRGB computeOneTwinkle( uint32_t ms, uint8_t salt) // (part of twinkleFOX)
- {
- uint16_t ticks = ms >> (8-TWINKLE_SPEED);
- uint8_t fastcycle8 = ticks;
- uint8_t slowcycle8 = (ticks >> 8) ^ salt;
- uint8_t bright = 0;
- if( ((slowcycle8 & 0x0E)/2) < TWINKLE_DENSITY) {
- bright = triwave8( fastcycle8);
- }
- uint8_t hue = (slowcycle8 * 16) + salt;
- return ColorFromPalette( gCurrentPalette, hue, bright, NOBLEND);
- }
- // ----Palette definitions for twinkleFOX----
- // A mostly red palette with green accents.
- // "CRGB::Gray" is used instead of 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 red and white striped palette
- // "CRGB::Gray" is used instead of white.
- 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 instead of white.
- 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 =
- { 0x404040, 0x404040, 0x404040, 0x404040,
- 0x404040, 0x404040, 0x404040, 0x404040,
- 0x404040, 0x404040, 0x404040, 0x404040,
- 0x404040, 0x404040, 0x404040, 0xFFFFFF };
- // ----Palettes to be used when running twinkleFOX----
- // Add or remove or comment out palette names from this list to control
- // which color palettes are used, and in what order.
- const TProgmemRGBPalette16* ActivePaletteList[] = {
- &RedGreenWhite_p,
- &BlueWhite_p,
- &PartyColors_p,
- &RainbowColors_p,
- &FairyLight_p,
- &RedWhite_p,
- &PartyColors_p,
- &Snow_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]);
- }
- //---------------------------------------------------------------
- void faceTest() //ONLY USED FOR TESTING
- {
- EVERY_N_MILLISECONDS(80){ leds[5] = leds[6] = CRGB::Black; // left eye off
- }
- EVERY_N_MILLISECONDS(160){ leds[5] = leds[6] = CRGB::Green; // left eye on
- }
- EVERY_N_MILLISECONDS(60){ leds[7] = leds[8] = CRGB::Black; // right eye off
- }
- EVERY_N_MILLISECONDS(120){ leds[7] = leds[8] = CRGB::Red; // right eye on
- }
- EVERY_N_MILLISECONDS(30){leds[0] = leds[1] = leds[2] = leds[3] = leds[4] = CRGB::Black; // mouth
- }
- EVERY_N_MILLISECONDS(60){leds[0] = leds[1] = leds[2] = leds[3] = leds[4] = CRGB::Blue; // mouth
- }
- }
- //---------------------------------------------------------------
- /* Adjust some pixels before showing.
- void preShow()
- {
- // Turn off the gap pixels between the eyes and mouth zones
- leds[0] = leds[3] = leds[9] = CRGB::Black;
- leds[1].fadeToBlackBy(195); // fade the top of right eye a bit
- leds[11].fadeToBlackBy(195); // fade the top of left eye a bit
- }
- */
- //---------------------------------------------------------------
- //EOF
Advertisement
Add Comment
Please, Sign In to add comment