steveof2620

Stick v3.0

Dec 26th, 2019
462
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 30.31 KB | None | 0 0
  1. /*
  2. Hardware:
  3.   Circuit Playground Express (uses internal accelerometer, microphone, buttons A & B and slide switch
  4.                               and onboard neoPixels)
  5.   1 x Potentiometer
  6.   1 x 38 LED Neopixel WS2812B strip
  7. */
  8.  
  9. // libraries used
  10. #include "FastLED.h"
  11. #include <Adafruit_CircuitPlayground.h>
  12.  
  13. //====================================================================================================================
  14. // Global Definitions
  15. //====================================================================================================================
  16.  
  17. //Buttons A & B on the CPX
  18. #define BUTTON_A 4
  19. #define BUTTON_B 5
  20.  
  21. //The total number of LEDs being used
  22. #define NUM_LEDS 38
  23.  
  24. //NeoPixel strip connected to A7
  25. #define DATA_PIN 1
  26.  
  27. //Definitations for the VU_meter() function
  28. #define SAMPLE_WINDOW   10  // Sample window for average level
  29. #define PEAK_HANG       24  // Time of pause before peak dot falls
  30. #define PEAK_FALL        4  // Rate of falling peak dot
  31.  
  32. //Definitations for the fire_effect() function
  33. #define FRAMES_PER_SECOND 60
  34. #define COOLING  55        // COOLING: How much does the air cool as it rises?
  35.                            //Less cooling = taller flames.  More cooling = shorter flames.
  36.                            // Default 55, suggested range 20-100
  37. #define SPARKING 120       // SPARKING: What chance (out of 255) is there that a new spark will be lit?
  38.                            // Higher chance = more roaring fire.  Lower chance = more flickery fire.
  39.                            // Default 120, suggested range 50-200.
  40.  
  41. //For the potentiometer
  42. #define POT_PIN  A3        //Otherwise known as pin 10?
  43.  
  44. //Initialise the LED array.
  45. CRGB leds[NUM_LEDS];
  46.  
  47. //====================================================================================================================
  48. // Global Variables
  49. //====================================================================================================================
  50.  
  51. byte intensity = 150;       // intensity: default brightness
  52. float X, Y, Z;              // For the adafruit accelerometer
  53.  
  54. // variables for the selection function:
  55. int mode = 0;               // mode: used to differentiate and select one out of the five functions
  56. bool slideSwitch;           // used to select the VU_function (incomparable with case statement)
  57.  
  58. // variables for the chaser() function:
  59. int onePos = 2;
  60. int twoPos = 2;
  61. boolean oneDir = true;
  62. boolean twoDir = true;
  63.  
  64. // variables for the rainbow_display() function
  65. int rainbow_timer = 0;
  66.  
  67. // variables for the VU_meter() function
  68. byte peak = 16;           // Peak level of column; used for falling dots
  69. unsigned int sample;
  70. byte dotCount = 0;        //Frame counter for peak dot
  71. byte dotHangCount = 0;    //Frame counter for holding peak dot
  72.  
  73. // variables for the fire_effect() function
  74. bool gReverseDirection = false;
  75. CRGBPalette16 gPal;
  76.  
  77. //used by adjustSpeed (called via commetEffect & firestarter)
  78. int LEDAccel=0;             // stores the acceleration value of the LED animation sequence (speed up or slow down)
  79.  
  80. //used by setDelay (called via commetEffect & firestarter)
  81. int maxLEDSpeed = 50;       // maxLEDSpeed: identifies the maximum speed of the LED animation sequence
  82. int animationDelay = 0;     // animationDelay: is used in the animation Speed calculation. The greater the
  83.                             // animationDelay, the slower the LED sequence.
  84.  
  85. //used by commetEffect & fireStarter
  86. int LEDSpeed=1;                   // stores the "speed" of the LED animation sequence
  87. int LEDPosition=int(NUM_LEDS/2);  // identifies the LED within the strip to modify (leading LED).
  88.                                   // The number will be between 0 & NUM_LEDS-1
  89. byte bright = 80;                 // used to modify the brightness of the trailing LEDs
  90.  
  91. //used by fireStarter
  92. byte ledb[NUM_LEDS];
  93. byte ledh[NUM_LEDS];
  94.  
  95. //used by sparkle (called via firestarter)
  96. int sparkTest = 0;          // sparkTest:   variable used in the "sparkle" LED animation sequence
  97.  
  98. //====================================================================================================================
  99. // setup() : Start up and housekeeping. Display the boot sequence animation
  100. //====================================================================================================================
  101. void setup(){
  102.    
  103.     Serial.begin(9600);
  104.     CircuitPlayground.begin(); //for the built in accelerometer, onboard LEDs etc  
  105.     delay(2000);          //Delay for two seconds to power the LEDS before starting the data signal
  106.     FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);    //initialise the LED strip
  107.     FastLED.setBrightness(intensity);
  108.     FastLED.clear();      //So we know where we are at
  109.     FastLED.show();
  110.     //used by the fire_effect() function, sets a (bulit in) palette for the funciton to use
  111.     gPal = HeatColors_p;
  112.     boot_sequence();
  113. }
  114.  
  115. //====================================================================================================================
  116. // loop() : The main loop
  117. //====================================================================================================================
  118. void loop(){
  119.  
  120.   slideSwitch = CircuitPlayground.slideSwitch();
  121.    
  122.   // using the slide switch to run the VU_meter function(s) cause it sets
  123.   // the mode variable to zero for reasons unknown
  124.   if (slideSwitch){
  125.     // Set the indicator to zero because VU_meter sets mode to zero
  126.     // for reasons unknown. Also indicates we're not in the select mode mode.
  127.     CircuitPlayground.clearPixels();
  128.     VU_meter();
  129.   }
  130.   else {
  131.     mode = selectMode();  
  132.     //Serial.println(mode);
  133.     switch(mode){
  134.       case 0:                                              
  135.         //Serial.println("Mode one selected");
  136.         rainbow_display();
  137.         break;
  138.  
  139.       case 1:
  140.         //Serial.println("Mode two selected");
  141.         fire_effect();
  142.         break;
  143.      
  144.       case 2:
  145.         //Serial.println("Mode three selected");
  146.         chaser();
  147.         break;
  148.  
  149.       case 3:                                              
  150.         //Serial.println("Mode four selected");
  151.         cometEffect();
  152.         break;
  153.  
  154.       case 4:
  155.         //Serial.println("Mode five selected");
  156.         fireStarter();
  157.         break;
  158.     }
  159.   }
  160. }
  161.  
  162. //====================================================================================================================
  163. // selectMode() : Read button states. This value will be used to choose the animation sequence to display and
  164. //                    update the CPX leds accordingly.
  165. //====================================================================================================================
  166. int selectMode (){
  167.   // left button A increases, right button B decreases
  168.  
  169.   // Indicate the current mode
  170.   CircuitPlayground.setPixelColor(mode, 0, 255, 0);
  171.  
  172.   // Button A, going forward (or up)
  173.     if (digitalRead(BUTTON_A)){
  174.     mode++;
  175.     CircuitPlayground.setPixelColor(mode, 0, 255, 0);
  176.     if (mode > 4){
  177.       mode = 0;
  178.       CircuitPlayground.clearPixels();
  179.       CircuitPlayground.setPixelColor(mode, 0, 255, 0);
  180.     }
  181.     delay(500); //delay here, otherwise it slows everything.
  182.   }
  183.  
  184.   // Button B, going backward (or down)
  185.   if (digitalRead(BUTTON_B)){
  186.     mode--;
  187.     CircuitPlayground.setPixelColor(mode+1, 0, 0, 0);
  188.     if (mode < 1){
  189.       mode = 0;
  190.       CircuitPlayground.clearPixels();
  191.       CircuitPlayground.setPixelColor(mode, 0, 255, 0);
  192.     }
  193.     delay(500);
  194.   }
  195.   return mode;
  196. }
  197.  
  198. //====================================================================================================================
  199. // boot_sequence() : Called from void setup() to run only once. Displays a sort of flickering effect to look like
  200. //                   it's coming to life.
  201. //====================================================================================================================
  202. void boot_sequence(){
  203.   lightning();
  204.   flicker();
  205. }
  206.  
  207. //====================================================================================================================
  208. // lightning() : Called from void boot_sequence(). Displays a sort of lightning effect.
  209. //====================================================================================================================
  210. void lightning(){
  211.   int FLASHES = 50;       //the number of flashes
  212.   int FREQUENCY = 50;     //delay between flashes
  213.   int dimmer;
  214.   int flash_length = random(3,5);
  215.  
  216. for (int flashCounter = 0; flashCounter < random8(int(FLASHES/3),FLASHES); flashCounter++)
  217.   {
  218.     if(flashCounter == 0) dimmer = 5;     // the brightness of the leader is scaled down by a factor of 5
  219.     else dimmer = random8(1,3);           // return strokes are brighter than the leader
  220.    
  221.     //fill_solid(leds,NUM_LEDS,CHSV(255, 0, 255/dimmer));    
  222.     fill_solid(leds+random(0,NUM_LEDS-flash_length), flash_length, CHSV(255, 0, 255/dimmer));
  223.    
  224.     FastLED.show();
  225.     delay(random8(4,10));                 // each flash only lasts 4-10 milliseconds
  226.    
  227.     fill_solid(leds,NUM_LEDS,CHSV(0, 0, 0));
  228.     FastLED.show();
  229.    
  230.     if (flashCounter == 0) delay (150);   // longer delay until next flash after the leader
  231.     delay(50+random8(100));               // shorter delay between strokes  
  232.   }
  233.   //Not needed >> delay(random8(FREQUENCY)*100);  // delay between strikes  
  234. }
  235.  
  236. //====================================================================================================================
  237. // flicker() : Called from void boot_sequence(). Displays a sort of flickering effect to mimic a sort of flouro
  238. //             tube coming to life, before displaying a rainbow.
  239. //====================================================================================================================
  240. void flicker() {
  241.    // a flicker effect
  242.    //1000 - about 3 seconds
  243.    
  244.    //flickers from each end
  245.    for (int i = 0; i < 80; i++) {
  246.     if (random(2) == 1) {
  247.       //set the colors here
  248.       fill_solid(leds,int(random(NUM_LEDS/2)), CRGB::White);
  249.       fill_solid(leds+int(NUM_LEDS-(NUM_LEDS/2)),int(random(NUM_LEDS/2)), CRGB::White);
  250.       FastLED.show();        
  251.     } else {
  252.       FastLED.clear();
  253.       FastLED.show();
  254.     }
  255.     delay(random(60));
  256.   }
  257.  
  258.   //flickers the whole strip
  259.   for (int i = 0; i < 40; i++) {
  260.     if (random(2) == 1) {
  261.       //set the colors here
  262.       fill_solid(leds, NUM_LEDS, CRGB::White);
  263.       FastLED.show();
  264.     } else {
  265.       FastLED.clear();
  266.       FastLED.show();
  267.     }
  268.     delay(random(60));
  269.   }
  270.   fill_rainbow(leds, NUM_LEDS, 0, 255/NUM_LEDS);
  271.   FastLED.show();
  272. }
  273.  
  274. //====================================================================================================================
  275. // rainbow_display () : This is where the rainbow sequence is controlled. It calls display_rainbow,
  276. //                           clear_rainbow and rainbow cylon.
  277. //====================================================================================================================
  278. void rainbow_display(){
  279.  
  280.   int rainbowRunTime = 2; // time in seconds for the initial rainbow display to run
  281.   int cylonRunTime = 10;
  282.  
  283.   // Increment a counter every second so that each sequence runs for a specified
  284.   // number of seconds
  285.   EVERY_N_SECONDS( 1 ) { rainbow_timer++; };
  286.  
  287.   // call the required sequence according to the time the routine has run.
  288.   if (rainbow_timer <= rainbowRunTime) {
  289.     display_rainbow();  
  290.   }
  291.   else if (rainbow_timer == rainbowRunTime +1) {
  292.     clear_rainbow();
  293.     rainbow_timer ++;  //run only once  
  294.   }
  295.   else if (rainbow_timer > rainbowRunTime) {
  296.     rainbow_cylon();
  297.     FastLED.show();
  298.     // reset the timer so that it can run from the beginning again
  299.     if (rainbow_timer > rainbowRunTime + cylonRunTime){
  300.       rainbow_timer = 0;
  301.     }
  302.   }
  303. }
  304.  
  305. //====================================================================================================================
  306. // display_rainbow () : The beginning of the sequence. A rainbow is displayed with a glitter effect and the the
  307. //                           rainbow_cylon running underneath.
  308. //====================================================================================================================
  309. void display_rainbow(){
  310.   int glitter_led;
  311.  
  312.   FastLED.setBrightness (intensity/2);
  313.   fill_rainbow(leds, NUM_LEDS, 0, 255/NUM_LEDS);
  314.  
  315.   if( random8() < NUM_LEDS/2) {
  316.     glitter_led = random16(NUM_LEDS);
  317.     leds[glitter_led].maximizeBrightness();
  318.     leds[glitter_led] += CRGB::White;
  319.    }
  320.   rainbow_cylon();  
  321.   FastLED.show();
  322. }
  323.  
  324. //====================================================================================================================
  325. // clear_rainbow () : Clears the rainbow one led at time to give a swipe effect.
  326. //====================================================================================================================
  327. void clear_rainbow(){    
  328.   for (int i = 0; i< NUM_LEDS; i++){
  329.     leds[i] = CRGB::Black;
  330.     delay(15); //rainbowRunTime * 5 ??
  331.     FastLED.show();
  332.   }
  333. }
  334.  
  335. //====================================================================================================================
  336. // rainbow_cylon () : Displays one dot for each colour of the rainbow, in sort of chase effect.
  337. //====================================================================================================================
  338. void rainbow_cylon(){
  339.  
  340.   uint8_t fadeval = 100;            // Trail behind the LED's. Lower => faster fade.
  341.   uint8_t bpm = 75;
  342.  
  343.   uint8_t inner = beatsin8(bpm, NUM_LEDS/4, NUM_LEDS/4*3);          // Move 1/4 to 3/4
  344.   uint8_t outer = beatsin8(bpm, 0, NUM_LEDS-1);                     // Move entire length
  345.   uint8_t middle = beatsin8(bpm, NUM_LEDS/3, NUM_LEDS/3*2);         // Move 1/3 to 2/3
  346.   uint8_t lower_middle = beatsin8(bpm, NUM_LEDS/5, NUM_LEDS/5*4);   // Move 1/5 to 4/5
  347.   uint8_t lower = beatsin8(bpm, NUM_LEDS/10, NUM_LEDS/10*9);        // Move 1/6 to 5/6
  348.  
  349.   leds[lower] = CRGB::Yellow;
  350.   leds[inner] = CRGB::Red;
  351.   leds[lower_middle] = CRGB::Green;
  352.   leds[middle] = CRGB::Blue;
  353.   leds[outer] = CRGB::Purple;
  354.  
  355.   nscale8(leds,NUM_LEDS,fadeval); // Fade the entire array. Or for just a few LED's, use  
  356. }
  357.  
  358. //====================================================================================================================
  359. // VU_Meter() : Displays a series of LEDS according to sound picked up by the Circuit Playground Express microphone.
  360. //              Derived from the VU_Meter() contained within CPX examples.
  361. //====================================================================================================================
  362. void VU_meter(){
  363.  
  364.   Serial.println(mode);
  365.  
  366.   int inputCeiling = 90;    // Upper range of mic sensitivity in db SPL -> original setting 110
  367.                             // lower the setting the higher the range
  368.   int inputFloor = 70;      // Lower range of mic sensitivity in dB SPL -> original setting 56
  369.                             // 62 seems the setting to cancel out background noise
  370.  
  371.   float mapf(float x, float in_min, float in_max, float out_min, float out_max);
  372.  
  373.   inputCeiling = map(analogRead(POT_PIN), 0, 1023, 120, 80);
  374.  
  375.   //Tried to set the inputFloor by InputCeiling, didn't seem to work
  376.   //inputFloor = inputCeiling - 15;
  377.  
  378.   float peakToPeak = 0;   // peak-to-peak level
  379.   unsigned int c, y;
  380.  
  381.   //get peak sound pressure level over the sample window
  382.   peakToPeak = CircuitPlayground.mic.soundPressureLevel(SAMPLE_WINDOW);
  383.  
  384.   //limit to the floor value
  385.   peakToPeak = max(inputFloor, peakToPeak);
  386.  
  387.   //Fill the strip with rainbow gradient
  388.   for (int i=0;i<=NUM_LEDS-1;i++){
  389.     //colours set in the map function
  390.     leds[i] = CHSV(map(i,0,NUM_LEDS-1,96,254), 255, 255);
  391.   }
  392.  
  393.   c = mapf(peakToPeak, inputFloor, inputCeiling, NUM_LEDS, 0);
  394.  
  395.   // Turn off pixels that are below volume threshold.
  396.   if(c < peak) {
  397.     peak = c;        // Keep dot on top
  398.     dotHangCount = 0;    // make the dot hang before falling
  399.   }
  400.   if (c <= NUM_LEDS) { // Fill partial column with off pixels
  401.     drawLine(NUM_LEDS, NUM_LEDS-c, 0);
  402.   }
  403.  
  404.   // Set the peak dot to match the rainbow gradient
  405.   y = NUM_LEDS - peak;
  406.   leds[y-1] = CHSV(map(y,0,NUM_LEDS-1,96,254), 255, 255);
  407.   FastLED.show();
  408.  
  409.   // Frame based peak dot animation
  410.   if(dotHangCount > PEAK_HANG) { //Peak pause length
  411.     if(++dotCount >= PEAK_FALL) { //Fall rate
  412.       peak++;
  413.       dotCount = 0;
  414.     }
  415.   }
  416.   else {
  417.     dotHangCount++;
  418.   }
  419. }
  420.  
  421. //===================================================================================================================
  422. // drawLine(...) : Used by VU_Meter() to draw a line between two points of a given color.
  423. //===================================================================================================================
  424. void drawLine(uint8_t from, uint8_t to, uint32_t c){
  425.   uint8_t fromTemp;
  426.   if (from > to) {
  427.     fromTemp = from;
  428.     from = to;
  429.     to = fromTemp;
  430.   }
  431.   for(int i=from; i<=to; i++){
  432.     leds[i] = CRGB::Black;
  433.   }
  434. }
  435.  
  436. //===================================================================================================================
  437. // mapf(...) : Used by VU_Meter() to maths support of some kind.
  438. //===================================================================================================================
  439. float mapf(float x, float in_min, float in_max, float out_min, float out_max){
  440.     return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  441. }
  442.  
  443. //===================================================================================================================
  444. // fire_effect() : A flame effect. Derived from Fire2012WithPalette provided as an example within the FastLED libary
  445. //===================================================================================================================
  446. void fire_effect(){
  447.  
  448.   // Array of temperature readings at each simulation cell
  449.   static byte heat[NUM_LEDS];
  450.  
  451.   random16_add_entropy( random());
  452.   // Step 1.  Cool down every cell a little
  453.     for( int i = 0; i < NUM_LEDS; i++) {
  454.       heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
  455.     }
  456.  
  457.     // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  458.     for( int k= NUM_LEDS - 1; k >= 2; k--) {
  459.       heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
  460.     }
  461.    
  462.     // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
  463.     if( random8() < SPARKING ) {
  464.       int y = random8(7);
  465.       heat[y] = qadd8( heat[y], random8(160,255) );
  466.     }
  467.  
  468.     // Step 4.  Map from heat cells to LED colors
  469.     for( int j = 0; j < NUM_LEDS; j++) {
  470.       // Scale the heat value from 0-255 down to 0-240
  471.       // for best results with color palettes.
  472.       byte colorindex = scale8( heat[j], 240);
  473.       CRGB color = ColorFromPalette( gPal, colorindex);
  474.       int pixelnumber;
  475.       if( gReverseDirection ) {
  476.         pixelnumber = (NUM_LEDS-1) - j;
  477.       } else {
  478.         pixelnumber = j;
  479.       }
  480.       leds[pixelnumber] = color;
  481.     }
  482.  
  483.   FastLED.show(); // display this frame
  484.   FastLED.delay(1000 / FRAMES_PER_SECOND);
  485. }
  486.  
  487. //===================================================================================================================
  488. // chaser() : Two sets of LEDs chasing one another. Colours randomly selected from a list of colours of the rainbow,
  489. //            pace set by potentiometer.
  490. //            Derived from 'dotBeat' By John Burrougs and modified by Andrew Tuline.
  491. //===================================================================================================================
  492. void chaser(){
  493.  
  494.   int delay_speed = map(analogRead(POT_PIN), 0, 1023, 50, 10);
  495.   int random_colour;
  496.  
  497.   //a list of colours from the rainbow, one is randomly selected
  498.   CRGB colour_choices[5] = {CHSV(HUE_RED, 255, 255), CHSV(HUE_YELLOW, 255, 255), CHSV(HUE_GREEN, 255, 255),
  499.                             CHSV(HUE_BLUE, 255, 255), CHSV(HUE_PURPLE, 255, 255)};
  500.  
  501.   //select a colour from the list
  502.   random_colour = random(0,5);
  503.  
  504.   // turn on the LEDs to draw the current position of each line along the strip  
  505.   //leds[onePos] = CRGB::Green;  
  506.   leds[onePos] = colour_choices[random_colour];
  507.   leds[max(onePos - 1, 0)] = leds[onePos];
  508.   leds[min(onePos + 1, NUM_LEDS - 1)] = leds[onePos];
  509.  
  510.   //leds[twoPos] = CRGB::Blue;
  511.   if (random_colour < 4){
  512.     leds[twoPos] = colour_choices[random_colour+1];
  513.   }
  514.   else{
  515.      leds[twoPos] = colour_choices[0];  
  516.   }
  517.   leds[max(twoPos - 1, 0)] = leds[twoPos];
  518.   leds[min(twoPos + 1, NUM_LEDS - 1)] = leds[twoPos];
  519.  
  520.   FastLED.show();
  521.  
  522.   delay(delay_speed);
  523.  
  524.   // turn all LEDs off so they can be re-drawn on the next loop in the next calculated position
  525.   leds[onePos] = CRGB::Black;
  526.   leds[max(onePos - 1, 0)] = leds[onePos];
  527.   leds[min(onePos + 1, NUM_LEDS - 1)] = leds[onePos];
  528.  
  529.   leds[twoPos] = CRGB::Black;
  530.   leds[max(twoPos - 1, 0)] = leds[twoPos];
  531.   leds[min(twoPos + 1, NUM_LEDS - 1)] = leds[twoPos];
  532.  
  533.   FastLED.show();
  534.  
  535.   // calculate the next position of each LED line by advancing the LED position in the forward or reverse
  536.   // direction as required. If the line reaches the end of the LED strip, it is time to change its
  537.   // direction.
  538.   if (oneDir) {     // if going forward
  539.     onePos += 4;
  540.     if (onePos >= NUM_LEDS) {
  541.       onePos = NUM_LEDS - 1;
  542.       oneDir = false;  // go in reverse direction
  543.     }
  544.   }
  545.   // else {   //if going reverse
  546.   if (!oneDir) {
  547.     onePos -= 4;
  548.     if (onePos <= 0) {
  549.       onePos = 0;
  550.       oneDir = true;  // go in forward direction
  551.     }
  552.   }
  553.  
  554.   if (twoDir) {     // if going forward
  555.     twoPos += 3;
  556.     if (twoPos >= NUM_LEDS) {
  557.       twoPos = NUM_LEDS - 1;
  558.       twoDir = false;  // go in reverse direction
  559.     }
  560.   }
  561.   //else {   //if going reverse
  562.   if (!twoDir) {
  563.     twoPos -= 3;
  564.     if (twoPos <= 0) {
  565.       twoPos = 0;
  566.       twoDir = true;  // go in forward direction
  567.     }
  568.   }
  569. }
  570.  
  571. //===================================================================================================================
  572. // cometEffect() :  random brightness of the trailing LEDs produces an interesting comet-like effect. Colour via
  573. //                  potentiometer, speed set via accelerometer.
  574. //                  Derived from NeoPixel Playground project by Scott C
  575. //                  https://arduinobasics.blogspot.com/2015/07/neopixel-playground.html
  576. //===================================================================================================================
  577. void cometEffect(){
  578.  
  579.       adjustSpeed();
  580.       constrainLEDs();
  581.      
  582.       byte potVal = map(analogRead(POT_PIN), 0, 1023, 0, 255);
  583.  
  584.       //Serial.println(potVal);
  585.      
  586.       showLED(LEDPosition, potVal, 255, intensity);       // Hue set via potentiometer.
  587.  
  588.       //The following lines create the comet effect
  589.       bright = random(50, 100);                           // Randomly select a brightness between 50 and 100
  590.       leds[LEDPosition] = CHSV((potVal+40),255, bright);  // The trailing LEDs will have a different hue to the
  591.       fadeLEDs(8);                                        // leading LED, and will have a random brightness.
  592.       setDelay(LEDSpeed);                                 // This will affect the length of the Trailing LEDs.
  593. }                                                         // The LEDSpeed will be affected by the slope of the
  594.                                                           // Accelerometer's X-Axis
  595. //===================================================================================================================
  596. // fireStarter() : using the accelerometer. Starts off looking like a ball of fire, leaving a trail of little fires.
  597. //                 As the potentiometer is turned, it becomes more like a shooting star with a rainbow-sparkle trail.
  598. //                 Derived from NeoPixel Playground project by Scott'
  599. //                 C https://arduinobasics.blogspot.com/2015/07/neopixel-playground.html
  600. //===================================================================================================================
  601. void fireStarter(){
  602.  
  603.       adjustSpeed();
  604.       constrainLEDs();
  605.      
  606.       byte potVal = map(analogRead(POT_PIN), 0, 1023, 0, 255);
  607.      
  608.       ledh[LEDPosition] = potVal;                      // Hue set by potentiometer
  609.       showLED(LEDPosition, ledh[LEDPosition], 255, intensity);
  610.  
  611.       //The following lines create the fire starter effect
  612.       bright = random(50, 100);                       // Randomly select a brightness between 50 and 100
  613.       ledb[LEDPosition] = bright;                     // Assign this random brightness value to the trailing LEDs
  614.       sparkle(potVal/5);                              // Call the sparkle routine to create that sparkling effect.
  615.                                                       // The potentiometer controls the difference in hue from
  616.       fadeLEDs(1);                                    //  LED to LED. A low number creates a longer tail
  617.       setDelay(LEDSpeed);                             // The LEDSpeed will be affected by the slope of the
  618. }                                                     //  Accelerometer's X Axis                                
  619.  
  620. //===================================================================================================================
  621. // adjustSpeed() : called by commetEffect & fireStarter. Uses the X  axis value of the accelerometer to adjust speed
  622. //                 and direction of the LED animation sequence
  623. //===================================================================================================================
  624. void adjustSpeed(){
  625.   // Take a reading from the Y Pin of the accelerometer and adjust the value so that positive numbers move in one
  626.   // direction, and negative numbers move in the opposite diraction. map function used to convert accelerometer
  627.   // readings, constrain function to ensure it stays within the desired limits
  628.   // values of -2.5 and -7 determined by trial and error.
  629.  
  630.   // added circuit playground Y
  631.   X = CircuitPlayground.motionX();
  632.   LEDAccel = constrain(map(X, -2.5, -7 , maxLEDSpeed, -maxLEDSpeed),-maxLEDSpeed, maxLEDSpeed);
  633.  
  634.   //delay(500);
  635.   //Serial.println(X);
  636.  
  637.   // The Speed of the LED animation sequence can increase (accelerate), decrease (decelerate)
  638.   LEDSpeed = LEDSpeed + LEDAccel;
  639.  
  640.   //The following lines of code are used to control the direction of the LED animation sequence, and limit
  641.   //the speed of that animation.
  642.   if (LEDSpeed>0){
  643.     LEDPosition++;                         // Illuminate the LED in the Next position
  644.     if (LEDSpeed>maxLEDSpeed){
  645.       LEDSpeed=maxLEDSpeed;                // Ensure that the speed does not go beyond the maximum
  646.     }                                      // speed in the positive direction              
  647.   }
  648.  
  649.   if (LEDSpeed<0){
  650.     LEDPosition--;                         // Illuminate the LED in the Prior position
  651.     if (LEDSpeed<-maxLEDSpeed){
  652.       LEDSpeed = -maxLEDSpeed;             // Ensure that the speed does not go beyond the maximum speed
  653.     }                                      // in the negative direction            
  654.   }
  655. }
  656.  
  657. //===================================================================================================================
  658. // constrainLEDs() : called by commetEffect & fireStarter. Ensures that the LED animation sequence remains within
  659. //                   boundaries of the various arrays (and the LED strip) and it also creates a "bouncing" effect
  660. //                   at both ends of the LED strip.
  661. //===================================================================================================================
  662. void constrainLEDs(){
  663.   LEDPosition = constrain(LEDPosition, 0, NUM_LEDS-1);    // Make sure that the LEDs stay within the boundaries of
  664.   if(LEDPosition == 0 || LEDPosition == NUM_LEDS-1) {     //  the LED strip
  665.     LEDSpeed = (LEDSpeed * -0.9);                         // Reverse the direction of movement when LED gets to
  666.   }                                                       // end of strip.Creating a bouncing ball effect.
  667. }
  668.  
  669. //===================================================================================================================
  670. // fadeLEDs(fadeVal):  called by commetEffect & fireStarter, used to fade the LEDs back to black (OFF)
  671. //===================================================================================================================
  672. void fadeLEDs(int fadeVal){
  673.   for (int i = 0; i<NUM_LEDS; i++){
  674.     leds[i].fadeToBlackBy( fadeVal );
  675.   }
  676. }
  677.  
  678. //===================================================================================================================
  679. // showLED(...) : called by commetEffect & fireStarter, used to fire the LEDs
  680. //===================================================================================================================
  681. void showLED(int pos, byte LEDhue, byte LEDsat, byte LEDbright){
  682.   leds[pos] = CHSV(LEDhue,LEDsat,LEDbright);
  683.   FastLED.show();
  684. }
  685.  
  686. //===================================================================================================================
  687. // setDelay(LSpeed) : called by commetEffect & fireStarter.
  688. //===================================================================================================================
  689. void setDelay(int LSpeed){
  690.   animationDelay = maxLEDSpeed - abs(LSpeed);
  691.   delay(animationDelay);
  692. }
  693.  
  694. //===================================================================================================================
  695. // sparkle(hDiff) : called by fireStarter to create a sparkling/fire-like effect each LED. Hue and brightness is
  696. //                  monitored and modified using arrays (ledh & ledb)
  697. //===================================================================================================================
  698. void sparkle(byte hDiff){
  699.   for(int i = 0; i < NUM_LEDS; i++) {
  700.     ledh[i] = ledh[i] + hDiff;         // hDiff controls the extent to which the hue changes along the trailing LEDs
  701.  
  702.     //prevents "negative" brightness.
  703.     if(ledb[i]<3){
  704.       ledb[i]=0;
  705.     }
  706.  
  707.     // The probability of "re-igniting" an LED will decrease as you move along the tail
  708.     // Once the brightness reaches zero, it cannot be re-ignited unless the leading LED passes over it again.
  709.     if(ledb[i]>0){
  710.       ledb[i]=ledb[i]-2;
  711.       sparkTest = random(0,bright);
  712.       if(sparkTest>(bright-(ledb[i]/1.1))){
  713.         ledb[i] = bright;
  714.       } else {
  715.         ledb[i] = ledb[i] / 2;
  716.       }
  717.     }
  718.     leds[i] = CHSV(ledh[i],255,ledb[i]);
  719.   }
  720. }
Advertisement
Add Comment
Please, Sign In to add comment