Advertisement
GyroGearloose

Jasons_torch_serpentine_layout_20x14

Mar 10th, 2016
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.75 KB | None | 0 0
  1. /* This code compiles but  shows only the first 15 Leds on a 20x14 serpentine layout matrix
  2.  *
  3.  * Torch: https://github.com/evilgeniuslabs/torch
  4.  * pics: https://photos.google.com/share/AF1QipNUex4j2A516Mqrjh4RlNw9PGTjkKa4rIiYrl1mBebG9VDGVJ9vix-6qdbLEVUKwg?key=ZjdUZl9Za0dtTUp6eC03MHhqd3EycUpzV1RSS19R
  5.  * Copyright (C) 2015 Jason Coon
  6.  *
  7.  * use Teensy
  8.  * This program is free software: you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation, either version 3 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20.  
  21.  pinout:     now
  22.  LED DATA     0    SPI 11
  23.  LED Clock         SPI 13
  24.  IR receive  12
  25.  STROBE_PIN   2
  26.  RESET_PIN    3
  27.  MSGEQ7_LEFT_PIN   A0
  28.  RIGHT_PIN         A1
  29.  
  30. check remote control
  31. my LED matrix = 20 x 14 (3 pixels higher)
  32.  
  33.  */
  34.  
  35. #include <FastLED.h>
  36. #include <IRremote.h>
  37. #include <EEPROM.h>
  38.  
  39. #if FASTLED_VERSION < 3001000
  40. #error "Requires FastLED 3.1 or later; check github for latest code."
  41. #endif
  42.  
  43. #define LED_PIN     11  //0
  44. #define CLK_PIN     13
  45. #define IR_RECV_PIN 12
  46. //#define COLOR_ORDER GRB
  47. //#define CHIPSET     WS2812B
  48. #define COLOR_ORDER BGR
  49. #define CHIPSET     APA102
  50.  
  51. //#define NUM_LEDS    282 //240 // was two pixel too many
  52.  
  53. const uint8_t MATRIX_WIDTH =  14; //14;
  54. const uint8_t MATRIX_HEIGHT = 20; //17;
  55. const bool    kMatrixSerpentineLayout = true;
  56.  
  57. const int MATRIX_CENTER_X = MATRIX_WIDTH / 2;
  58. const int MATRIX_CENTER_Y = MATRIX_HEIGHT / 2;
  59.  
  60. const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1;
  61. const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1;
  62.  
  63.  
  64. uint16_t XY( uint8_t x, uint8_t y)
  65. {
  66.   uint16_t i;
  67.  
  68.   if( kMatrixSerpentineLayout == false) {
  69.     i = (y * MATRIX_WIDTH) + x;
  70.   }
  71.  
  72.   if( kMatrixSerpentineLayout == true) {
  73.     if( y & 0x01) {
  74.       // Odd rows run backwards
  75.       uint8_t reverseX = (MATRIX_WIDTH - 1) - x;
  76.       i = (y * MATRIX_WIDTH) + reverseX;
  77.     } else {
  78.       // Even rows run forwards
  79.       i = (y * MATRIX_WIDTH) + x;
  80.     }
  81.   }
  82.  
  83.   return i;
  84. }
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93. const uint8_t brightnessCount = 5;
  94. uint8_t brightnessMap[brightnessCount] = { 16, 32, 64, 128, 255 };
  95. uint8_t brightness = brightnessMap[0];
  96.  
  97. #define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
  98. CRGB leds_plus_safety_pixel[NUM_LEDS + 1];
  99. CRGB* const leds( leds_plus_safety_pixel + 1);
  100.  
  101. uint16_t XYsafe( uint8_t x, uint8_t y)
  102. {
  103.   if( x >= MATRIX_WIDTH) return -1;
  104.   if( y >= MATRIX_HEIGHT) return -1;
  105.   return XY(x,y);
  106. }
  107.  
  108.  
  109. IRrecv irReceiver(IR_RECV_PIN);
  110.  
  111. #include "Commands.h"
  112. #include "GradientPalettes.h"
  113.  
  114. CRGB solidColor = CRGB::White;
  115.  
  116. typedef uint16_t(*PatternFunctionPointer)();
  117. typedef PatternFunctionPointer PatternList [];
  118. #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
  119.  
  120. int autoPlayDurationSeconds = 10;
  121. unsigned int autoPlayTimout = 0;
  122. bool autoplayEnabled = true;
  123.  
  124. InputCommand command;
  125.  
  126. int currentPatternIndex = 0;
  127. PatternFunctionPointer currentPattern;
  128.  
  129. CRGB w(85, 85, 85), W(CRGB::White);
  130. CRGBPalette16 snowColors = CRGBPalette16( W, W, W, W, w, w, w, w, w, w, w, w, w, w, w, w );
  131.  
  132. CRGB l(0xE1A024);
  133. CRGBPalette16 incandescentColors = CRGBPalette16( l, l, l, l, l, l, l, l, l, l, l, l, l, l, l, l );
  134.  
  135. const CRGBPalette16 palettes[] = {
  136.   RainbowColors_p,
  137.   RainbowStripeColors_p,
  138.   OceanColors_p,
  139.   CloudColors_p,
  140.   ForestColors_p,
  141.   PartyColors_p,
  142.   HeatColors_p,
  143.   LavaColors_p,
  144.   snowColors,
  145. };
  146.  
  147. const int paletteCount = ARRAY_SIZE(palettes);
  148.  
  149. int currentPaletteIndex = 0;
  150. CRGBPalette16 palette = palettes[0];
  151.  
  152. uint8_t gHue = 0; // rotating "base color" used by many of the patterns
  153.  
  154. #include "Drawing.h"
  155. #include "Effects.h"
  156.  
  157. #include "Noise.h"
  158. #include "Pulse.h"
  159. #include "Wave.h"
  160. #include "Fire2012WithPalette.h"
  161. #include "Torch.h"
  162. #include "AudioLogic.h"
  163. #include "AudioPatterns.h"
  164.  
  165. const PatternList patterns = {
  166.   analyzerColumns,
  167.   analyzerPixels,
  168.   fallingSpectrogram,
  169.   audioNoise,
  170.   fireNoise,
  171.   lavaNoise,
  172.   torch,
  173.   fire2012WithPalette,
  174.   rainbowNoise,
  175.   rainbowStripeNoise,
  176.   partyNoise,
  177.   forestNoise,
  178.   cloudNoise,
  179.   oceanNoise,
  180.   blackAndWhiteNoise,
  181.   blackAndBlueNoise,
  182.   pulse,
  183.   wave,
  184.   pride,
  185.   colorWaves,
  186.   rainbow,
  187.   rainbowWithGlitter,
  188.   confetti,
  189.   bpm,
  190.   juggle,
  191.   sinelon,
  192.   hueCycle,
  193.   rainbowTwinkles,
  194.   snowTwinkles,
  195.   cloudTwinkles,
  196.   incandescentTwinkles,
  197.   fireflies,
  198.   showSolidColor
  199. };
  200.  
  201. const int patternCount = ARRAY_SIZE(patterns);
  202.  
  203. void setup() {
  204.   delay(500); // sanity delay
  205.    Serial.begin(9600);
  206.    Serial.println("setup start");
  207.  
  208.   loadSettings();
  209.  
  210. //  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  211.   FastLED.addLeds<CHIPSET, LED_PIN, CLK_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  212.  
  213.   FastLED.setCorrection(TypicalLEDStrip);
  214.   FastLED.setBrightness(brightness);
  215. //  FastLED.setDither(false);
  216.   FastLED.setDither(brightness < 255);
  217.  
  218.   // Initialize the IR receiver
  219.   irReceiver.enableIRIn();
  220.   irReceiver.blink13(true);
  221.  
  222.   currentPattern = patterns[currentPatternIndex];
  223.  
  224.   autoPlayTimout = millis() + (autoPlayDurationSeconds * 1000);
  225.  
  226.   initializeAudio();
  227.  
  228.   // Serial.println("setup end");
  229. }
  230.  
  231. void loop() {
  232.   // Add entropy to random number generator; we use a lot of it.
  233.   random16_add_entropy(random());
  234.  
  235.   readAudio();
  236.  
  237.   uint16_t requestedDelay = currentPattern();
  238.  
  239.   FastLED.show(); // display this frame
  240. //  Serial.println(currentPatternIndex);
  241.   handleInput(requestedDelay);
  242.  
  243.   if (autoplayEnabled && millis() > autoPlayTimout) {
  244.     move(1);
  245.     autoPlayTimout = millis() + (autoPlayDurationSeconds * 1000);
  246.   }
  247.  
  248.   // do some periodic updates
  249.   EVERY_N_MILLISECONDS(20) {
  250.     gHue++;  // slowly cycle the "base color" through the rainbow
  251.   }
  252. }
  253.  
  254. void loadSettings() {
  255.   // load settings from EEPROM
  256.  
  257.   // brightness
  258.   brightness = EEPROM.read(0);
  259.   if (brightness < 1)
  260.     brightness = 1;
  261.   else if (brightness > 255)
  262.     brightness = 255;
  263.  
  264.   // currentPatternIndex
  265.   currentPatternIndex = EEPROM.read(1);
  266.   if (currentPatternIndex < 0)
  267.     currentPatternIndex = 0;
  268.   else if (currentPatternIndex >= patternCount)
  269.     currentPatternIndex = patternCount - 1;
  270.  
  271.   // solidColor
  272.   solidColor.r = EEPROM.read(2);
  273.   solidColor.g = EEPROM.read(3);
  274.   solidColor.b = EEPROM.read(4);
  275.  
  276.   if (solidColor.r == 0 && solidColor.g == 0 && solidColor.b == 0)
  277.     solidColor = CRGB::White;
  278. }
  279.  
  280. void setSolidColor(CRGB color) {
  281.   solidColor = color;
  282.  
  283.   EEPROM.write(2, solidColor.r);
  284.   EEPROM.write(3, solidColor.g);
  285.   EEPROM.write(4, solidColor.b);
  286.  
  287.   moveTo(patternCount - 1);
  288. }
  289.  
  290. void powerOff()
  291. {
  292.   // clear the display
  293.  
  294.   const uint8_t stepSize = 4;
  295.  
  296.   for (uint8_t i = 0; i < NUM_LEDS / 2 - stepSize; i += stepSize) {
  297.     for (uint8_t j = 0; j < stepSize; j++) {
  298.       leds[i + j] = CRGB::Black;
  299.       leds[(NUM_LEDS - 1) - (i + j)] = CRGB::Black;
  300.     }
  301.  
  302.     FastLED.show(); // display this frame
  303.   }
  304.  
  305.   fill_solid(leds, NUM_LEDS, CRGB::Black);
  306.  
  307.   FastLED.show(); // display this frame
  308.  
  309.   while (true) {
  310.     InputCommand command = readCommand();
  311.     if (command == InputCommand::Power ||
  312.         command == InputCommand::Brightness)
  313.       return;
  314.  
  315.     // go idle for a while, converve power
  316.     delay(250);
  317.   }
  318. }
  319.  
  320. void move(int delta) {
  321.   moveTo(currentPatternIndex + delta);
  322. }
  323.  
  324. void moveTo(int index) {
  325.   currentPatternIndex = index;
  326.  
  327.   if (currentPatternIndex >= patternCount)
  328.     currentPatternIndex = 0;
  329.   else if (currentPatternIndex < 0)
  330.     currentPatternIndex = patternCount - 1;
  331.  
  332.   currentPattern = patterns[currentPatternIndex];
  333.  
  334.   fill_solid(leds, NUM_LEDS, CRGB::Black);
  335.  
  336.   EEPROM.write(1, currentPatternIndex);
  337. }
  338.  
  339. int getBrightnessLevel() {
  340.   int level = 0;
  341.   for (int i = 0; i < brightnessCount; i++) {
  342.     if (brightnessMap[i] >= brightness) {
  343.       level = i;
  344.       break;
  345.     }
  346.   }
  347.   return level;
  348. }
  349.  
  350. uint8_t cycleBrightness() {
  351.   adjustBrightness(1);
  352.  
  353.   if (brightness == brightnessMap[0])
  354.     return 0;
  355.  
  356.   return brightness;
  357. }
  358.  
  359. void adjustBrightness(int delta) {
  360.   int level = getBrightnessLevel();
  361.  
  362.   level += delta;
  363.   if (level < 0)
  364.     level = 0;
  365.   if (level >= brightnessCount)
  366.     level = brightnessCount - 1;
  367.  
  368.   brightness = brightnessMap[level];
  369.   FastLED.setBrightness(brightness);
  370.   FastLED.setDither(brightness < 255);
  371.  
  372.   EEPROM.write(0, brightness);
  373. }
  374.  
  375. void cyclePalette(int delta = 1) {
  376.   if (currentPaletteIndex == 0 && delta < 0)
  377.     currentPaletteIndex = paletteCount - 1;
  378.   else if (currentPaletteIndex >= paletteCount - 1 && delta > 0)
  379.     currentPaletteIndex = 0;
  380.   else
  381.     currentPaletteIndex += delta;
  382.  
  383.   if (currentPaletteIndex >= paletteCount)
  384.     currentPaletteIndex = 0;
  385.  
  386.   palette = palettes[currentPaletteIndex];
  387. }
  388.  
  389. void handleInput(unsigned int requestedDelay) {
  390.   unsigned int requestedDelayTimeout = millis() + requestedDelay;
  391.  
  392.   while (true) {
  393.     command = readCommand(defaultHoldDelay);
  394.  
  395.     if (command != InputCommand::None) {
  396.       // Serial.print("command: ");
  397.       // Serial.println((int) command);
  398.     }
  399.  
  400.     if (command == InputCommand::Up) {
  401.       move(1);
  402.       break;
  403.     }
  404.     else if (command == InputCommand::Down) {
  405.       move(-1);
  406.       break;
  407.     }
  408.     else if (command == InputCommand::Brightness) {
  409.       if (isHolding || cycleBrightness() == 0) {
  410.         heldButtonHasBeenHandled();
  411.         powerOff();
  412.         break;
  413.       }
  414.     }
  415.     else if (command == InputCommand::Power) {
  416.       powerOff();
  417.       break;
  418.     }
  419.     else if (command == InputCommand::BrightnessUp) {
  420.       adjustBrightness(1);
  421.     }
  422.     else if (command == InputCommand::BrightnessDown) {
  423.       adjustBrightness(-1);
  424.     }
  425.     else if (command == InputCommand::PlayMode) { // toggle pause/play
  426.       autoplayEnabled = !autoplayEnabled;
  427.     }
  428.     else if (command == InputCommand::NextPalette) { // cycle color palette
  429.       cyclePalette(1);
  430.     }
  431.     else if (command == InputCommand::PreviousPalette) { // cycle color palette
  432.       cyclePalette(-1);
  433.     }
  434.  
  435.     // pattern buttons
  436.  
  437.     else if (command == InputCommand::Pattern1) {
  438.       moveTo(0);
  439.       break;
  440.     }
  441.     else if (command == InputCommand::Pattern2) {
  442.       moveTo(1);
  443.       break;
  444.     }
  445.     else if (command == InputCommand::Pattern3) {
  446.       moveTo(2);
  447.       break;
  448.     }
  449.     else if (command == InputCommand::Pattern4) {
  450.       moveTo(3);
  451.       break;
  452.     }
  453.     else if (command == InputCommand::Pattern5) {
  454.       moveTo(4);
  455.       break;
  456.     }
  457.     else if (command == InputCommand::Pattern6) {
  458.       moveTo(5);
  459.       break;
  460.     }
  461.     else if (command == InputCommand::Pattern7) {
  462.       moveTo(6);
  463.       break;
  464.     }
  465.     else if (command == InputCommand::Pattern8) {
  466.       moveTo(7);
  467.       break;
  468.     }
  469.     else if (command == InputCommand::Pattern9) {
  470.       moveTo(8);
  471.       break;
  472.     }
  473.     else if (command == InputCommand::Pattern10) {
  474.       moveTo(9);
  475.       break;
  476.     }
  477.     else if (command == InputCommand::Pattern11) {
  478.       moveTo(10);
  479.       break;
  480.     }
  481.     else if (command == InputCommand::Pattern12) {
  482.       moveTo(11);
  483.       break;
  484.     }
  485.  
  486.     // custom color adjustment buttons
  487.  
  488.     else if (command == InputCommand::RedUp) {
  489.       solidColor.red += 1;
  490.       setSolidColor(solidColor);
  491.       break;
  492.     }
  493.     else if (command == InputCommand::RedDown) {
  494.       solidColor.red -= 1;
  495.       setSolidColor(solidColor);
  496.       break;
  497.     }
  498.     else if (command == InputCommand::GreenUp) {
  499.       solidColor.green += 1;
  500.       setSolidColor(solidColor); \
  501.       break;
  502.     }
  503.     else if (command == InputCommand::GreenDown) {
  504.       solidColor.green -= 1;
  505.       setSolidColor(solidColor);
  506.       break;
  507.     }
  508.     else if (command == InputCommand::BlueUp) {
  509.       solidColor.blue += 1;
  510.       setSolidColor(solidColor);
  511.       break;
  512.     }
  513.     else if (command == InputCommand::BlueDown) {
  514.       solidColor.blue -= 1;
  515.       setSolidColor(solidColor);
  516.       break;
  517.     }
  518.  
  519.     // color buttons
  520.  
  521.     else if (command == InputCommand::Red && currentPatternIndex != patternCount - 2 && currentPatternIndex != patternCount - 3) { // Red, Green, and Blue buttons can be used by ColorInvaders game, which is the next to last pattern
  522.       setSolidColor(CRGB::Red);
  523.       break;
  524.     }
  525.     else if (command == InputCommand::RedOrange) {
  526.       setSolidColor(CRGB::OrangeRed);
  527.       break;
  528.     }
  529.     else if (command == InputCommand::Orange) {
  530.       setSolidColor(CRGB::Orange);
  531.       break;
  532.     }
  533.     else if (command == InputCommand::YellowOrange) {
  534.       setSolidColor(CRGB::Goldenrod);
  535.       break;
  536.     }
  537.     else if (command == InputCommand::Yellow) {
  538.       setSolidColor(CRGB::Yellow);
  539.       break;
  540.     }
  541.  
  542.     else if (command == InputCommand::Green && currentPatternIndex != patternCount - 2 && currentPatternIndex != patternCount - 3) { // Red, Green, and Blue buttons can be used by ColorInvaders game, which is the next to last pattern
  543.       setSolidColor(CRGB::Green);
  544.       break;
  545.     }
  546.     else if (command == InputCommand::Lime) {
  547.       setSolidColor(CRGB::Lime);
  548.       break;
  549.     }
  550.     else if (command == InputCommand::Aqua) {
  551.       setSolidColor(CRGB::Aqua);
  552.       break;
  553.     }
  554.     else if (command == InputCommand::Teal) {
  555.       setSolidColor(CRGB::Teal);
  556.       break;
  557.     }
  558.     else if (command == InputCommand::Navy) {
  559.       setSolidColor(CRGB::Navy);
  560.       break;
  561.     }
  562.  
  563.     else if (command == InputCommand::Blue && currentPatternIndex != patternCount - 2 && currentPatternIndex != patternCount - 3) { // Red, Green, and Blue buttons can be used by ColorInvaders game, which is the next to last pattern
  564.       setSolidColor(CRGB::Blue);
  565.       break;
  566.     }
  567.     else if (command == InputCommand::RoyalBlue) {
  568.       setSolidColor(CRGB::RoyalBlue);
  569.       break;
  570.     }
  571.     else if (command == InputCommand::Purple) {
  572.       setSolidColor(CRGB::Purple);
  573.       break;
  574.     }
  575.     else if (command == InputCommand::Indigo) {
  576.       setSolidColor(CRGB::Indigo);
  577.       break;
  578.     }
  579.     else if (command == InputCommand::Magenta) {
  580.       setSolidColor(CRGB::Magenta);
  581.       break;
  582.     }
  583.  
  584.     else if (command == InputCommand::White && currentPatternIndex != patternCount - 2 && currentPatternIndex != patternCount - 3) {
  585.       setSolidColor(CRGB::White);
  586.       break;
  587.     }
  588.     else if (command == InputCommand::Pink) {
  589.       setSolidColor(CRGB::Pink);
  590.       break;
  591.     }
  592.     else if (command == InputCommand::LightPink) {
  593.       setSolidColor(CRGB::LightPink);
  594.       break;
  595.     }
  596.     else if (command == InputCommand::BabyBlue) {
  597.       setSolidColor(CRGB::CornflowerBlue);
  598.       break;
  599.     }
  600.     else if (command == InputCommand::LightBlue) {
  601.       setSolidColor(CRGB::LightBlue);
  602.       break;
  603.     }
  604.  
  605.     if (millis() >= requestedDelayTimeout)
  606.       break;
  607.   }
  608. }
  609. /*
  610. // take out for Marks implementation
  611. uint16_t XY( uint8_t x, uint8_t y) // maps the matrix to the strip
  612. {
  613.   uint16_t i;
  614.   i = (y * MATRIX_WIDTH) + (MATRIX_WIDTH - x);
  615.  
  616.   i = (NUM_LEDS - 1) - i;
  617.  
  618.   if (i > NUM_LEDS)
  619.     i = NUM_LEDS;
  620.  
  621.   return i;
  622. }
  623. */
  624.  
  625. // scale the brightness of the screenbuffer down
  626. void dimAll(byte value)
  627. {
  628.   for (int i = 0; i < NUM_LEDS; i++) {
  629.     leds[i].nscale8(value);
  630.   }
  631. }
  632.  
  633. uint16_t showSolidColor() {
  634.   fill_solid(leds, NUM_LEDS, solidColor);
  635.  
  636.   return 60;
  637. }
  638.  
  639. uint16_t rainbow()
  640. {
  641.   // FastLED's built-in rainbow generator
  642.   fill_rainbow(leds, NUM_LEDS, gHue, 1);
  643.  
  644.   return 8;
  645. }
  646.  
  647. uint16_t rainbowWithGlitter()
  648. {
  649.   // built-in FastLED rainbow, plus some random sparkly glitter
  650.   rainbow();
  651.   addGlitter(80);
  652.   return 8;
  653. }
  654.  
  655. void addGlitter(fract8 chanceOfGlitter)
  656. {
  657.   if (random8() < chanceOfGlitter) {
  658.     leds[random16(NUM_LEDS)] += CRGB::White;
  659.   }
  660. }
  661.  
  662. uint16_t confetti()
  663. {
  664.   // random colored speckles that blink in and fade smoothly
  665.   fadeToBlackBy(leds, NUM_LEDS, 10);
  666.   int pos = random16(NUM_LEDS);
  667.   leds[pos] += ColorFromPalette(palette, gHue + random8(64), 255); // CHSV(gHue + random8(64), 200, 255);
  668.   return 8;
  669. }
  670.  
  671. uint16_t bpm()
  672. {
  673.   // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  674.   uint8_t BeatsPerMinute = 62;
  675.   uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
  676.   for (int i = 0; i < NUM_LEDS; i++) { //9948
  677.     leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
  678.   }
  679.   return 8;
  680. }
  681.  
  682. uint16_t juggle() {
  683.   // N colored dots, weaving in and out of sync with each other
  684.   fadeToBlackBy(leds, NUM_LEDS, 20);
  685.   byte dothue = 0;
  686.   byte dotCount = 3;
  687.   for (int i = 0; i < dotCount; i++) {
  688.     leds[beatsin16(i + dotCount - 1, 0, NUM_LEDS)] |= CHSV(dothue, 200, 255);
  689.     dothue += 256 / dotCount;
  690.   }
  691.   return 0;
  692. }
  693.  
  694. // An animation to play while the crowd goes wild after the big performance
  695. uint16_t applause()
  696. {
  697.   static uint16_t lastPixel = 0;
  698.   fadeToBlackBy(leds, NUM_LEDS, 32);
  699.   leds[lastPixel] = CHSV(random8(HUE_BLUE, HUE_PURPLE), 255, 255);
  700.   lastPixel = random16(NUM_LEDS);
  701.   leds[lastPixel] = CRGB::White;
  702.   return 8;
  703. }
  704.  
  705. // An "animation" to just fade to black.  Useful as the last track
  706. // in a non-looping performance-oriented playlist.
  707. uint16_t fadeToBlack()
  708. {
  709.   fadeToBlackBy(leds, NUM_LEDS, 10);
  710.   return 8;
  711. }
  712.  
  713. uint16_t sinelon()
  714. {
  715.   // a colored dot sweeping back and forth, with fading trails
  716.   fadeToBlackBy( leds, NUM_LEDS, 20);
  717.   uint16_t pos = beatsin16(13, 0, NUM_LEDS);
  718.   static uint16_t prevpos = 0;
  719.   if ( pos < prevpos ) {
  720.     fill_solid( leds + pos, (prevpos - pos) + 1, CHSV(gHue, 220, 255));
  721.   } else {
  722.     fill_solid( leds + prevpos, (pos - prevpos) + 1, CHSV( gHue, 220, 255));
  723.   }
  724.   prevpos = pos;
  725.  
  726.   return 8;
  727. }
  728.  
  729. uint16_t hueCycle() {
  730.   fill_solid(leds, NUM_LEDS, CHSV(gHue, 255, 255));
  731.   return 60;
  732. }
  733.  
  734. // Pride2015 by Mark Kriegsman
  735. // https://gist.github.com/kriegsman/964de772d64c502760e5
  736.  
  737. // This function draws rainbows with an ever-changing,
  738. // widely-varying set of parameters.
  739. uint16_t pride()
  740. {
  741.   static uint16_t sPseudotime = 0;
  742.   static uint16_t sLastMillis = 0;
  743.   static uint16_t sHue16 = 0;
  744.  
  745.   uint8_t sat8 = beatsin88(87, 220, 250);
  746.   uint8_t brightdepth = beatsin88(341, 96, 224);
  747.   uint16_t brightnessthetainc16 = beatsin88(203, (25 * 256), (40 * 256));
  748.   uint8_t msmultiplier = beatsin88(147, 23, 60);
  749.  
  750.   uint16_t hue16 = sHue16;//gHue * 256;
  751.   uint16_t hueinc16 = beatsin88(113, 1, 3000);
  752.  
  753.   uint16_t ms = millis();
  754.   uint16_t deltams = ms - sLastMillis;
  755.   sLastMillis = ms;
  756.   sPseudotime += deltams * msmultiplier;
  757.   sHue16 += deltams * beatsin88(400, 5, 9);
  758.   uint16_t brightnesstheta16 = sPseudotime;
  759.  
  760.   for (int i = 0; i < NUM_LEDS; i++) {
  761.     hue16 += hueinc16;
  762.     uint8_t hue8 = hue16 / 256;
  763.  
  764.     brightnesstheta16 += brightnessthetainc16;
  765.     uint16_t b16 = sin16(brightnesstheta16) + 32768;
  766.  
  767.     uint16_t bri16 = (uint32_t) ((uint32_t) b16 * (uint32_t) b16) / 65536;
  768.     uint8_t bri8 = (uint32_t) (((uint32_t) bri16) * brightdepth) / 65536;
  769.     bri8 += (255 - brightdepth);
  770.  
  771.     CRGB newcolor = CHSV(hue8, sat8, bri8);
  772.  
  773.     uint8_t pixelnumber = i;
  774.     pixelnumber = (NUM_LEDS - 1) - pixelnumber;
  775.  
  776.     nblend(leds[pixelnumber], newcolor, 64);
  777.   }
  778.  
  779.   return 0;
  780. }
  781.  
  782. ///////////////////////////////////////////////////////////////////////
  783.  
  784. // Forward declarations of an array of cpt-city gradient palettes, and
  785. // a count of how many there are.  The actual color palette definitions
  786. // are at the bottom of this file.
  787. extern const TProgmemRGBGradientPalettePtr gGradientPalettes[];
  788. extern const uint8_t gGradientPaletteCount;
  789.  
  790. // Current palette number from the 'playlist' of color palettes
  791. uint8_t gCurrentPaletteNumber = 0;
  792.  
  793. CRGBPalette16 gCurrentPalette( CRGB::Black);
  794. CRGBPalette16 gTargetPalette( gGradientPalettes[0] );
  795.  
  796. // ten seconds per color palette makes a good demo
  797. // 20-120 is better for deployment
  798. #define SECONDS_PER_PALETTE 10
  799.  
  800. uint16_t colorWaves()
  801. {
  802.   EVERY_N_SECONDS( SECONDS_PER_PALETTE ) {
  803.     gCurrentPaletteNumber = addmod8( gCurrentPaletteNumber, 1, gGradientPaletteCount);
  804.     gTargetPalette = gGradientPalettes[ gCurrentPaletteNumber ];
  805.   }
  806.  
  807.   EVERY_N_MILLISECONDS(40) {
  808.     nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 16);
  809.   }
  810.  
  811.   colorwaves( leds, NUM_LEDS, gCurrentPalette);
  812.  
  813.   return 20;
  814. }
  815.  
  816.  
  817. // This function draws color waves with an ever-changing,
  818. // widely-varying set of parameters, using a color palette.
  819. void colorwaves( CRGB* ledarray, uint16_t numleds, CRGBPalette16& palette)
  820. {
  821.   static uint16_t sPseudotime = 0;
  822.   static uint16_t sLastMillis = 0;
  823.   static uint16_t sHue16 = 0;
  824.  
  825.   // uint8_t sat8 = beatsin88( 87, 220, 250);
  826.   uint8_t brightdepth = beatsin88( 341, 96, 224);
  827.   uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
  828.   uint8_t msmultiplier = beatsin88(147, 23, 60);
  829.  
  830.   uint16_t hue16 = sHue16;//gHue * 256;
  831.   uint16_t hueinc16 = beatsin88(113, 300, 1500);
  832.  
  833.   uint16_t ms = millis();
  834.   uint16_t deltams = ms - sLastMillis ;
  835.   sLastMillis  = ms;
  836.   sPseudotime += deltams * msmultiplier;
  837.   sHue16 += deltams * beatsin88( 400, 5, 9);
  838.   uint16_t brightnesstheta16 = sPseudotime;
  839.  
  840.   for ( uint16_t i = 0 ; i < numleds; i++) {
  841.     hue16 += hueinc16;
  842.     uint8_t hue8 = hue16 / 256;
  843.     uint16_t h16_128 = hue16 >> 7;
  844.     if ( h16_128 & 0x100) {
  845.       hue8 = 255 - (h16_128 >> 1);
  846.     } else {
  847.       hue8 = h16_128 >> 1;
  848.     }
  849.  
  850.     brightnesstheta16  += brightnessthetainc16;
  851.     uint16_t b16 = sin16( brightnesstheta16  ) + 32768;
  852.  
  853.     uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
  854.     uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
  855.     bri8 += (255 - brightdepth);
  856.  
  857.     uint8_t index = hue8;
  858.     //index = triwave8( index);
  859.     index = scale8( index, 240);
  860.  
  861.     CRGB newcolor = ColorFromPalette( palette, index, bri8);
  862.  
  863.     uint16_t pixelnumber = i;
  864.     pixelnumber = (numleds - 1) - pixelnumber;
  865.  
  866.     nblend( ledarray[pixelnumber], newcolor, 128);
  867.   }
  868. }
  869.  
  870. // Alternate rendering function just scrolls the current palette
  871. // across the defined LED strip.
  872. void palettetest( CRGB* ledarray, uint16_t numleds, const CRGBPalette16& gCurrentPalette)
  873. {
  874.   static uint8_t startindex = 0;
  875.   startindex--;
  876.   fill_palette( ledarray, numleds, startindex, (256 / NUM_LEDS) + 1, gCurrentPalette, 255, LINEARBLEND);
  877. }
  878.  
  879. #define STARTING_BRIGHTNESS 64
  880. #define FADE_IN_SPEED       32
  881. #define FADE_OUT_SPEED      20
  882. uint8_t DENSITY          = 255;
  883.  
  884. uint16_t cloudTwinkles()
  885. {
  886.   DENSITY = 255;
  887.   colortwinkles(CloudColors_p);
  888.   return 20;
  889. }
  890.  
  891. uint16_t rainbowTwinkles()
  892. {
  893.   DENSITY = 255;
  894.   colortwinkles(RainbowColors_p);
  895.   return 20;
  896. }
  897.  
  898. uint16_t snowTwinkles()
  899. {
  900.   DENSITY = 255;
  901.   colortwinkles(snowColors);
  902.   return 20;
  903. }
  904.  
  905. uint16_t incandescentTwinkles()
  906. {
  907.   DENSITY = 255;
  908.   colortwinkles(incandescentColors);
  909.   return 20;
  910. }
  911.  
  912. uint16_t fireflies()
  913. {
  914.   DENSITY = 16;
  915.   colortwinkles(incandescentColors);
  916.   return 20;
  917. }
  918.  
  919. enum { GETTING_DARKER = 0, GETTING_BRIGHTER = 1 };
  920.  
  921. void colortwinkles(CRGBPalette16 palette)
  922. {
  923.   // Make each pixel brighter or darker, depending on
  924.   // its 'direction' flag.
  925.   brightenOrDarkenEachPixel( FADE_IN_SPEED, FADE_OUT_SPEED);
  926.  
  927.   // Now consider adding a new random twinkle
  928.   if ( random8() < DENSITY ) {
  929.     int pos = random16(NUM_LEDS);
  930.     if ( !leds[pos]) {
  931.       leds[pos] = ColorFromPalette( palette, random8(), STARTING_BRIGHTNESS, NOBLEND);
  932.       setPixelDirection(pos, GETTING_BRIGHTER);
  933.     }
  934.   }
  935. }
  936.  
  937. void brightenOrDarkenEachPixel( fract8 fadeUpAmount, fract8 fadeDownAmount)
  938. {
  939.   for ( uint16_t i = 0; i < NUM_LEDS; i++) {
  940.     if ( getPixelDirection(i) == GETTING_DARKER) {
  941.       // This pixel is getting darker
  942.       leds[i] = makeDarker( leds[i], fadeDownAmount);
  943.     } else {
  944.       // This pixel is getting brighter
  945.       leds[i] = makeBrighter( leds[i], fadeUpAmount);
  946.       // now check to see if we've maxxed out the brightness
  947.       if ( leds[i].r == 255 || leds[i].g == 255 || leds[i].b == 255) {
  948.         // if so, turn around and start getting darker
  949.         setPixelDirection(i, GETTING_DARKER);
  950.       }
  951.     }
  952.   }
  953. }
  954.  
  955. CRGB makeBrighter( const CRGB& color, fract8 howMuchBrighter)
  956. {
  957.   CRGB incrementalColor = color;
  958.   incrementalColor.nscale8( howMuchBrighter);
  959.   return color + incrementalColor;
  960. }
  961.  
  962. CRGB makeDarker( const CRGB& color, fract8 howMuchDarker)
  963. {
  964.   CRGB newcolor = color;
  965.   newcolor.nscale8( 255 - howMuchDarker);
  966.   return newcolor;
  967. }
  968.  
  969. // Compact implementation of
  970. // the directionFlags array, using just one BIT of RAM
  971. // per pixel.  This requires a bunch of bit wrangling,
  972. // but conserves precious RAM.  The cost is a few
  973. // cycles and about 100 bytes of flash program memory.
  974. uint8_t  directionFlags[ (NUM_LEDS + 7) / 8];
  975.  
  976. bool getPixelDirection( uint16_t i) {
  977.   uint16_t index = i / 8;
  978.   uint8_t  bitNum = i & 0x07;
  979.  
  980.   uint8_t  andMask = 1 << bitNum;
  981.   return (directionFlags[index] & andMask) != 0;
  982. }
  983.  
  984. void setPixelDirection( uint16_t i, bool dir) {
  985.   uint16_t index = i / 8;
  986.   uint8_t  bitNum = i & 0x07;
  987.  
  988.   uint8_t  orMask = 1 << bitNum;
  989.   uint8_t andMask = 255 - orMask;
  990.   uint8_t value = directionFlags[index] & andMask;
  991.   if ( dir ) {
  992.     value += orMask;
  993.   }
  994.   directionFlags[index] = value;
  995. }
  996.  
  997. /*
  998. //
  999. // Mark's xy coordinate mapping code.  See the XYMatrix for more information on it.
  1000. //
  1001. uint16_t XY( uint8_t x, uint8_t y)
  1002. {
  1003.   uint16_t i;
  1004.   if( kMatrixSerpentineLayout == false) {
  1005.     i = (y * MATRIX_WIDTH) + x;
  1006.   }
  1007.   if( kMatrixSerpentineLayout == true) {
  1008.     if( y & 0x01) {
  1009.       // Odd rows run backwards
  1010.       uint8_t reverseX = (MATRIX_WIDTH - 1) - x;
  1011.       i = (y * MATRIX_WIDTH) + reverseX;
  1012.     } else {
  1013.       // Even rows run forwards
  1014.       i = (y * MATRIX_WIDTH) + x;
  1015.     }
  1016.   }
  1017.   return i;
  1018. }
  1019. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement