Advertisement
ezdiver67

L3D Cube demo with Valentine

Jan 27th, 2015
3,014
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
SPARK 26.12 KB | None | 0 0
  1. // This #include statement was automatically added by the Spark IDE.
  2. #include "neopixel/neopixel.h"
  3.  
  4. /*L3D demo code - EZU added Valentine's'*/
  5. #include <math.h>
  6. //set up the pin that controls the LEDs, the type of LEDs (WS2812B) and the number of LEDs in the cube (8*8*8=512)
  7. #define PIXEL_PIN D0
  8. #define PIXEL_COUNT 512
  9. #define PIXEL_TYPE WS2812B
  10. #define SIDE 8
  11. SYSTEM_MODE(SEMI_AUTOMATIC); //don't connect to the internet on boot
  12. #define BUTTON D2 //press this button to connect to the internet
  13. #define MODE D3
  14. #define MICROPHONE 12
  15. #define GAIN_CONTROL 11
  16. #define MAX_POINTS 20
  17. #define SPEED 0.22
  18. #define MIN_SALVO_SPACING 100
  19. bool onlinePressed=false;
  20. bool lastOnline=true;
  21. #define FIREWORKS 0
  22. #define PLASMA 1
  23. #define SQUARRAL 2
  24. #define PURPLE_RAIN 3
  25. #define VALENTINE 4
  26. #define DEMO_ROUTINES 5
  27.  
  28.  
  29. /* datatype definitions
  30. */
  31. typedef struct{
  32.     unsigned char red, green, blue;
  33. } color;
  34.  
  35. typedef struct{
  36.     float x;
  37.     float y;
  38.     float z;
  39. } point;
  40.  
  41. typedef struct{
  42.     point raindrops[MAX_POINTS];
  43.     bool dead;
  44. } salvo;
  45.  
  46. /******************************
  47. * function definitions
  48. * ***************************/
  49. void background(color col);
  50. color getPixel(int x, int y, int z);
  51. void setPixel(int x, int y, int z, color col);
  52. color colorMap(float val, float min, float max);
  53. color lerpColor(color a, color b, int val, int min, int max);
  54. void add(point& a, point& b);
  55. /******************************
  56. *  Valentine's definitions
  57. *******************************/
  58. /* For now just draw a simple red heart in the center */
  59.  
  60. float vRotAngle = 0.0;
  61.  
  62. /******************************
  63. * fireworks variables *
  64. * ****************************/
  65. color black;
  66. int centerX, centerY, centerZ;
  67. int launchX, launchZ;
  68. int red, green, blue;
  69. int brightness=35;
  70. float radius=0;
  71. float speed;
  72. bool showRocket;
  73. bool exploded;
  74. float xInc, yInc, zInc;
  75. float rocketX, rocketY, rocketZ;
  76. float launchTime;
  77. int maxSize;
  78. color rocketColor, fireworkColor;
  79. /*********************************
  80. * squarral variables *
  81. * ******************************/
  82. #define TRAIL_LENGTH 50
  83. int frame=0;
  84. color pixelColor;
  85. point position, increment, pixel;
  86. point trailPoints[TRAIL_LENGTH];
  87. int posX, posY, posZ;
  88. int incX, incY, incZ;
  89. int squarral_zInc=1;
  90. int bound=0;
  91. int boundInc=1;
  92. unsigned char axis=0;
  93. bool rainbow=true;
  94. //maxBrightness is the brightness limit for each pixel. All color data will be scaled down
  95. //so that the largest value is maxBrightness
  96. int maxBrightness=50;
  97. /********************************
  98. * zplasma variables *
  99. * *****************************/
  100. float phase = 0.0;
  101. float phaseIncrement = 0.035; // Controls the speed of the moving points. Higher == faster
  102. float colorStretch = 0.23; // Higher numbers will produce tighter color bands
  103. float plasmaBrightness = 0.2;
  104. color plasmaColor;
  105. /*********************************
  106. * purple rain variables *
  107. * *******************************/
  108. int threshhold;
  109. int max=-1;
  110. int min=10000;
  111. float sensitivity=0.5;
  112. int maxAmplitude=0;
  113. bool aboveThreshhold=false;
  114. int timeAboveThreshhold;
  115. color rainColor;
  116. salvo salvos[SIDE];
  117. /**********************************
  118. * flip variables *
  119. * ********************************/
  120. //accelerometer pinout
  121. #define X 13
  122. #define Y 14
  123. #define Z 15
  124. #define AUTOCYCLE_TIME 30000
  125. #define FACEPLANT 2300
  126. #define UPSIDE_DOWN 1850
  127. #define RIGHTSIDE_UP 2400
  128. #define LEFT_SIDE 1800
  129. #define RIGHT_SIDE 2400
  130. #define FLIP_TIMEOUT 3000
  131. #define FLIP_DEBOUNCE 250
  132. long lastFaceplant=-1*FLIP_TIMEOUT;
  133. bool upsideDown=false;
  134. bool sideways=false;
  135. bool autoCycle=true; //start on autocycle by default
  136. int upsideDownTime=-1*FLIP_TIMEOUT;
  137. long lastAutoCycle=0;
  138. int lastLeft=-1*FLIP_TIMEOUT;
  139. int lastRight=-1*FLIP_TIMEOUT;
  140. int accelerometer[3];
  141. long lastChange=0;
  142. int demo=FIREWORKS;
  143. Adafruit_NeoPixel strip=Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
  144. int frameCount=0;
  145. /*******************************
  146. * fade variables *
  147. * ****************************/
  148. bool fading=false;
  149. int fadeValue=255;
  150. int fadeSpeed=2;
  151.  
  152. void setup() {
  153.     pinMode(7,OUTPUT);
  154.     digitalWrite(7, HIGH);
  155.     // seed the random number generator. THINGS WILL NEVER BE THE SAME AGAIN
  156.     uint32_t seed = millis();
  157.     srand(seed);
  158.     // Serial.begin(115200);
  159.     initCube();
  160.     initCloudButton();
  161.     initSquarral();
  162.     initFireworks();
  163.     initMicrophone();
  164.     initSalvos();
  165.     initValentine();
  166. }
  167.  
  168. void initValentine()
  169. {
  170. }
  171.  
  172. float heartColor(int x, int z, int y)
  173. {
  174.     // translate the coordinates from 0..7 to -2..+2 range
  175.     float vX=abs((float)x-3.5)/1.8;
  176.     float vY=((float)y-3.5)*1.8; // y is squished by a factor 3
  177.     float vZ=(3.5-(float)z)/1.8;
  178.  
  179.     // Rotate 45degrees around Y axis to create a heart
  180.     float hX= vX * 0.7071 - vZ * 0.7071; //vX*cos(theta) - vZ*sin(theta);
  181.     float hY= vY;
  182.     float hZ= vX * 0.7071 + vZ * 0.7071; //vX * sin(theta) + vZ*cos(theta);
  183.  
  184.     // Let's give it some heartbeat :-)
  185.     float rX= hX;
  186.     float rY= hY * cos(vRotAngle) - hZ * sin(vRotAngle);
  187.     float rZ= hZ * sin(vRotAngle) + hY * cos(vRotAngle);
  188.  
  189.     if(rX>1.0)
  190.     {
  191.         //inside a Sphere centered in 1,0,0
  192.         if(distance(rX,rY,rZ,1.0,0.0,0.0) <1.0)
  193.             return(0.5);
  194.     }
  195.     else // inside a cylinder diameter 1, around X axis
  196.         if(distance(rX,rY,rZ,rX,0.0,0.0) < 1.0)
  197.             return(0.5);
  198.  
  199.     //outside!
  200.     return (0.0);
  201. }
  202.  
  203.  
  204.  
  205. void doValentine()
  206. {
  207.     int x, y, z;
  208.     color pixelColor;
  209.  
  210.     pixelColor.green=0;
  211.     pixelColor.blue=0;
  212.  
  213.     for(int x=0;x<SIDE;x++)
  214.     for(int y=0;y<SIDE;y++)
  215.     for(int z=0;z<SIDE;z++)
  216.     {
  217.         pixelColor.red=100 * heartColor(x,y,z);
  218.         setPixel(x,y,z, pixelColor);
  219.     }
  220.  
  221.     // Slowly spin heart around Z axis
  222.     vRotAngle += 0.1;
  223. }
  224.  
  225.  
  226. //sets up the online/offline switch
  227. void initCloudButton()
  228. {
  229.     //set the input mode for the 'connect to cloud' button
  230.     pinMode(BUTTON, INPUT_PULLUP);
  231.     pinMode(MODE, INPUT_PULLUP);
  232.     if(!digitalRead(MODE))
  233.         WiFi.listen();
  234.     //a.k.a. onlinePressed is HIGH when the switch is set to 'online' and LOW when the switch is set to 'offline'
  235.     onlinePressed=digitalRead(BUTTON);
  236.     if(onlinePressed)
  237.         Spark.connect();
  238. }
  239.  
  240. //checks to see if the 'online/offline' switch is switched
  241. void checkCloudButton()
  242. {
  243.     //if the 'connect to cloud' button is pressed, try to connect to wifi.
  244.     //otherwise, run the program
  245.     //note -- how does this behave when there are no wifi credentials loaded on the spark?
  246.     //onlinePressed is HIGH when the switch is _not_ connected and LOW when the switch is connected
  247.     //a.k.a. onlinePressed is HIGH when the switch is set to 'online' and LOW when the switch is set to 'offline'
  248.     onlinePressed=digitalRead(BUTTON);
  249.     if((!onlinePressed)&&(lastOnline)) //marked as 'online'
  250.     {
  251.         lastOnline=onlinePressed;
  252.         Spark.connect();
  253.     }
  254.     else if((onlinePressed)&&(!lastOnline)) //marked as 'offline'
  255.     {
  256.         lastOnline=onlinePressed;
  257.         Spark.disconnect();
  258.     }
  259.     lastOnline=onlinePressed;
  260.     if(!digitalRead(MODE))
  261.         WiFi.listen();
  262. }
  263.  
  264. void loop()
  265. {
  266.     //if the 'connect to cloud' button is pressed, try to connect to wifi.
  267.     //otherwise, run the program
  268.     checkCloudButton();
  269.  
  270.     if(fading)
  271.         fade();
  272.     else
  273.     {
  274.         background(black);
  275.         switch(demo)
  276.         {
  277.             case(FIREWORKS):    updateFireworks();
  278.                                 break;
  279.             case(PLASMA):       zPlasma();
  280.                                 break;
  281.             case(SQUARRAL):     squarral();
  282.                                 break;
  283.             case(PURPLE_RAIN):  purpleRain();
  284.                                 break;
  285.             case(VALENTINE):    doValentine();
  286.                                 break;
  287.         }
  288.         frameCount++;
  289.     }
  290.     //check to see how if the cube has been flipped
  291.     checkFlipState();
  292.     strip.show();
  293.  
  294.     if(fading)
  295.     {
  296.         fadeValue-=fadeSpeed;
  297.         //if we're done fading)
  298.         if(fadeValue<=0)
  299.         {
  300.             fading=false;
  301.             fadeValue=255;
  302.         }
  303.         else
  304.             fade();
  305.     }
  306. }
  307.  
  308. void fade()
  309. {
  310.     color pixelColor;
  311.     for(int x=0;x<SIDE;x++)
  312.     for(int y=0;y<SIDE;y++)
  313.     for(int z=0;z<SIDE;z++)
  314.     {
  315.         pixelColor=getPixel(x,y,z);
  316.         if(pixelColor.red>0)
  317.             pixelColor.red--;
  318.         if(pixelColor.green>0)
  319.             pixelColor.green--;
  320.         if(pixelColor.blue>0)
  321.             pixelColor.blue--;
  322.         setPixel(x,y,z, pixelColor);
  323.     }
  324. }
  325.  
  326. //sets a pixel at position (x,y,z) to the col parameter's color
  327. void setPixel(int x, int y, int z, color col)
  328. {
  329.     int index = (z*SIDE*SIDE) + (x*SIDE) + y;
  330.     strip.setPixelColor(index,strip.Color(col.red, col.green, col.blue));
  331. }
  332.  
  333. //returns the color value currently displayed at the x,y,z location
  334. color getPixel(int x, int y, int z)
  335. {
  336.     int index = (z*SIDE*SIDE) + (x*SIDE) + y;
  337.     uint32_t col=strip.getPixelColor(index);
  338.     color pixelColor;
  339.     pixelColor.red=(col>>16)&255;
  340.     pixelColor.green=(col>>8)&255;
  341.     pixelColor.blue=col&255;
  342.     return pixelColor;
  343. }
  344.  
  345. void initCube()
  346. {
  347.     black.red=0;
  348.     black.green=0;
  349.     black.blue=0;
  350. }
  351.  
  352. void background(color col)
  353. {
  354.     for(int x=0;x<SIDE;x++)
  355.     for(int y=0;y<SIDE;y++)
  356.     for(int z=0;z<SIDE;z++)
  357.     setPixel(x,y,z, col);
  358. }
  359.  
  360. /***************************************
  361. * fireworks functions *
  362. * ***********************************/
  363. void updateFireworks()
  364. {
  365.     //loop through all the pixels, calculate the distance to the center point, and turn the pixel on if it's at the right radius
  366.     for(int x=0;x<SIDE;x++)
  367.         for(int y=0;y<SIDE;y++)
  368.             for(int z=0;z<SIDE;z++)
  369.             {
  370.                 if(showRocket)
  371.                     if(abs(distance(x,y,z,rocketX, rocketY, rocketZ)-radius)<0.05)
  372.                         setPixel(x,y,z, rocketColor);
  373.                 if(exploded)
  374.                     if(abs(distance(x,y,z,centerX, centerY, centerZ)-radius)<0.1)
  375.                         setPixel(x,y,z, fireworkColor);
  376.             }
  377.             if(exploded)
  378.                 radius+=speed; //the sphere gets bigger
  379.             if(showRocket)
  380.             {
  381.                 rocketX+=xInc;
  382.                 rocketY+=yInc;
  383.                 rocketZ+=zInc;
  384.             }
  385.             //if our sphere gets too large, restart the animation in another random spot
  386.             if(radius>maxSize)
  387.                 prepRocket();
  388.             if(abs(distance(centerX,centerY,centerZ,rocketX, rocketY, rocketZ)-radius)<2)
  389.             {
  390.                 showRocket=false;
  391.                 exploded=true;
  392.             }
  393. }
  394.  
  395. float distance(float x, float y, float z, float x1, float y1, float z1)
  396. {
  397.     return(sqrt(pow(x-x1,2)+pow(y-y1,2)+pow(z-z1,2)));
  398. }
  399.  
  400. void prepRocket()
  401. {
  402.     radius=0;
  403.     centerX=rand()%8;
  404.     centerY=rand()%8;
  405.     centerZ=rand()%8;
  406.     fireworkColor.red=rand()%brightness;
  407.     fireworkColor.green=rand()%brightness;
  408.     fireworkColor.blue=rand()%brightness;
  409.     launchX=rand()%8;
  410.     launchZ=rand()%8;
  411.     rocketX=launchX;
  412.     rocketY=0;
  413.     rocketZ=launchZ;
  414.     launchTime=15+rand()%25;
  415.     xInc=(centerX-rocketX)/launchTime;
  416.     yInc=(centerY-rocketY)/launchTime;
  417.     zInc=(centerZ-rocketZ)/launchTime;
  418.     showRocket=true;
  419.     exploded=false;
  420.     speed=0.15;
  421.     maxSize=2+rand()%6;
  422.     //speed=rand()%5;
  423.     //speed*=0.1;
  424. }
  425.  
  426. void initFireworks()
  427. {
  428.     rocketColor.red=255;
  429.     rocketColor.green=150;
  430.     rocketColor.blue=100;
  431.     prepRocket();
  432. }
  433.  
  434. void initSquarral()
  435. {
  436.     position={0,0,0};
  437.     increment={1,0,0};
  438. }
  439.  
  440. void squarral()
  441. {
  442.     add(position, increment);
  443.     if((increment.x==1)&&(position.x==SIDE-1-bound))
  444.         increment={0,1,0};
  445.     if((increment.x==-1)&&(position.x==bound))
  446.         increment={0,-1,0};
  447.     if((increment.y==1)&&(position.y==SIDE-1-bound))
  448.         increment={-1,0,0};
  449.  
  450.     if((increment.y==-1)&&(position.y==bound))
  451.     {
  452.         increment={1,0,0};
  453.         position.z+=squarral_zInc;
  454.         bound+=boundInc;
  455.         if((position.z==3)&&(squarral_zInc>0))
  456.             boundInc=0;
  457.         if((position.z==4)&&(squarral_zInc>0))
  458.             boundInc=-1;
  459.         if((position.z==3)&&(squarral_zInc<0))
  460.             boundInc=-1;
  461.         if((position.z==4)&&(squarral_zInc<0))
  462.             boundInc=0;
  463.         if((position.z==0)||(position.z==SIDE-1))
  464.             boundInc*=-1;
  465.         if((position.z==SIDE-1)||(position.z==0))
  466.         {
  467.             squarral_zInc*=-1;
  468.             if(squarral_zInc==1)
  469.             {
  470.                 axis=rand()%6;
  471.                 if(rand()%5==0)
  472.                     rainbow=true;
  473.                 else
  474.                     rainbow=false;
  475.             }
  476.         }
  477.     }
  478.     posX=position.x;
  479.     posY=position.y;
  480.     posZ=position.z;
  481.     incX=increment.x;
  482.     incY=increment.y;
  483.     incZ=increment.z;
  484.     for(int i=TRAIL_LENGTH-1;i>0;i--)
  485.     {
  486.         trailPoints[i].x=trailPoints[i-1].x;
  487.         trailPoints[i].y=trailPoints[i-1].y;
  488.         trailPoints[i].z=trailPoints[i-1].z;
  489.     }
  490.     trailPoints[0].x=pixel.x;
  491.     trailPoints[0].y=pixel.y;
  492.     trailPoints[0].z=pixel.z;
  493.     switch(axis)
  494.     {
  495.     case(0):    pixel.x=position.x;
  496.                 pixel.y=position.y;
  497.                 pixel.z=position.z;
  498.                 break;
  499.     case(1):    pixel.x=position.z;
  500.                 pixel.y=position.x;
  501.                 pixel.z=position.y;
  502.                 break;
  503.     case(2):    pixel.x=position.y;
  504.                 pixel.y=position.z;
  505.                 pixel.z=position.x;
  506.                 break;
  507.     case(3):    pixel.x=position.z;
  508.                 pixel.y=SIDE-1-position.x;
  509.                 pixel.z=position.y;
  510.                 break;
  511.     case(4):    pixel.x=position.y;
  512.                 pixel.y=position.z;
  513.                 pixel.z=SIDE-1-position.x;
  514.                 break;
  515.     case(5):    pixel.x=position.x;
  516.                 pixel.y=SIDE-1-position.y;
  517.                 pixel.z=position.z;
  518.                 break;
  519.     }
  520.  
  521.     pixelColor=colorMap(frame%1000,0,1000);
  522.     setPixel((int)pixel.x, (int)pixel.y, (int)pixel.z, pixelColor);
  523.     for(int i=0;i<TRAIL_LENGTH;i++)
  524.     {
  525.         color trailColor;
  526.         if(rainbow)
  527.         {
  528.             trailColor=colorMap((frame+(i*1000/TRAIL_LENGTH))%1000,0,1000);
  529.             //fade the trail to black over the length of the trail
  530.             trailColor.red=trailColor.red*(TRAIL_LENGTH-i)/TRAIL_LENGTH;
  531.             trailColor.green=trailColor.green*(TRAIL_LENGTH-i)/TRAIL_LENGTH;
  532.             trailColor.blue=trailColor.blue*(TRAIL_LENGTH-i)/TRAIL_LENGTH;
  533.         }
  534.         else
  535.         {
  536.             trailColor.red=pixelColor.red*(TRAIL_LENGTH-i)/TRAIL_LENGTH;
  537.             trailColor.green=pixelColor.green*(TRAIL_LENGTH-i)/TRAIL_LENGTH;
  538.             trailColor.blue=pixelColor.blue*(TRAIL_LENGTH-i)/TRAIL_LENGTH;
  539.         }
  540.         setPixel((int)trailPoints[i].x, (int)trailPoints[i].y, (int)trailPoints[i].z, trailColor);
  541.     }
  542.     frame++;
  543. }
  544.  
  545. void add(point& a, point& b)
  546. {
  547.     a.x+=b.x;
  548.     a.y+=b.y;
  549.     a.z+=b.z;
  550. }
  551. //returns a color from a set of colors fading from blue to green to red and back again
  552. //the color is returned based on where the parameter *val* falls between the parameters
  553. //*min* and *max*. If *val* is min, the function returns a blue color. If *val* is halfway
  554. //between *min* and *max*, the function returns a yellow color.
  555. color colorMap(float val, float min, float max)
  556. {
  557.     float range=1024;
  558.     val=range*(val-min)/(max-min);
  559.     color colors[6];
  560.     colors[0].red=0;
  561.     colors[0].green=0;
  562.     colors[0].blue=maxBrightness;
  563.     colors[1].red=0;
  564.     colors[1].green=maxBrightness;
  565.     colors[1].blue=maxBrightness;
  566.     colors[2].red=0;
  567.     colors[2].green=maxBrightness;
  568.     colors[2].blue=0;
  569.     colors[3].red=maxBrightness;
  570.     colors[3].green=maxBrightness;
  571.     colors[3].blue=0;
  572.     colors[4].red=maxBrightness;
  573.     colors[4].green=0;
  574.     colors[4].blue=0;
  575.     colors[5].red=maxBrightness;
  576.     colors[5].green=0;
  577.     colors[5].blue=maxBrightness;
  578.     if (val<=range/6)
  579.         return(lerpColor(colors[0], colors[1], val, 0, range/6));
  580.     else if (val<=2*range/6)
  581.         return(lerpColor(colors[1], colors[2], val, range/6, 2*range/6));
  582.     else if (val<=3*range/6)
  583.         return(lerpColor(colors[2], colors[3], val, 2*range/6, 3*range/6));
  584.     else if (val<=4*range/6)
  585.         return(lerpColor(colors[3], colors[4], val, 3*range/6, 4*range/6));
  586.     else if (val<=5*range/6)
  587.         return(lerpColor(colors[4], colors[5], val, 4*range/6, 5*range/6));
  588.  
  589.     return(lerpColor(colors[5], colors[0], val, 5*range/6, range));
  590. }
  591. //returns a color that's an interpolation between colors a and b. The color
  592. //is controlled by the position of val relative to min and max -- if val is equal to min,
  593. //the resulting color is identical to color a. If it's equal to max, the resulting color
  594. //is identical to color b. If val is (max-min)/2, the resulting color is the average of
  595. //color a and color b
  596. color lerpColor(color a, color b, int val, int min, int max)
  597. {
  598.     color lerped;
  599.     lerped.red=a.red+(b.red-a.red)*(val-min)/(max-min);
  600.     lerped.green=a.green+(b.green-a.green)*(val-min)/(max-min);
  601.     lerped.blue=a.blue+(b.blue-a.blue)*(val-min)/(max-min);
  602.     return lerped;
  603. }
  604. /********************************
  605. * zplasma functions *
  606. * *****************************/
  607. void zPlasma()
  608. {
  609.     phase += phaseIncrement;
  610.     // The two points move along Lissajious curves, see: http://en.wikipedia.org/wiki/Lissajous_curve
  611.     // We want values that fit the LED grid: x values between 0..8, y values between 0..8, z values between 0...8
  612.     // The sin() function returns values in the range of -1.0..1.0, so scale these to our desired ranges.
  613.     // The phase value is multiplied by various constants; I chose these semi-randomly, to produce a nice motion.
  614.     point p1 = { (sin(phase*1.000)+1.0) * 4, (sin(phase*1.310)+1.0) * 4.0, (sin(phase*1.380)+1.0) * 4.0};
  615.     point p2 = { (sin(phase*1.770)+1.0) * 4, (sin(phase*2.865)+1.0) * 4.0, (sin(phase*1.410)+1.0) * 4.0};
  616.     point p3 = { (sin(phase*0.250)+1.0) * 4, (sin(phase*0.750)+1.0) * 4.0, (sin(phase*0.380)+1.0) * 4.0};
  617.     byte row, col, dep;
  618.     // For each row
  619.     for(row=0; row<SIDE; row++)
  620.     {
  621.         float row_f = float(row); // Optimization: Keep a floating point value of the row number, instead of recasting it repeatedly.
  622.         // For each column
  623.         for(col=0; col<SIDE; col++)
  624.         {
  625.             float col_f = float(col); // Optimization.
  626.             // For each depth
  627.             for(dep=0; dep<SIDE; dep++)
  628.             {
  629.                 float dep_f = float(dep); // Optimization.
  630.                 // Calculate the distance between this LED, and p1.
  631.                 point dist1 = { col_f - p1.x, row_f - p1.y, dep_f - p1.z }; // The vector from p1 to this LED.
  632.                 float distance1 = sqrt( dist1.x*dist1.x + dist1.y*dist1.y + dist1.z*dist1.z);
  633.                 // Calculate the distance between this LED, and p2.
  634.                 point dist2 = { col_f - p2.x, row_f - p2.y, dep_f - p2.z}; // The vector from p2 to this LED.
  635.                 float distance2 = sqrt( dist2.x*dist2.x + dist2.y*dist2.y + dist2.z*dist2.z);
  636.                 // Calculate the distance between this LED, and p3.
  637.                 point dist3 = { col_f - p3.x, row_f - p3.y, dep_f - p3.z}; // The vector from p3 to this LED.
  638.                 float distance3 = sqrt( dist3.x*dist3.x + dist3.y*dist3.y + dist3.z*dist3.z);
  639.                 // Warp the distance with a sin() function. As the distance value increases, the LEDs will get light,dark,light,dark,etc...
  640.                 // You can use a cos() for slightly different shading, or experiment with other functions.
  641.                 float color_1 = distance1; // range: 0.0...1.0
  642.                 float color_2 = distance2;
  643.                 float color_3 = distance3;
  644.                 float color_4 = (sin( distance1 * distance2 * colorStretch )) + 2.0 * 0.5;
  645.                 // Square the color_f value to weight it towards 0. The image will be darker and have higher contrast.
  646.                 color_1 *= color_1 * color_4;
  647.                 color_2 *= color_2 * color_4;
  648.                 color_3 *= color_3 * color_4;
  649.                 color_4 *= color_4;
  650.                 // Scale the color up to 0..7 . Max brightness is 7.
  651.                 //strip.setPixelColor(col + (8 * row), strip.Color(color_4, 0, 0) );
  652.                 plasmaColor.red=color_1*plasmaBrightness;
  653.                 plasmaColor.green=color_2*plasmaBrightness;
  654.                 plasmaColor.blue=color_3*plasmaBrightness;
  655.                 setPixel(row,col,dep,plasmaColor);
  656.             }
  657.         }
  658.     }
  659. }
  660.  
  661.  
  662. /*********************************************
  663. * purple rain functions *
  664. * *******************************************/
  665. void checkMicrophone()
  666. {
  667.     int mic=analogRead(MICROPHONE);
  668.     if(mic<min)
  669.         min=mic;
  670.     if(mic>max)
  671.         max=mic;
  672.     float range=max-min;
  673.     int mean=(max-min)/2;
  674.     /*
  675.     if(min<mean)
  676.     min++;
  677.     if(max>mean)
  678.     max--;
  679.     */
  680.     threshhold=mean+sensitivity*(range/2);
  681.     if(mic>threshhold)
  682.     {
  683.         if((!aboveThreshhold)&&((timeAboveThreshhold-millis())>MIN_SALVO_SPACING))
  684.         {
  685.             launchRain(mic-threshhold);
  686.             aboveThreshhold=true;
  687.             timeAboveThreshhold=millis();
  688.         }
  689.     }
  690.     else
  691.         aboveThreshhold=false;
  692.     /*
  693.     Serial.print(mic);
  694.     Serial.print(": ");
  695.     Serial.print(threshhold);
  696.     Serial.print(" - above threshhold: ");
  697.     Serial.println(aboveThreshhold);
  698.     */
  699. }
  700.  
  701. void launchRain(int amplitude)
  702. {
  703.     int i;
  704.     for(i=0;((i<SIDE)&&(!salvos[i].dead));i++)
  705.         ;
  706.     if(i<SIDE)
  707.     {
  708.         if(amplitude>maxAmplitude)
  709.             maxAmplitude=amplitude;
  710.         int numDrops=map(amplitude,0, maxAmplitude,0, MAX_POINTS);
  711.         for(int j=0;j<numDrops;j++)
  712.         {
  713.             salvos[i].raindrops[j].x=1+(rand()%6);
  714.             salvos[i].raindrops[j].y=((rand()%10)-5)/10;
  715.             salvos[i].raindrops[j].z=1+(rand()%6);
  716.             salvos[i].dead=false;
  717.         }
  718.         for(int j=numDrops;j<MAX_POINTS;j++)
  719.         {
  720.             salvos[i].raindrops[j].x=-1;
  721.             salvos[i].raindrops[j].z=-1;
  722.         }
  723.     }
  724. }
  725.  
  726. void drawSalvos()
  727. {
  728.     for(int i=0;i<SIDE;i++)
  729.     if(!salvos[i].dead)
  730.         for(int j=0;j<MAX_POINTS;j++)
  731.             setPixel(salvos[i].raindrops[j].x, salvos[i].raindrops[j].y, salvos[i].raindrops[j].z, rainColor);
  732. }
  733.  
  734. void updateSalvos()
  735. {
  736.     for(int i=0;i<SIDE;i++)
  737.     {
  738.         int offCube=true;
  739.         for(int j=0;j<MAX_POINTS;j++)
  740.         {
  741.             salvos[i].raindrops[j].y+=SPEED;
  742.  
  743.             if(salvos[i].raindrops[j].y<SIDE)
  744.                 offCube=false;
  745.             else
  746.             {
  747.                 salvos[i].raindrops[j].x=-1;
  748.                 salvos[i].raindrops[j].z=-1;
  749.             }
  750.         }
  751.  
  752.         if(offCube)
  753.             salvos[i].dead=true;
  754.     }
  755. }
  756.  
  757.  
  758. void initMicrophone()
  759. {
  760.     pinMode(GAIN_CONTROL, OUTPUT);
  761.     digitalWrite(GAIN_CONTROL, LOW);
  762. }
  763.  
  764. void initSalvos()
  765. {
  766.     for(int i=0;i<SIDE;i++)
  767.     {
  768.         for(int j=0;j<MAX_POINTS;j++)
  769.         {
  770.             salvos[i].raindrops[j].x=-1;
  771.             salvos[i].raindrops[j].z=-1;
  772.         }
  773.         salvos[i].dead=true;
  774.     }
  775.     rainColor.red=100;
  776.     rainColor.green=0;
  777.     rainColor.blue=80;
  778. }
  779.  
  780. void purpleRain()
  781. {
  782.     checkMicrophone();
  783.     updateSalvos();
  784.     drawSalvos();
  785. }
  786.  
  787. /****************************************
  788. * flip functions *
  789. * **************************************/
  790. void checkFlipState()
  791. {
  792.     updateAccelerometer();
  793.     /*
  794.     if(accelerometer[2]<UPSIDE_DOWN) //if the cube is upside-down, set the upside-down flag and mark the time when it was flipped
  795.     {
  796.     upsideDownTime=millis();
  797.     //Serial.println("I'm upside-down!");
  798.     }
  799.     */
  800.     if(accelerometer[0]>FACEPLANT) //if the cube is upside-down, set the upside-down flag and mark the time when it was flipped
  801.     {
  802.         lastFaceplant=millis();
  803.         // Serial.println("I'm upside-down!");
  804.     }
  805.     if(accelerometer[1]<LEFT_SIDE) //if the cube is flipped to either side
  806.     {
  807.         lastLeft=millis();
  808.         // Serial.println("I'm on my left side");
  809.     }
  810.     if(accelerometer[1]>RIGHT_SIDE)
  811.     {
  812.     lastRight=millis();
  813.     // Serial.println("I'm on my right side");
  814.     }
  815.     if(accelerometer[2]>RIGHTSIDE_UP)
  816.     {
  817.         // Serial.println("whew! I'm rightside-up");
  818.         /*
  819.         if(((millis()-upsideDownTime)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
  820.         {
  821.         // Serial.println("turned upside down and back");
  822.         lastChange=millis();
  823.         autoCycle=!autoCycle;
  824.         upsideDownTime=millis()-FLIP_TIMEOUT;
  825.         lastLeft=millis()-FLIP_TIMEOUT; //clears the left and right turns, in case the user turned it sideways
  826.         lastRight=millis()-FLIP_TIMEOUT; //clears the left and right turns, in case the user turned it sideways
  827.         }
  828.         if(((millis()-lastLeft)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
  829.         {
  830.         // Serial.println("turned to the left and back");
  831.         lastChange=millis();
  832.         decrementDemo();
  833.         lastLeft=millis()-FLIP_TIMEOUT;
  834.         }
  835.         if(((millis()-lastRight)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
  836.         {
  837.         // Serial.println("turned to the right and back");
  838.         lastChange=millis();
  839.         incrementDemo();
  840.         lastRight=millis()-FLIP_TIMEOUT;
  841.         }
  842.         }
  843.         */
  844.         if(((millis()-lastFaceplant)<FLIP_TIMEOUT)&&(millis()-lastFaceplant>FLIP_DEBOUNCE))
  845.         {
  846.             autoCycle=false;
  847.             lastFaceplant=millis()-FLIP_TIMEOUT;
  848.             color flash;
  849.             flash.red=maxBrightness;
  850.             flash.green=maxBrightness;
  851.             flash.blue=maxBrightness;
  852.             background(flash);
  853.         }
  854.         if(((millis()-lastLeft)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
  855.         {
  856.             // Serial.println("turned to the left and back");
  857.             autoCycle=false;
  858.             lastChange=millis();
  859.             decrementDemo();
  860.             lastLeft=millis()-FLIP_TIMEOUT;
  861.         }
  862.         if(((millis()-lastRight)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
  863.         {
  864.             // Serial.println("turned to the right and back");
  865.             autoCycle=false;
  866.             lastChange=millis();
  867.             incrementDemo();
  868.             lastRight=millis()-FLIP_TIMEOUT;
  869.         }
  870.     }
  871.     if(autoCycle)
  872.     if(millis()-lastAutoCycle>AUTOCYCLE_TIME) //in autocycle, change demos every 15 seconds
  873.     {
  874.         incrementDemo();
  875.         // Serial.print("autocycling...Demo is ");
  876.         // Serial.println(demo);
  877.         lastAutoCycle=millis();
  878.     }
  879. }
  880.  
  881. void updateAccelerometer()
  882. {
  883.     for(int i=0;i<3;i++)
  884.         accelerometer[i]=analogRead(X+i);
  885. }
  886.  
  887. void setFadeSpeed()
  888. {
  889.     if(autoCycle)
  890.         fadeSpeed=2;
  891.     else
  892.         fadeSpeed=20;
  893. }
  894.  
  895. void incrementDemo()
  896. {
  897.     demo++;
  898.     setFadeSpeed();
  899.     fading=true;
  900.     if(demo>=DEMO_ROUTINES)
  901.         demo=0;
  902. }
  903.  
  904. void decrementDemo()
  905. {
  906.     demo--;
  907.     setFadeSpeed();
  908.     fading=true;
  909.     if(demo<0)
  910.         demo=DEMO_ROUTINES-1;
  911. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement