ezdiver67

L3D Cube demo with Valentine

Jan 27th, 2015
783
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×