pchestna

L3D Cube Accelerometer Demo

Dec 26th, 2014
529
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.15 KB | None | 0 0
  1. #include "FastLED.h"
  2.  
  3. // LEDS
  4. #define LED_PIN     2
  5. #define LED_TYPE    WS2812B
  6. #define COLOR_ORDER GRB
  7. #define NUM_LEDS    512
  8. #define MASTER_BRIGHTNESS   128
  9. CRGB leds[NUM_LEDS];
  10.  
  11. // Accelerometer
  12. #define X A1
  13. #define Y A2
  14. #define Z A3
  15. #define FACEPLANT 590        
  16. #define UPSIDE_DOWN 430
  17. #define RIGHTSIDE_UP 590
  18. #define LEFT_SIDE 430
  19. #define RIGHT_SIDE 590
  20. #define BACK_SIDE 430
  21. #define FLIP_TIMEOUT 3000
  22. #define FLIP_DEBOUNCE 250
  23.  
  24. // Orientation
  25. typedef enum {NOTKNOWN, FACEUP, LSD, RSD, BSD, USD, FSD} ORIENTATION;
  26. ORIENTATION currentOrientation = NOTKNOWN;
  27. long lastFaceplant=-1*FLIP_TIMEOUT;
  28. int lastLeft=-1*FLIP_TIMEOUT;
  29. int lastRight=-1*FLIP_TIMEOUT;
  30. int accelerometer[3];
  31. long lastChange=0;
  32. bool printAccelVals = false;
  33.  
  34. // Animation by layer
  35. typedef enum {X_LAYER, Y_LAYER, Z_LAYER} LAYER;
  36. typedef enum {UP, DOWN} DIRECTION;
  37. const uint8_t kCubeSize = 8;
  38. static uint8_t hue = 0;
  39.  
  40. // Function definitions
  41. void printOrientation(ORIENTATION state);
  42. void fillLayer(uint8_t layer_index, LAYER layer);
  43. void fillAndShowLayer(LAYER layer, int nIndex);
  44. void lightLayers(LAYER layer, DIRECTION dir);
  45.  
  46. // Return the pixel index for the x, y & z vals.
  47. // returns 0 if out of bounds
  48. uint16_t XYZ( uint8_t x, uint8_t y, uint8_t z)
  49. {
  50.   uint16_t i;
  51.  
  52.   i = 8 * ((y * kCubeSize) + x) + z;
  53.  
  54.   if ((i >= 0) && (i <= 512))
  55.     return i;
  56.   else
  57.     return 0; // Safe return val if out of bounds
  58. }
  59.  
  60. // Fade all pixels
  61. void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(150); } }
  62.  
  63. void initAccelerometer()
  64. {
  65.   pinMode(X,INPUT);
  66.   pinMode(Y,INPUT);
  67.   pinMode(Z,INPUT);
  68.   delay(50);
  69.   updateAccelerometer(); // First read appears to be dirty, discard
  70.   delay(50);
  71. }
  72.  
  73. // prints vals based on bool that is toggled by rocking the cube on its back
  74. void printNewAccelVals()
  75. {
  76.     if (!printAccelVals) return;
  77.     Serial.print("Accel [");
  78.     for(int i=0;i<3;i++)
  79.     {
  80.         Serial.print(accelerometer[i]);
  81.         if (i<2) Serial.print(", ");
  82.     }
  83.     Serial.println("]");
  84.   }
  85.  
  86. // read the current values
  87. void updateAccelerometer()
  88. {
  89.     for(int i=0;i<3;i++)
  90.     {
  91.         accelerometer[i]=analogRead(X+i);
  92.     }
  93.     printNewAccelVals();
  94. }
  95.  
  96. void printOrientation(ORIENTATION state)
  97. {
  98.   switch (state)
  99.   {
  100.     case NOTKNOWN: Serial.print("Unknown"); break;
  101.     case FACEUP: Serial.print("Right side up"); break;
  102.     case LSD: Serial.print("Left side down"); break;
  103.     case RSD: Serial.print("Right side down"); break;
  104.     case BSD: Serial.print("Back side down"); break;
  105.     case FSD: Serial.print("Front side down"); break;
  106.     case USD: Serial.print("Upside down"); break;
  107.     default: Serial.print("Illegal state"); break;
  108.   }
  109. }
  110.  
  111. void checkFlipState()
  112.  {
  113.     updateAccelerometer();
  114.     ORIENTATION newState = NOTKNOWN;
  115.    
  116.     if(accelerometer[0]>FACEPLANT)  
  117.     {
  118.         lastFaceplant=millis();
  119.         newState = FSD;
  120.     }
  121.     if(accelerometer[1]<LEFT_SIDE)
  122.     {
  123.         lastLeft=millis();
  124.         newState = LSD;
  125.     }
  126.     if(accelerometer[1]>RIGHT_SIDE)
  127.     {
  128.         lastRight=millis();
  129.         newState = RSD;
  130.     }
  131.     if(accelerometer[2]<UPSIDE_DOWN)
  132.     {
  133.         newState = USD;
  134.     }
  135.     if(accelerometer[0]<BACK_SIDE)
  136.     {
  137.         newState = BSD;
  138.     }
  139.  
  140.     if(accelerometer[2]>RIGHTSIDE_UP)
  141.     {
  142.         newState = FACEUP;
  143.         if(((millis()-lastFaceplant)<FLIP_TIMEOUT)&&(millis()-lastFaceplant>FLIP_DEBOUNCE))
  144.         {
  145.             lastFaceplant=millis()-FLIP_TIMEOUT;
  146.         }
  147.         if(((millis()-lastLeft)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
  148.         {
  149.             //Serial.println("turned to the left and back");
  150.             lastChange=millis();
  151.             lastLeft=millis()-FLIP_TIMEOUT;
  152.         }
  153.         if(((millis()-lastRight)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
  154.         {
  155.             //Serial.println("turned to the right and back");
  156.             lastChange=millis();
  157.             lastRight=millis()-FLIP_TIMEOUT;
  158.         }
  159.     }
  160.    
  161.     // If it's changed...
  162.     if ((newState != currentOrientation) && (newState != NOTKNOWN))
  163.     {
  164.       if (currentOrientation != NOTKNOWN) // Should only happen first time
  165.       {
  166.         Serial.print("Orientation state change from: ");
  167.         printOrientation(currentOrientation);
  168.         Serial.print(" to: ");
  169.         printOrientation(newState);
  170.         Serial.println();
  171.       }
  172.       currentOrientation=newState;
  173.       if (currentOrientation == BSD) printAccelVals = !printAccelVals;
  174.     }
  175.  }
  176.  
  177. // fills all pixels in the layer
  178. void fillLayer(uint8_t layer_index, LAYER layer)
  179. {
  180.   int i;
  181.   for (int m = 0; m < kCubeSize; m++)
  182.     for (int n = 0; n < kCubeSize; n++)
  183.   {
  184.     switch (layer)
  185.     {
  186.        case X_LAYER:
  187.          i = XYZ(layer_index, m, n);
  188.        break;
  189.        case Y_LAYER:
  190.          i = XYZ(m, layer_index, n);
  191.        break;
  192.        case Z_LAYER:
  193.          i = XYZ(m, n, layer_index);
  194.        break;
  195.     }
  196.     leds[i] = CHSV(hue, 255, 255);
  197.   }
  198. }
  199.  
  200. void fillAndShowLayer(LAYER layer, int nIndex)
  201. {
  202.     fillLayer(nIndex, layer);
  203.     hue+=3;
  204.     FastLED.show();
  205.     fadeall();
  206.     delay(50);
  207. }
  208.  
  209. void lightLayers(LAYER layer, DIRECTION dir)
  210. {
  211.   switch (dir)
  212.   {
  213.     case UP:
  214.     {
  215.       for (int m = 0; m < kCubeSize; m++)
  216.         fillAndShowLayer(layer, m);
  217.     }
  218.     break;
  219.    
  220.     case DOWN:
  221.     {
  222.       for (int m = kCubeSize - 1; m >= 0; m--)
  223.         fillAndShowLayer(layer, m);
  224.     }
  225.     break;
  226.   }
  227. }
  228.  
  229. void animateLayers()
  230. {
  231.   switch (currentOrientation)
  232.   {
  233.     case FACEUP: lightLayers(Z_LAYER, DOWN); break;
  234.     case LSD: lightLayers(X_LAYER, DOWN); break;
  235.     case RSD: lightLayers(X_LAYER, UP); break;
  236.     case BSD: lightLayers(Y_LAYER, DOWN); break;
  237.     case FSD: lightLayers(Y_LAYER, UP); break;
  238.     case USD: lightLayers(Z_LAYER, UP); break;
  239.     default: Serial.println("Illegal state"); break;
  240.   }
  241. }
  242.  
  243. void setup() {
  244.   Serial.begin(9600);          //  setup serial
  245.   delay(3000);
  246.   FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  247.   FastLED.setBrightness(MASTER_BRIGHTNESS);
  248.   initAccelerometer();
  249. }
  250.  
  251. void loop() {
  252.   checkFlipState();
  253.   animateLayers();
  254. }
Advertisement
Add Comment
Please, Sign In to add comment