JPRoy

Atom

Oct 6th, 2015
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.41 KB | None | 0 0
  1. #define USE_OCTOWS2811
  2. #include<OctoWS2811.h>
  3. #include <FastLED.h>
  4. #include <Math.h>
  5.  
  6. // Atom visualization sketch on homemade 8X8X8 cube driven by a Teensy3.1 with an OCTOWS2811 adapter by Jean-Pierre Roy.
  7. // Based on Peter Chestna's original sketch found here: http://pastebin.com/ua72KQHu
  8. // Thanks to Peter Chestna and to Mark Kriegsman and FastLED.
  9. // This will always be...  Work in progress...
  10.  
  11. const uint8_t kCubeSize = 8;
  12. const uint8_t kFracs = 16;
  13.  
  14. #define NUM_LEDS kCubeSize * kCubeSize * kCubeSize
  15. #define LEDS_PER_OCTO_PIN kCubeSize * kCubeSize
  16. #define MAX_POS (kCubeSize-1)*kFracs
  17. #define CENTER MAX_POS/2
  18. #define FILLED_NUCLEUS true
  19. #define E_MIN_RAD 25
  20. #define E_MAX_RAD 54
  21. #define N_MAX_RAD 18
  22. #define N_MIN_POS 32
  23. #define N_MAX_POS 80
  24. #define F88_PI 804
  25. //#define F88_PI 3
  26. #define MIN_THETA 0
  27. #define MAX_THETA 2 * F88_PI
  28. #define MIN_PHI 0
  29. #define MAX_PHI F88_PI
  30. //#define THETA_RES 65535
  31. //#define PHI_RES 65535
  32. #define THETA_RES 60
  33. #define PHI_RES 30
  34. #define MASTER_BRIGHTNESS   255
  35. #define FADE 230
  36. #define NUM_PIXELS 0
  37. #define NUM_ELECTRONS 4
  38. CRGB leds[NUM_LEDS];
  39.  
  40. typedef struct {
  41.   int     F16posX = 0; // x position of the pixel
  42.   int     F16posY = 0; // y position of the pixel
  43.   int     F16posZ = 0; // z position of the pixel
  44.   uint8_t hue = 0;
  45.   uint8_t xPosMod = 1;
  46.   uint8_t yPosMod = 1;
  47.   uint8_t zPosMod = 1;
  48.   uint8_t posMin = N_MIN_POS;
  49.   uint8_t posMax = N_MAX_POS;
  50. } pixel;
  51. pixel pixels[NUM_PIXELS];
  52.  
  53. typedef struct {
  54.   int     F16posX = 0; // x position of the pixel
  55.   int     F16posY = 0; // y position of the pixel
  56.   int     F16posZ = 0; // z position of the pixel
  57.   uint16_t radius = E_MAX_RAD;
  58.   int theta = 0;
  59.   int phi = 0;
  60.   uint8_t thetaOrig = 0;
  61.   int radiusMod = 1;
  62.   bool thetaMod = false;
  63.   bool phiMod = true;
  64.   uint8_t hue = 0;
  65. } electron;
  66. electron electrons[NUM_ELECTRONS];
  67.  
  68. //void initPixelsNucleus()
  69. //{
  70. //  // NUM_PIXELS should be 2 to use only these two values
  71. //  pixels[0].hue = beatsin8(19,HUE_RED,HUE_YELLOW);
  72. //  pixels[0].xPosMod = 143;
  73. //  pixels[0].yPosMod = 91;
  74. //  pixels[0].zPosMod = 74;
  75. //
  76. //  pixels[1].hue = beatsin8(3,HUE_AQUA,HUE_PURPLE);
  77. //  pixels[1].xPosMod = 121;
  78. //  pixels[1].yPosMod = 77;
  79. //  pixels[1].zPosMod = 95;
  80. //}
  81.  
  82. void initNucleusPixelsRandom()
  83. {
  84.   for (int i=0; i<NUM_PIXELS; i++)
  85.   {
  86.     pixels[i].hue = random8();
  87.     pixels[i].xPosMod = random8();
  88.     pixels[i].yPosMod = random8();
  89.     pixels[i].zPosMod = random8();
  90.   }
  91. }
  92.  
  93. void initElectronsRandom()
  94. {
  95.   int thetaOffset = 0;
  96.   for (int i=0; i<NUM_ELECTRONS; i++)
  97.   {
  98.     electrons[i].hue = i*256/NUM_ELECTRONS;
  99.     electrons[i].radiusMod = 1;
  100.     electrons[i].phiMod = (i % 2) ? true : false;
  101.     electrons[i].phi = i*PHI_RES/NUM_ELECTRONS;
  102.     electrons[i].thetaOrig = (i*THETA_RES/NUM_ELECTRONS) + thetaOffset;
  103.   }
  104. }
  105.  
  106. void printElectronPos()
  107. {
  108.   for (int i=0; i<NUM_ELECTRONS; i++)
  109.   {
  110.     Serial.print("Electron (");
  111.     Serial.print(i);
  112.     Serial.print(") [");
  113.     Serial.print(electrons[i].F16posX);
  114.     Serial.print(", ");
  115.     Serial.print(electrons[i].F16posY);
  116.     Serial.print(", ");
  117.     Serial.print(electrons[i].F16posZ);
  118.     Serial.print("] Theta ");
  119.     Serial.print(electrons[i].theta);
  120.     Serial.print(", Phi ");
  121.     Serial.print(electrons[i].phi);
  122.     Serial.print(", Radius ");
  123.     Serial.println(electrons[i].radius);
  124.   }
  125. }
  126.  
  127. //void moveElectrons()
  128. //{
  129. //  for (int i=0; i<NUM_ELECTRONS; i++)
  130. //  {
  131. //    electrons[i].phi = beatsin16(20, 0, 65535);
  132. //    electrons[i].hue++;
  133. //
  134. //    if (electrons[i].phi == 65535)
  135. //      electrons[i].theta = electrons[i].thetaOrig + (THETA_RES/2);
  136. //    else if (electrons[i].phi == 0)
  137. //      electrons[i].theta = electrons[i].thetaOrig;
  138. //
  139. //    electrons[i].F16posX = CENTER + ((electrons[i].radius
  140. //      * cos16(electrons[i].theta)
  141. //      * sin16(electrons[i].phi))/(32767*32767));
  142. //
  143. //    electrons[i].F16posY = CENTER + ((electrons[i].radius
  144. //      * sin16(electrons[i].theta)
  145. //      * sin16(electrons[i].phi))/(32767*32767));
  146. //      
  147. //    electrons[i].F16posZ = CENTER + ((electrons[i].radius
  148. //      * cos16(electrons[i].phi))/32767);
  149. //  }
  150. //
  151. ////  printElectronPos();
  152. //}
  153.  
  154. void moveElectrons()
  155. {
  156.   for (int i=0; i<NUM_ELECTRONS; i++)
  157.   {
  158.     if (electrons[i].phi == PHI_RES)
  159.       electrons[i].phiMod = !electrons[i].phiMod;
  160.  
  161.     electrons[i].phi += (electrons[i].phiMod) ? 1 : -1;
  162.     electrons[i].theta = (electrons[i].phiMod) ? electrons[i].thetaOrig : electrons[i].thetaOrig + (THETA_RES/2);
  163.     // electrons[i].hue++;
  164.  
  165.     electrons[i].F16posX = CENTER + (electrons[i].radius * cos((float) PI * electrons[i].theta / THETA_RES)
  166.             * sin((float) PI * electrons[i].phi / PHI_RES));
  167.  
  168.     electrons[i].F16posY = CENTER + (electrons[i].radius * sin((float) PI * electrons[i].theta / THETA_RES)
  169.             * sin((float) PI * electrons[i].phi / PHI_RES));
  170.      
  171.     electrons[i].F16posZ = CENTER + (electrons[i].radius * cos((float) PI * electrons[i].phi / PHI_RES));
  172.  
  173.   }
  174. }
  175.  
  176. void moveNucleusPixels()
  177. {
  178.   for (int i=0; i<NUM_PIXELS; i++)
  179.   {
  180.     pixels[i].F16posX = beatsin16(pixels[i].xPosMod, pixels[i].posMin, pixels[i].posMax);
  181.     pixels[i].F16posY = beatsin16(pixels[i].yPosMod, pixels[i].posMin, pixels[i].posMax);
  182.     pixels[i].F16posZ = beatsin16(pixels[i].zPosMod, pixels[i].posMin, pixels[i].posMax);
  183.     pixels[i].hue++;
  184.   }
  185. }
  186.  
  187. //void fillNucleus()
  188. //{
  189. //  int res = 20;
  190. //  if (! FILLED_NUCLEUS) return;
  191. //  for (int theta=0; theta<res; theta+=2)
  192. //    for (int phi=0; phi<res; phi+=2)
  193. //    {
  194. //      int x, y, z;
  195. //        x = CENTER + (N_MAX_RAD * cos((float) 2 * PI * theta / res)
  196. //              * sin((float) PI * phi / res));
  197. //    
  198. //        y = CENTER + (N_MAX_RAD * sin((float) 2* PI * theta / res)
  199. //              * sin((float) PI * phi / res));
  200. //          
  201. //        z = CENTER + (N_MAX_RAD * cos((float) PI * phi / res));
  202. //        
  203. //        paintPixels(x, y, z, nucleusHue);
  204. //    }
  205. //}
  206.  
  207. void paintPixels(int nx, int ny, int nz, uint8_t hue)
  208. {
  209.     uint8_t x = nx / kFracs; // convert from pos to raw pixel number
  210.     uint8_t y = ny / kFracs; // convert from pos to raw pixel number
  211.     uint8_t z = nz / kFracs; // convert from pos to raw pixel number
  212.     uint8_t fracX = nx & 0x0F; // extract the 'factional' part of the position
  213.     uint8_t fracY = ny & 0x0F; // extract the 'factional' part of the position
  214.     uint8_t fracZ = nz & 0x0F; // extract the 'factional' part of the position
  215.  
  216.     uint8_t px = 255 - (fracX * kFracs);
  217.     uint8_t py = 255 - (fracY * kFracs);
  218.     uint8_t pz = 255 - (fracZ * kFracs);
  219.    
  220.     leds[XYZ(x,y,z)] = CHSV( hue, 255, scale8(px, scale8(py, pz)));
  221.     leds[XYZ(x,y+1,z)] = CHSV( hue, 255, scale8(px, scale8((255-py), pz)));
  222.     leds[XYZ(x,y,z+1)] = CHSV( hue, 255, scale8(px, scale8(py, (255-pz))));
  223.     leds[XYZ(x,y+1,z+1)] = CHSV( hue, 255, scale8(px, scale8((255-py), (255-pz))));
  224.     leds[XYZ(x+1,y,z)] = CHSV( hue, 255, scale8((255-px), scale8(py, pz)));
  225.     leds[XYZ(x+1,y+1,z)] = CHSV( hue, 255, scale8((255-px), scale8((255-py), pz)));
  226.     leds[XYZ(x+1,y,z+1)] = CHSV( hue, 255, scale8((255-px), scale8(py, (255-pz))));
  227.     leds[XYZ(x+1,y+1,z+1)] = CHSV( hue, 255, scale8((255-px), scale8((255-py), (255-pz))));
  228. }
  229.  
  230. void fillNucleus()
  231. {
  232.      paintNucleus(3, 3, 3);
  233.      paintNucleus(3, 4, 3);
  234.      paintNucleus(3, 3, 4);
  235.      paintNucleus(3, 4, 4);
  236.      paintNucleus(4, 3, 3);
  237.      paintNucleus(4, 4, 3);
  238.      paintNucleus(4, 3, 4);
  239.      paintNucleus(4, 4, 4);
  240. }
  241.  
  242. int nb = 32;
  243. int nh = 0;
  244. void paintNucleus(int x, int y, int z)
  245. {
  246.     nb = beatsin8(15, 32, 64);
  247.     nh = beatsin8(7, 0, 255);
  248.     leds[XYZ(x,y,z)] += CHSV( nh, 255, nb);
  249. }
  250.  
  251. void setup() {
  252.   Serial.begin(57600);
  253.   delay(3000); // setup guard
  254.   LEDS.addLeds<OCTOWS2811, RGB>(leds, LEDS_PER_OCTO_PIN);
  255.   FastLED.setBrightness(MASTER_BRIGHTNESS);
  256.   initElectronsRandom();
  257.   initNucleusPixelsRandom();
  258. }
  259.  
  260. uint16_t XYZ( uint8_t x, uint8_t y, uint8_t z)
  261. {
  262.   uint16_t i;
  263.  
  264.   if(z & 1) i = kCubeSize * ((x * kCubeSize) + z) +7-y;     // Check for odd numbered vertical layers
  265.   else i = kCubeSize * ((x * kCubeSize) + z) + y;           // to take care of cube's zig-zag wiring
  266.    
  267.   if ((i >= 0) && (i <= 512))
  268.     return i;
  269.   else
  270.     return 0;
  271. }
  272.  
  273. // Draw a pixel on a matrix using fractions of light. Positions are measured in
  274. // sixteenths of a pixel.  Fractional positions are
  275. // rendered using 'anti-aliasing' of pixel brightness.
  276. void drawPixels()
  277. {
  278.   for (int i = 0; i < NUM_PIXELS; i++)
  279.   {
  280.     int hue = pixels[i].hue;
  281.    
  282.     uint8_t x = pixels[i].F16posX / kFracs; // convert from pos to raw pixel number
  283.     uint8_t y = pixels[i].F16posY / kFracs; // convert from pos to raw pixel number
  284.     uint8_t z = pixels[i].F16posZ / kFracs; // convert from pos to raw pixel number
  285.     uint8_t fracX = pixels[i].F16posX & 0x0F; // extract the 'factional' part of the position
  286.     uint8_t fracY = pixels[i].F16posY & 0x0F; // extract the 'factional' part of the position
  287.     uint8_t fracZ = pixels[i].F16posZ & 0x0F; // extract the 'factional' part of the position
  288.  
  289.     uint8_t px = 255 - (fracX * kFracs);
  290.     uint8_t py = 255 - (fracY * kFracs);
  291.     uint8_t pz = 255 - (fracZ * kFracs);
  292.    
  293.     leds[XYZ(x,y,z)] += CHSV( hue, 255, scale8(px, scale8(py, pz)));
  294.     leds[XYZ(x,y+1,z)] += CHSV( hue, 255, scale8(px, scale8((255-py), pz)));
  295.     leds[XYZ(x,y,z+1)] += CHSV( hue, 255, scale8(px, scale8(py, (255-pz))));
  296.     leds[XYZ(x,y+1,z+1)] += CHSV( hue, 255, scale8(px, scale8((255-py), (255-pz))));
  297.     leds[XYZ(x+1,y,z)] += CHSV( hue, 255, scale8((255-px), scale8(py, pz)));
  298.     leds[XYZ(x+1,y+1,z)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), pz)));
  299.     leds[XYZ(x+1,y,z+1)] += CHSV( hue, 255, scale8((255-px), scale8(py, (255-pz))));
  300.     leds[XYZ(x+1,y+1,z+1)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), (255-pz))));
  301.   }
  302. }
  303.  
  304. void drawElectrons()
  305. {
  306.   for (int i = 0; i < NUM_ELECTRONS; i++)
  307.   {
  308.     int hue = electrons[i].hue;
  309.    
  310.     uint8_t x = electrons[i].F16posX / kFracs; // convert from pos to raw pixel number
  311.     uint8_t y = electrons[i].F16posY / kFracs; // convert from pos to raw pixel number
  312.     uint8_t z = electrons[i].F16posZ / kFracs; // convert from pos to raw pixel number
  313.     uint8_t fracX = electrons[i].F16posX & 0x0F; // extract the 'factional' part of the position
  314.     uint8_t fracY = electrons[i].F16posY & 0x0F; // extract the 'factional' part of the position
  315.     uint8_t fracZ = electrons[i].F16posZ & 0x0F; // extract the 'factional' part of the position
  316.  
  317.     uint8_t px = 255 - (fracX * kFracs);
  318.     uint8_t py = 255 - (fracY * kFracs);
  319.     uint8_t pz = 255 - (fracZ * kFracs);
  320.    
  321.     leds[XYZ(x,y,z)] += CHSV( hue, 255, scale8(px, scale8(py, pz)));
  322.     leds[XYZ(x,y+1,z)] += CHSV( hue, 255, scale8(px, scale8((255-py), pz)));
  323.     leds[XYZ(x,y,z+1)] += CHSV( hue, 255, scale8(px, scale8(py, (255-pz))));
  324.     leds[XYZ(x,y+1,z+1)] += CHSV( hue, 255, scale8(px, scale8((255-py), (255-pz))));
  325.     leds[XYZ(x+1,y,z)] += CHSV( hue, 255, scale8((255-px), scale8(py, pz)));
  326.     leds[XYZ(x+1,y+1,z)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), pz)));
  327.     leds[XYZ(x+1,y,z+1)] += CHSV( hue, 255, scale8((255-px), scale8(py, (255-pz))));
  328.     leds[XYZ(x+1,y+1,z+1)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), (255-pz))));
  329.   }
  330. }
  331.  
  332. void loop()
  333. {
  334.   // Dim everything
  335.   nscale8(leds, NUM_LEDS, FADE);
  336.  
  337.   moveNucleusPixels();
  338.   moveElectrons();
  339.   drawPixels();
  340.   drawElectrons();
  341.   fillNucleus();
  342.    
  343.   FastLED.show();
  344.   FastLED.delay(20);
  345. }
Advertisement
Add Comment
Please, Sign In to add comment