Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 33.80 KB | None | 0 0
  1. #include <QueueArray.h>
  2.  
  3. // for the sound board
  4. #include <SoftwareSerial.h>
  5. #include "Adafruit_Soundboard.h"
  6.  
  7. #include <Adafruit_NeoPixel.h>
  8.  
  9. // for led triggers
  10. #define HIGH 0x1
  11. #define LOW  0x0
  12.  
  13. // Relay Pin for ECig
  14. int relayPin = 13;
  15.  
  16. // neopixel pins / setup
  17. #define NEO_POWER 2 // for cyclotron and powercell
  18. Adafruit_NeoPixel powerStick = Adafruit_NeoPixel(9, NEO_POWER, NEO_GRB + NEO_KHZ800);
  19.  
  20. #define NEO_NOSE 3 // for nose of wand
  21. Adafruit_NeoPixel noseJewel = Adafruit_NeoPixel(1, NEO_NOSE, NEO_GRB + NEO_KHZ800);
  22.  
  23. #define NEO_WAND 4 // for nose of wand
  24. Adafruit_NeoPixel wandLights = Adafruit_NeoPixel(4, NEO_WAND, NEO_GRB + NEO_KHZ800);
  25.  
  26. // LED indexes into the neopixel powerstick chain for the cyclotron. Each stick has 8 neopixels for a total of
  27. // 16 with an index starting at 0. These offsets are because my powercell window only shows 13 leds. If you can show more
  28. // change the offset index and powercell count to get more or less lit.
  29. const int powercellLedCount = 3;                                         // total number of led's in the animation
  30. const int powercellIndexOffset = 0;                                       // first led offset into the led chain for the animation
  31.  
  32. // These are the indexes for the led's on the chain. Each jewel has 7 LEDs. If you are using a single neopixel or
  33. // some other neopixel configuration you will need to update these indexes to match where things are in the chain
  34. const int c1Start = 4;
  35. const int c1End = 4;
  36. const int c2Start = 5;
  37. const int c2End = 5;
  38. const int c3Start = 6;
  39. const int c3End = 6;
  40. const int c4Start = 7;
  41. const int c4End = 7;
  42. const int ventStart = 8;
  43. const int ventEnd = 8;
  44.  
  45. // inputs for switches and buttons
  46. const int THEME_SWITCH = 5;
  47. const int STARTUP_SWITCH = 6;
  48. const int SAFETY_SWITCH = 7;
  49. const int FIRE_BUTTON = 8;
  50.  
  51. // soundboard pins and setup
  52. #define SFX_RST 9
  53. #define SFX_RX 10
  54. #define SFX_TX 11
  55. const int ACT = 12;    // this allows us to know if the audio is playing
  56.  
  57. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);
  58. Adafruit_Soundboard sfx = Adafruit_Soundboard( &ss, NULL, SFX_RST);
  59.  
  60. // ##############################
  61. // available options
  62. // ##############################
  63. const bool useGameCyclotronEffect = true;   // set this to true to get the fading previous cyclotron light in the idle sequence
  64. const bool useCyclotronFadeInEffect = false; // Instead of the yellow alternate flashing on boot/vent this fades the cyclotron in from off to red
  65. const bool useDialogTracks = true;          // set to true if you want the dialog tracks to play after firing for 5 seconds
  66.  
  67. // Possible Pack states
  68. bool powerBooted = false;   // has the pack booted up
  69. bool isFiring = false;      // keeps track of the firing state
  70. bool shouldWarn = false;    // track the warning state for alert audio
  71. bool shuttingDown = false;  // is the pack in the process of shutting down
  72. bool poweredDown = true;    // is the pack powered down
  73. bool venting = false;       // is the pack venting
  74.  
  75. // physical switch states
  76. bool startup = false;
  77. bool theme = false;
  78. bool safety = false;
  79. bool fire = false;
  80. bool warning = false;
  81.  
  82. // audio track names on soundboard
  83. char startupTrack[] =   "T00     OGG";
  84. char blastTrack[] =     "T01     WAV";
  85. char endTrack[] =       "T02     OGG";
  86. char idleTrack[] =      "T03     WAV";
  87. char shutdownTrack[] =  "T04     OGG";
  88. char clickTrack[] =     "T05     OGG";
  89. char chargeTrack[] =    "T06     WAV";
  90. char warnTrack[] =      "T07     WAV";
  91. char ventTrack[] =      "T08     WAV";
  92. char texTrack[] =       "T09     OGG";
  93. char choreTrack[] =     "T09     OGG";
  94. char toolsTrack[] =     "T09     OGG";
  95. char listenTrack[] =    "T09     OGG";
  96. char thatTrack[] =      "T09     OGG";
  97. char neutronizedTrack[]="T09     OGG";
  98. char boxTrack[] =       "T09     OGG";
  99. char themeTrack[] =     "T16     OGG";
  100.  
  101. // this queue holds a shuffled list of dialog tracks we can pull from so we don't
  102. // play the same ones twice
  103. QueueArray <int> dialogQueue;
  104. int numDialog = 7;
  105.  
  106. // timer trigger times/states
  107. unsigned long firingStateMillis;
  108. const unsigned long firingWarmWaitTime = 5000;  // how long to hold down fire for lights to speed up
  109. const unsigned long firingWarnWaitTime = 10000;  // how long to hold down fire before warning sounds
  110.  
  111. // Arduino setup function
  112. void setup() {    
  113.  
  114.   // softwareserial at 9600 baud for the audio board
  115.   ss.begin(9600);
  116.  
  117.   // set act modes for the fx board
  118.   pinMode(ACT, INPUT);
  119.  
  120.   // Depending on your relay this may need to be updated.
  121.   pinMode(relayPin, OUTPUT);
  122.   // If relay defaults to on set the pin HIGH on init
  123.   digitalWrite(relayPin, LOW);
  124.  
  125.   // configure nose jewel
  126.   noseJewel.begin();
  127.   noseJewel.setBrightness(100);
  128.   noseJewel.show(); // Initialize all pixels to 'off'
  129.  
  130.   // configure powercell/cyclotron
  131.   powerStick.begin();
  132.   powerStick.setBrightness(75);
  133.   powerStick.show(); // Initialize all pixels to 'off'
  134.  
  135.   // configure wand lights
  136.   wandLights.begin();
  137.   wandLights.setBrightness(75);
  138.   wandLights.show();
  139.  
  140.   // set the modes for the switches/buttons
  141.   pinMode(THEME_SWITCH, INPUT);
  142.   digitalWrite(THEME_SWITCH, HIGH);
  143.   pinMode(STARTUP_SWITCH, INPUT);
  144.   digitalWrite(STARTUP_SWITCH, HIGH);
  145.   pinMode(SAFETY_SWITCH, INPUT);
  146.   digitalWrite(SAFETY_SWITCH, HIGH);
  147.   pinMode(FIRE_BUTTON, INPUT);
  148.   digitalWrite(FIRE_BUTTON, HIGH);
  149. }
  150.  
  151. /* ************* Audio Board Helper Functions ************* */
  152. // helper function to play a track by name on the audio board
  153. void playAudio( char* trackname, int playing ) {
  154.   // stop track if one is going
  155.   if (playing == 0) {
  156.     sfx.stop();
  157.   }
  158.    
  159.   // now go play
  160.   if (sfx.playTrack(trackname)) {
  161.     sfx.unpause();
  162.   }
  163. }
  164.  
  165. void playDialogTrack( int playing ){
  166.   // if the queue is empty reseed it
  167.   if ( dialogQueue.isEmpty() ){
  168.     for (int i=1; i<=numDialog; i++){
  169.       dialogQueue.enqueue(i);
  170.     }
  171.   }
  172.  
  173.   switch (dialogQueue.dequeue()){
  174.     case (1):
  175.       playAudio(texTrack, playing);
  176.       break;
  177.     case (2):
  178.       playAudio(listenTrack, playing);
  179.       break;
  180.     case (3):
  181.       playAudio(choreTrack, playing);
  182.       break;
  183.     case (4):
  184.       playAudio(boxTrack, playing);
  185.       break;
  186.     case (5):
  187.       playAudio(thatTrack, playing);
  188.       break;
  189.     case (6):
  190.       playAudio(neutronizedTrack, playing);
  191.       break;
  192.     case (7):
  193.       playAudio(toolsTrack, playing);
  194.       break;
  195.     default:
  196.       playAudio(endTrack, playing);
  197.       break;
  198.   }
  199. }
  200.  
  201. /* ************* Main Loop ************* */
  202. int cyclotronRunningFadeOut = 255;  // we reset this variable every time we change the cyclotron index so the fade effect works
  203. int cyclotronRunningFadeIn = 0;     // we reset this to 0 to fade the cyclotron in from nothing
  204.  
  205. // intervals that can be adjusted in real time to speed up animations
  206. unsigned long pwr_interval = 60;        // interval at which to cycle lights for the powercell. We update this in the loop to speed up the animation so must be declared here (milliseconds)
  207. unsigned long cyc_interval = 1000;      // interval at which to cycle lights for the cyclotron.
  208. unsigned long cyc_fade_interval = 15;   // fade the inactive cyclotron to light to nothing
  209. unsigned long firing_interval = 40;     // interval at which to cycle firing lights on the bargraph. We update this in the loop to speed up the animation so must be declared here (milliseconds).
  210.  
  211. void loop() {
  212.   // get the current time
  213.   unsigned long currentMillis = millis();
  214.  
  215.   // find out of the audio board is playing audio
  216.   int playing = digitalRead(ACT);
  217.  
  218.   // get the current switch states
  219.   int theme_switch = digitalRead(THEME_SWITCH);
  220.  
  221.   // if the theme switch has recently changed from off to on we
  222.   // should play the full ghostbusters theme song
  223.   if (theme_switch == 1) {
  224.     if (theme == false) {
  225.       playAudio(themeTrack, playing);
  226.       theme = true;
  227.     }
  228.   } else {
  229.     theme = false;
  230.   }
  231.  
  232.   int startup_switch = digitalRead(STARTUP_SWITCH);
  233.   int safety_switch = digitalRead(SAFETY_SWITCH);
  234.   int fire_button = digitalRead(FIRE_BUTTON);
  235.  
  236.   // while the startup switch is set on
  237.   if (startup_switch == 1) {  
  238.     // in general we always try to play the idle sound if started
  239.     if (playing == 1 && startup == true) {
  240.       playAudio(idleTrack, playing);
  241.     }
  242.    
  243.     // choose the right powercell animation sequence for booted/on
  244.     if ( powerBooted == true ) {
  245.       // standard idle power sequence for the pack
  246.       poweredDown = false;
  247.       shuttingDown = false;
  248.       venting = false;
  249.       setWandLightState(3, 0, 0); //set sloblow red
  250.       setVentLightState(ventStart, ventEnd, 2);
  251.       powerSequenceOne(currentMillis, pwr_interval, cyc_interval, cyc_fade_interval);
  252.     } else {
  253.       // boot up the pack. powerSequenceBoot will set powerBooted when complete
  254.       powerSequenceBoot(currentMillis);
  255.       setWandLightState(3, 7, currentMillis);   //set sloblow red blinking
  256.     }
  257.  
  258.     // if we are not started up we should play the startup sound and begin the boot sequence
  259.     if (startup == false) {
  260.       startup = true;
  261.       playAudio(startupTrack, playing);
  262.  
  263.       // get the current safety switch state
  264.       if (safety_switch == 1 && safety == false) {
  265.         safety = true;
  266.       }
  267.     }
  268.    
  269.     if( startup == true && safety_switch == 1 ){
  270.       if( venting == false && powerBooted == true ){
  271.         setWandLightState(1, 2, 0);    //  set back light orange
  272.         setWandLightState(2, 1, 0);    //  set body led white
  273.       }else{
  274.         setWandLightState(1, 4, 0);    //  set back light off
  275.         setWandLightState(2, 4, 0);    //  set body led off
  276.       }
  277.  
  278.       // if the safety switch is set off then we can fire when the button is pressed
  279.       if ( fire_button == 0) {
  280.         // if the button is just pressed we clear all led's to start the firing animations
  281.         if ( isFiring == false ) {
  282.           shutdown_leds();
  283.           isFiring = true;
  284.         }
  285.  
  286.         // show the firing bargraph sequence
  287.         barGraphSequenceTwo(currentMillis);
  288.  
  289.         // strobe the nose pixels
  290.         fireStrobe(currentMillis);
  291.  
  292.         // now powercell/cyclotron/wand lights
  293.         // if this is the first time reset some variables and play the blast track
  294.         if (fire == false) {
  295.           shouldWarn = false;
  296.           fire = true;
  297.           firingStateMillis = millis();
  298.           playAudio(blastTrack, playing);
  299.         } else {
  300.           // find out what our timing is
  301.           unsigned long diff = (unsigned long)(millis() - firingStateMillis);
  302.          
  303.           if ( diff > firingWarnWaitTime) { // if we are in the fire warn interval
  304.             pwr_interval = 10;      // speed up the powercell animation
  305.             firing_interval = 20;   // speed up the bar graph animation
  306.             cyc_interval = 50;      // really speed up cyclotron
  307.             cyc_fade_interval = 5;  // speed up the fade of the cyclotron
  308.             if (playing == 1 || shouldWarn == false ) {
  309.               shouldWarn = true;
  310.               playAudio(warnTrack, playing); // play the firing track with the warning
  311.             }
  312.             setWandLightState(0, 8, currentMillis);    // set top light red flashing fast
  313.           } else if ( diff > firingWarmWaitTime) { // if we are in the dialog playing interval
  314.             pwr_interval = 30;      // speed up the powercell animation
  315.             firing_interval = 30;   // speed up the bar graph animation
  316.             cyc_interval = 200;     // speed up cyclotron
  317.             cyc_fade_interval = 10; // speed up the fade of the cyclotron
  318.             if (playing == 1) {
  319.               playAudio(blastTrack, playing); // play the normal blast track
  320.             }
  321.             setWandLightState(0, 6, currentMillis);    // set top light orange flashing
  322.           }
  323.         }
  324.       } else { // if we were firing and are no longer reset the leds
  325.         if ( isFiring == true ) {
  326.           shutdown_leds();
  327.           isFiring = false;
  328.         }
  329.  
  330.         // and do the standard bargraph sequence
  331.         barGraphSequenceOne(currentMillis);
  332.  
  333.         if (fire == true) { // if we were firing let's reset the animations and play the correct final firing track
  334.           clearFireStrobe();
  335.           setWandLightState(0, 4, currentMillis);    // set top light off
  336.          
  337.           pwr_interval = 60;
  338.           firing_interval = 40;
  339.           cyc_interval = 1000;
  340.           cyc_fade_interval = 15;
  341.           fire = false;
  342.  
  343.           // see if we've been firing long enough to get the dialog or vent sounds
  344.           unsigned long diff = (unsigned long)(millis() - firingStateMillis);
  345.  
  346.           if ( diff > firingWarnWaitTime) { // if we are past the warning let's vent the pack
  347.             playAudio(ventTrack, playing);
  348.             venting = true;
  349.             clearPowerStrip(); // play the boot animation on the powercell
  350.           } else if ( diff > firingWarmWaitTime) { // if in the dialog time play the dialog in sequence
  351.             if( useDialogTracks == true ){
  352.               playDialogTrack(playing);
  353.             }else{
  354.               playAudio(endTrack, playing);
  355.             }
  356.           } else {
  357.             playAudio(endTrack, playing);
  358.           }
  359.         }
  360.       }
  361.  
  362.       // if the safety was just changed play the click track
  363.       if (safety == false) {
  364.         safety = true;
  365.         playAudio(chargeTrack, playing);
  366.       }
  367.     } else {
  368.       // if the safety is switched off play the click track
  369.       if (safety == true) {
  370.         setWandLightState(1, 4, 0);    // set back light off
  371.         setWandLightState(2, 4, 0);    // set body off
  372.         safety = false;
  373.         playAudio(clickTrack, playing);
  374.       }
  375.     }
  376.   } else { // if we are powering down
  377.     if( poweredDown == false ){
  378.       if( shuttingDown == false ){
  379.         playAudio(shutdownTrack, playing); // play the pack shutdown track
  380.         shuttingDown = true;
  381.       }
  382.       cyclotronRunningFadeOut = 255;
  383.       powerSequenceShutdown(currentMillis);
  384.     }else{
  385.       if (startup == true) { // if started reset the variables
  386.         clearPowerStrip(); // clear all led's
  387.         shutdown_leds();
  388.         startup = false;
  389.         safety = false;
  390.         fire = false;
  391.       }
  392.     }
  393.   }
  394.   delay(1);
  395. }
  396.  
  397. /*************** Wand Light Helpers *********************/
  398. unsigned long prevFlashMillis = 0; // last time we changed a powercell light in the idle sequence
  399. bool flashState = false;
  400. const unsigned long wandFastFlashInterval = 100; // interval at which we flash the top led on the wand
  401. const unsigned long wandMediumFlashInterval = 500; // interval at which we flash the top led on the wand
  402.  
  403. void setWandLightState(int lednum, int state, unsigned long currentMillis){
  404.   switch ( state ) {
  405.     case 0: // set led red
  406.       wandLights.setPixelColor(lednum, wandLights.Color(255, 0, 0));
  407.       break;
  408.     case 1: // set led white
  409.       wandLights.setPixelColor(lednum, wandLights.Color(255, 255, 255));
  410.       break;
  411.     case 2: // set led orange
  412.       wandLights.setPixelColor(lednum, wandLights.Color(255, 127, 0));
  413.       break;
  414.     case 3: // set led blue
  415.       wandLights.setPixelColor(lednum, wandLights.Color(0, 0, 255));
  416.       break;
  417.     case 4: // set led off
  418.       wandLights.setPixelColor(lednum, 0);
  419.       break;
  420.     case 5: // fast white flashing    
  421.       if ((unsigned long)(currentMillis - prevFlashMillis) >= wandFastFlashInterval) {    
  422.         prevFlashMillis = currentMillis;    
  423.         if( flashState == false ){    
  424.           wandLights.setPixelColor(lednum, wandLights.Color(255, 255, 255));    
  425.           flashState = true;    
  426.         }else{    
  427.           wandLights.setPixelColor(lednum, 0);    
  428.           flashState = false;  
  429.         }  
  430.       }  
  431.       break;
  432.     case 6: // slower orange flashing    
  433.       if ((unsigned long)(currentMillis - prevFlashMillis) >= wandMediumFlashInterval) {    
  434.         prevFlashMillis = currentMillis;    
  435.         if( flashState == false ){    
  436.           wandLights.setPixelColor(lednum, wandLights.Color(255, 127, 0));    
  437.           flashState = true;    
  438.         }else{    
  439.           wandLights.setPixelColor(lednum, 0);    
  440.           flashState = false;  
  441.         }  
  442.       }  
  443.       break;
  444.     case 7: // medium red flashing    
  445.       if ((unsigned long)(currentMillis - prevFlashMillis) >= wandMediumFlashInterval) {    
  446.         prevFlashMillis = currentMillis;    
  447.         if( flashState == false ){    
  448.           wandLights.setPixelColor(lednum, wandLights.Color(255, 0, 0));    
  449.           flashState = true;    
  450.         }else{    
  451.           wandLights.setPixelColor(lednum, 0);    
  452.           flashState = false;  
  453.         }  
  454.       }  
  455.       break;
  456.     case 8: // fast red flashing    
  457.       if ((unsigned long)(currentMillis - prevFlashMillis) >= wandFastFlashInterval) {    
  458.         prevFlashMillis = currentMillis;    
  459.         if( flashState == false ){    
  460.           wandLights.setPixelColor(lednum, wandLights.Color(255, 0, 0));    
  461.           flashState = true;    
  462.         }else{    
  463.           wandLights.setPixelColor(lednum, 0);    
  464.           flashState = false;  
  465.         }  
  466.       }  
  467.       break;
  468.   }
  469.  
  470.   wandLights.show();
  471. }
  472.  
  473.  
  474.  
  475. /*************** Vent Light *************************/
  476. void setVentLightState(int startLed, int endLed, int state ) {
  477.   switch ( state ) {
  478.     case 0: // set all leds to white
  479.       for (int i = startLed; i <= endLed; i++) {
  480.         powerStick.setPixelColor(i, powerStick.Color(255, 255, 255));
  481.       }
  482.       // Set the relay to on while venting. If relay is off set the pin LOW
  483.       digitalWrite (relayPin, HIGH);
  484.      
  485.       break;
  486.      
  487.     case 1: // set all leds to blue
  488.       for (int i = startLed; i <= endLed; i++) {
  489.         powerStick.setPixelColor(i, powerStick.Color(0, 0, 255));
  490.       }
  491.       // Set the relay to on while venting. If relay is off set the pin LOW
  492.       digitalWrite (relayPin, HIGH);
  493.       break;
  494.     case 2: // set all leds off
  495.       for (int i = startLed; i <= endLed; i++) {
  496.         powerStick.setPixelColor(i, 0);
  497.       }
  498.       // Set the relay to OFF while not venting. If relay is onf set the pin HIGH
  499.       digitalWrite (relayPin, LOW);
  500.       break;
  501.   }
  502. }
  503.  
  504. /*************** Powercell/Cyclotron Animations *********************/
  505. // timer helpers and intervals for the animations
  506. unsigned long prevPwrBootMillis = 0;    // the last time we changed a powercell light in the boot sequence
  507. const unsigned long pwr_boot_interval = 60;       // interval at which to cycle lights (milliseconds). Adjust this if
  508.  
  509. unsigned long prevCycBootMillis = 0;    // the last time we changed a cyclotron light in the boot sequence
  510. const unsigned long cyc_boot_interval = 500;      // interval at which to cycle lights (milliseconds).
  511. const unsigned long cyc_boot_alt_interval = 600;      // interval at which to cycle lights (milliseconds).
  512.  
  513. unsigned long prevShtdMillis = 0;       // last time we changed a light in the idle sequence
  514. const unsigned long pwr_shutdown_interval = 200;  // interval at which to cycle lights (milliseconds).
  515.  
  516. unsigned long prevPwrMillis = 0;        // last time we changed a powercell light in the idle sequence
  517. unsigned long prevCycMillis = 0;        // last time we changed a cyclotron light in the idle sequence
  518. unsigned long prevFadeCycMillis = 0;    // last time we changed a cyclotron light in the idle sequence
  519.  
  520. // LED tracking variables
  521. const int powerSeqTotal = powercellLedCount;                              // total number of led's for powercell 0 based
  522. int powerSeqNum = powercellIndexOffset;                                   // current running powercell sequence led
  523. int powerShutdownSeqNum = powercellLedCount - powercellIndexOffset;       // shutdown sequence counts down
  524.  
  525. // animation level trackers for the boot and shutdown
  526. int currentBootLevel = powercellIndexOffset;                              // current powercell boot level sequence led
  527. int currentLightLevel = powercellLedCount - powercellIndexOffset;         // current powercell boot light sequence led
  528.  
  529. void setCyclotronLightState(int startLed, int endLed, int state ){
  530.   switch ( state ) {
  531.     case 0: // set all leds to red
  532.       for(int i=startLed; i <= endLed; i++) {
  533.         powerStick.setPixelColor(i, powerStick.Color(255, 0, 0));
  534.       }
  535.       break;
  536.     case 1: // set all leds to orange
  537.       for(int i=startLed; i <= endLed; i++) {
  538.         powerStick.setPixelColor(i, powerStick.Color(255, 106, 0));
  539.       }
  540.       break;
  541.     case 2: // set all leds off
  542.       for(int i=startLed; i <= endLed; i++) {
  543.         powerStick.setPixelColor(i, 0);
  544.       }
  545.       break;
  546.     case 3: // fade all leds from red
  547.       for(int i=startLed; i <= endLed; i++) {
  548.         if( cyclotronRunningFadeOut >= 0 ){
  549.           powerStick.setPixelColor(i, 255 * cyclotronRunningFadeOut/255, 0, 0);
  550.           cyclotronRunningFadeOut--;
  551.         }else{
  552.           powerStick.setPixelColor(i, 0);
  553.         }
  554.       }
  555.       break;
  556.     case 4: // fade all leds to red
  557.       for(int i=startLed; i <= endLed; i++) {
  558.         if( cyclotronRunningFadeIn < 255 ){
  559.           powerStick.setPixelColor(i, 255 * cyclotronRunningFadeIn/255, 0, 0);
  560.           cyclotronRunningFadeIn++;
  561.         }else{
  562.           powerStick.setPixelColor(i, powerStick.Color(255, 0, 0));
  563.         }
  564.       }
  565.       break;
  566.   }
  567. }
  568.  
  569. // shuts off and resets the powercell/cyclotron leds
  570. void clearPowerStrip() {
  571.   // reset vars
  572.   powerBooted = false;
  573.   poweredDown = true;
  574.   powerSeqNum = powercellIndexOffset;
  575.   powerShutdownSeqNum = powercellLedCount - powercellIndexOffset;
  576.   currentLightLevel = powercellLedCount;
  577.   currentBootLevel = powercellIndexOffset;
  578.   cyclotronRunningFadeIn = 0;
  579.  
  580.   // shutoff the leds
  581.   for ( int i = 0; i <= c4End; i++) {
  582.     powerStick.setPixelColor(i, 0);
  583.   }
  584.   powerStick.show();
  585.  
  586.   for ( int j=0; j<=3; j++ ){
  587.     wandLights.setPixelColor(j, 0);
  588.   }
  589.   wandLights.show();
  590.  
  591.   if( venting == true ){
  592.     setVentLightState(ventStart, ventEnd, 0);
  593.   }
  594. }
  595.  
  596. // boot animation on the powercell/cyclotron
  597. bool reverseBootCyclotron = false;
  598. void powerSequenceBoot(unsigned long currentMillis) {
  599.   bool doUpdate = false;
  600.  
  601.   // START CYCLOTRON
  602.   if( useCyclotronFadeInEffect == false ){
  603.     if ((unsigned long)(currentMillis - prevCycBootMillis) >= cyc_boot_interval) {
  604.       prevCycBootMillis = currentMillis;
  605.  
  606.       if( reverseBootCyclotron == false ){
  607.         setCyclotronLightState(c1Start, c1End, 1);
  608.         setCyclotronLightState(c2Start, c2End, 2);
  609.         setCyclotronLightState(c3Start, c3End, 1);
  610.         setCyclotronLightState(c4Start, c4End, 2);
  611.        
  612.         doUpdate = true;
  613.         reverseBootCyclotron = true;
  614.       }else{
  615.         setCyclotronLightState(c1Start, c1End, 2);
  616.         setCyclotronLightState(c2Start, c2End, 1);
  617.         setCyclotronLightState(c3Start, c3End, 2);
  618.         setCyclotronLightState(c4Start, c4End, 1);
  619.        
  620.         doUpdate = true;
  621.         reverseBootCyclotron = false;
  622.       }
  623.     }
  624.   }else{
  625.     if ((unsigned long)(currentMillis - prevCycBootMillis) >= cyc_boot_alt_interval) {
  626.       prevCycBootMillis = currentMillis;
  627.       setCyclotronLightState(c1Start, c4End, 4);
  628.       doUpdate = true;
  629.     }
  630.   }
  631.   // END CYCLOTRON
  632.  
  633.   if ((unsigned long)(currentMillis - prevPwrBootMillis) >= pwr_boot_interval) {
  634.     // save the last time you blinked the LED
  635.     prevPwrBootMillis = currentMillis;
  636.  
  637.     // START POWERCELL
  638.     if( currentBootLevel != powerSeqTotal ){
  639.       if( currentBootLevel == currentLightLevel){
  640.         if(currentLightLevel+1 <= powerSeqTotal){
  641.           powerStick.setPixelColor(currentLightLevel+1, 0);
  642.         }
  643.         powerStick.setPixelColor(currentBootLevel, powerStick.Color(0, 0, 255));
  644.         currentLightLevel = powerSeqTotal;
  645.         currentBootLevel++;
  646.       }else{
  647.         if(currentLightLevel+1 <= powerSeqTotal){
  648.           powerStick.setPixelColor(currentLightLevel+1, 0);
  649.         }
  650.         powerStick.setPixelColor(currentLightLevel, powerStick.Color(0, 0, 255));
  651.         currentLightLevel--;
  652.       }
  653.       doUpdate = true;
  654.     }else{
  655.       powerBooted = true;
  656.       currentBootLevel = powercellIndexOffset;
  657.       currentLightLevel = powercellLedCount - powercellIndexOffset;
  658.     }
  659.     // END POWERCELL
  660.   }
  661.  
  662.   // if we have changed an led
  663.   if( doUpdate == true ){
  664.     powerStick.show(); // commit all of the changes
  665.   }
  666. }
  667.  
  668. // idle/firing animation for the powercell/cyclotron
  669. int cycOrder = 0;     // which cyclotron led will be lit next
  670. int cycFading = -1;   // which cyclotron led is fading out for game style
  671. void powerSequenceOne(unsigned long currentMillis, unsigned long anispeed, unsigned long cycspeed, unsigned long cycfadespeed) {
  672.   bool doUpdate = false;  // keep track of if we changed something so we only update on changes
  673.  
  674.   // START CYCLOTRON
  675.   if( useGameCyclotronEffect == true ){ // if we are doing the video game style cyclotron
  676.     if ((unsigned long)(currentMillis - prevCycMillis) >= cycspeed) {
  677.       prevCycMillis = currentMillis;
  678.      
  679.       switch ( cycOrder ) {
  680.         case 0:
  681.           setCyclotronLightState(c1Start, c1End, 0);
  682.           setCyclotronLightState(c2Start, c2End, 2);
  683.           setCyclotronLightState(c3Start, c3End, 2);
  684.           cycFading = 0;
  685.           cyclotronRunningFadeOut = 255;
  686.           cycOrder = 1;
  687.           break;
  688.         case 1:
  689.           setCyclotronLightState(c2Start, c2End, 0);
  690.           setCyclotronLightState(c3Start, c3End, 2);
  691.           setCyclotronLightState(c4Start, c4End, 2);
  692.           cycFading = 1;
  693.           cyclotronRunningFadeOut = 255;
  694.           cycOrder = 2;
  695.           break;
  696.         case 2:
  697.           setCyclotronLightState(c1Start, c1End, 2);
  698.           setCyclotronLightState(c3Start, c3End, 0);
  699.           setCyclotronLightState(c4Start, c4End, 2);
  700.           cycFading = 2;
  701.           cyclotronRunningFadeOut = 255;
  702.           cycOrder = 3;
  703.           break;
  704.         case 3:
  705.           setCyclotronLightState(c1Start, c1End, 2);
  706.           setCyclotronLightState(c2Start, c2End, 2);
  707.           setCyclotronLightState(c4Start, c4End, 0);
  708.           cycFading = 3;
  709.           cyclotronRunningFadeOut = 255;
  710.           cycOrder = 0;
  711.           break;
  712.       }
  713.  
  714.       doUpdate = true;
  715.     }
  716.  
  717.     // now figure out the fading light
  718.     if( (unsigned long)( currentMillis - prevFadeCycMillis) >= cycfadespeed ){
  719.       prevFadeCycMillis = currentMillis;
  720.       if( cycFading != -1 ){
  721.         switch ( cycFading ) {
  722.           case 0:
  723.             setCyclotronLightState(c4Start, c4End, 3);
  724.             break;
  725.           case 1:
  726.             setCyclotronLightState(c1Start, c1End, 3);
  727.             break;
  728.           case 2:
  729.             setCyclotronLightState(c2Start, c2End, 3);
  730.             break;
  731.           case 3:
  732.             setCyclotronLightState(c3Start, c3End, 3);
  733.             break;
  734.         }
  735.         doUpdate = true;
  736.       }
  737.     }
  738.   }else{ // otherwise this is the standard version
  739.     if ((unsigned long)(currentMillis - prevCycMillis) >= cycspeed) {
  740.       prevCycMillis = currentMillis;
  741.      
  742.       switch ( cycOrder ) {
  743.         case 0:
  744.           setCyclotronLightState(c4Start, c4End, 2);
  745.           setCyclotronLightState(c1Start, c1End, 0);
  746.           setCyclotronLightState(c2Start, c2End, 2);
  747.           setCyclotronLightState(c3Start, c3End, 2);
  748.           cycFading = 0;
  749.           cyclotronRunningFadeOut = 255;
  750.           cycOrder = 1;
  751.           break;
  752.         case 1:
  753.           setCyclotronLightState(c1Start, c1End, 2);
  754.           setCyclotronLightState(c2Start, c2End, 0);
  755.           setCyclotronLightState(c3Start, c3End, 2);
  756.           setCyclotronLightState(c4Start, c4End, 2);
  757.           cycFading = 1;
  758.           cyclotronRunningFadeOut = 255;
  759.           cycOrder = 2;
  760.           break;
  761.         case 2:
  762.           setCyclotronLightState(c1Start, c1End, 2);
  763.           setCyclotronLightState(c2Start, c2End, 2);
  764.           setCyclotronLightState(c3Start, c3End, 0);
  765.           setCyclotronLightState(c4Start, c4End, 2);
  766.           cycFading = 2;
  767.           cyclotronRunningFadeOut = 255;
  768.           cycOrder = 3;
  769.           break;
  770.         case 3:
  771.           setCyclotronLightState(c1Start, c1End, 2);
  772.           setCyclotronLightState(c2Start, c2End, 2);
  773.           setCyclotronLightState(c3Start, c3End, 2);
  774.           setCyclotronLightState(c4Start, c4End, 0);
  775.           cycFading = 3;
  776.           cyclotronRunningFadeOut = 255;
  777.           cycOrder = 0;
  778.           break;
  779.       }
  780.  
  781.       doUpdate = true;
  782.     }
  783.   }
  784.   // END CYCLOTRON
  785.  
  786.   // START POWERCELL
  787.   if ((unsigned long)(currentMillis - prevPwrMillis) >= anispeed) {
  788.     // save the last time you blinked the LED
  789.     prevPwrMillis = currentMillis;
  790.  
  791.     for ( int i = powercellIndexOffset; i <= powerSeqTotal; i++) {
  792.       if ( i <= powerSeqNum ) {
  793.         powerStick.setPixelColor(i, powerStick.Color(0, 0, 150));
  794.       } else {
  795.         powerStick.setPixelColor(i, 0);
  796.       }
  797.     }
  798.    
  799.     if ( powerSeqNum <= powerSeqTotal) {
  800.       powerSeqNum++;
  801.     } else {
  802.       powerSeqNum = powercellIndexOffset;
  803.     }
  804.  
  805.     doUpdate = true;
  806.   }
  807.   // END POWERCELL
  808.  
  809.   // if we changed anything update
  810.   if( doUpdate == true ){
  811.     powerStick.show();
  812.   }
  813. }
  814.  
  815. // shutdown animation for the powercell/cyclotron
  816. int cyclotronFadeOut = 255;
  817. void powerSequenceShutdown(unsigned long currentMillis) {
  818.   if ((unsigned long)(currentMillis - prevShtdMillis) >= pwr_shutdown_interval) {
  819.     prevShtdMillis = currentMillis;
  820.  
  821.     // START CYCLOTRON
  822.     for(int i=c1Start; i <= c4End; i++) {
  823.       if( cyclotronFadeOut >= 0 ){
  824.         powerStick.setPixelColor(i, 255 * cyclotronFadeOut/255, 0, 0);
  825.         cyclotronFadeOut--;
  826.       }else{
  827.         powerStick.setPixelColor(i, 0);
  828.       }
  829.     }
  830.     // END CYCLOTRON
  831.    
  832.     // START POWERCELL
  833.     for ( int i = powerSeqTotal; i >= powercellIndexOffset; i--) {
  834.       if ( i <= powerShutdownSeqNum ) {
  835.         powerStick.setPixelColor(i, powerStick.Color(0, 0, 150));
  836.       } else {
  837.         powerStick.setPixelColor(i, 0);
  838.       }
  839.     }
  840.    
  841.     powerStick.show();
  842.    
  843.     if ( powerShutdownSeqNum >= powercellIndexOffset) {
  844.       powerShutdownSeqNum--;
  845.     } else {
  846.       poweredDown = true;
  847.       powerShutdownSeqNum = powercellLedCount - powercellIndexOffset;
  848.       cyclotronFadeOut = 255;
  849.     }
  850.     // END POWERCELL
  851.   }
  852. }
  853.  
  854. /*************** Nose Jewel Firing Animations *********************/
  855. unsigned long prevFireMillis = 0;
  856. const unsigned long fire_interval = 50;     // interval at which to cycle lights (milliseconds).
  857. int fireSeqNum = 0;
  858. int fireSeqTotal = 5;
  859.  
  860. void clearFireStrobe() {
  861.   for ( int i = 0; i < 7; i++) {
  862.     noseJewel.setPixelColor(i, 0);
  863.   }
  864.   noseJewel.show();
  865.   fireSeqNum = 0;
  866. }
  867.  
  868. void fireStrobe(unsigned long currentMillis) {
  869.   if ((unsigned long)(currentMillis - prevFireMillis) >= fire_interval) {
  870.     prevFireMillis = currentMillis;
  871.    
  872.     switch ( fireSeqNum ) {
  873.       case 0:
  874.         noseJewel.setPixelColor(0, noseJewel.Color(255, 255, 255));
  875.         noseJewel.setPixelColor(1, noseJewel.Color(255, 255, 255));
  876.         noseJewel.setPixelColor(2, 0);
  877.         noseJewel.setPixelColor(3, noseJewel.Color(255, 255, 255));
  878.         noseJewel.setPixelColor(4, 0);
  879.         noseJewel.setPixelColor(5, noseJewel.Color(255, 255, 255));
  880.         noseJewel.setPixelColor(6, 0);
  881.         break;
  882.       case 1:
  883.         noseJewel.setPixelColor(0, noseJewel.Color(0, 0, 255));
  884.         noseJewel.setPixelColor(1, noseJewel.Color(255, 0, 0));
  885.         noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
  886.         noseJewel.setPixelColor(3, noseJewel.Color(255, 0, 0));
  887.         noseJewel.setPixelColor(4, noseJewel.Color(255, 255, 255));
  888.         noseJewel.setPixelColor(5, noseJewel.Color(255, 0, 0));
  889.         noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
  890.         break;
  891.       case 2:
  892.         noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 0));
  893.         noseJewel.setPixelColor(1, 0);
  894.         noseJewel.setPixelColor(2, noseJewel.Color(0, 0, 255));
  895.         noseJewel.setPixelColor(3, 0);
  896.         noseJewel.setPixelColor(4, noseJewel.Color(0, 0, 255));
  897.         noseJewel.setPixelColor(5, 0);
  898.         noseJewel.setPixelColor(6, noseJewel.Color(255, 0, 0));
  899.         break;
  900.       case 3:
  901.         noseJewel.setPixelColor(0, noseJewel.Color(0, 0, 255));
  902.         noseJewel.setPixelColor(1, noseJewel.Color(255, 0, 0));
  903.         noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
  904.         noseJewel.setPixelColor(3, noseJewel.Color(255, 0, 0));
  905.         noseJewel.setPixelColor(4, noseJewel.Color(255, 255, 255));
  906.         noseJewel.setPixelColor(5, noseJewel.Color(255, 0, 0));
  907.         noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
  908.         break;
  909.       case 4:
  910.         noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 0));
  911.         noseJewel.setPixelColor(1, 0);
  912.         noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
  913.         noseJewel.setPixelColor(3, 0);
  914.         noseJewel.setPixelColor(4, noseJewel.Color(255, 0, 0));
  915.         noseJewel.setPixelColor(5, 0);
  916.         noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
  917.         break;
  918.       case 5:
  919.         noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 255));
  920.         noseJewel.setPixelColor(1, noseJewel.Color(0, 255, 0));
  921.         noseJewel.setPixelColor(2, noseJewel.Color(255, 0, 0));
  922.         noseJewel.setPixelColor(3, noseJewel.Color(0, 0, 255));
  923.         noseJewel.setPixelColor(4, noseJewel.Color(255, 0, 255));
  924.         noseJewel.setPixelColor(5, noseJewel.Color(255, 255, 255));
  925.         noseJewel.setPixelColor(6, noseJewel.Color(0, 0, 255));
  926.         break;
  927.     }
  928.  
  929.     noseJewel.show();
  930.  
  931.     fireSeqNum++;
  932.     if ( fireSeqNum > fireSeqTotal ) {
  933.       fireSeqNum = 0;
  934.     }
  935.   }
  936. }
  937.  
  938. /*************** Bar Graph Animations *********************/
  939. void shutdown_leds() {
  940.   // stub function for when I re-enable to bargraph
  941. }
  942. void barGraphSequenceOne(unsigned long currentMillis) {
  943.   // stub function for when I re-enable to bargraph
  944. }
  945. void barGraphSequenceTwo(unsigned long currentMillis) {
  946.   // stub function for when I re-enable to bargraph
  947. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement