Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "FastLED.h"
- // LEDS
- #define LED_PIN 2
- #define LED_TYPE WS2812B
- #define COLOR_ORDER GRB
- #define NUM_LEDS 512
- #define MASTER_BRIGHTNESS 128
- CRGB leds[NUM_LEDS];
- // Accelerometer
- #define X A1
- #define Y A2
- #define Z A3
- #define FACEPLANT 590
- #define UPSIDE_DOWN 430
- #define RIGHTSIDE_UP 590
- #define LEFT_SIDE 430
- #define RIGHT_SIDE 590
- #define BACK_SIDE 430
- #define FLIP_TIMEOUT 3000
- #define FLIP_DEBOUNCE 250
- // Orientation
- typedef enum {NOTKNOWN, FACEUP, LSD, RSD, BSD, USD, FSD} ORIENTATION;
- ORIENTATION currentOrientation = NOTKNOWN;
- long lastFaceplant=-1*FLIP_TIMEOUT;
- int lastLeft=-1*FLIP_TIMEOUT;
- int lastRight=-1*FLIP_TIMEOUT;
- int accelerometer[3];
- long lastChange=0;
- bool printAccelVals = false;
- // Animation by layer
- typedef enum {X_LAYER, Y_LAYER, Z_LAYER} LAYER;
- typedef enum {UP, DOWN} DIRECTION;
- const uint8_t kCubeSize = 8;
- static uint8_t hue = 0;
- // Function definitions
- void printOrientation(ORIENTATION state);
- void fillLayer(uint8_t layer_index, LAYER layer);
- void fillAndShowLayer(LAYER layer, int nIndex);
- void lightLayers(LAYER layer, DIRECTION dir);
- // Return the pixel index for the x, y & z vals.
- // returns 0 if out of bounds
- uint16_t XYZ( uint8_t x, uint8_t y, uint8_t z)
- {
- uint16_t i;
- i = 8 * ((y * kCubeSize) + x) + z;
- if ((i >= 0) && (i <= 512))
- return i;
- else
- return 0; // Safe return val if out of bounds
- }
- // Fade all pixels
- void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(150); } }
- void initAccelerometer()
- {
- pinMode(X,INPUT);
- pinMode(Y,INPUT);
- pinMode(Z,INPUT);
- delay(50);
- updateAccelerometer(); // First read appears to be dirty, discard
- delay(50);
- }
- // prints vals based on bool that is toggled by rocking the cube on its back
- void printNewAccelVals()
- {
- if (!printAccelVals) return;
- Serial.print("Accel [");
- for(int i=0;i<3;i++)
- {
- Serial.print(accelerometer[i]);
- if (i<2) Serial.print(", ");
- }
- Serial.println("]");
- }
- // read the current values
- void updateAccelerometer()
- {
- for(int i=0;i<3;i++)
- {
- accelerometer[i]=analogRead(X+i);
- }
- printNewAccelVals();
- }
- void printOrientation(ORIENTATION state)
- {
- switch (state)
- {
- case NOTKNOWN: Serial.print("Unknown"); break;
- case FACEUP: Serial.print("Right side up"); break;
- case LSD: Serial.print("Left side down"); break;
- case RSD: Serial.print("Right side down"); break;
- case BSD: Serial.print("Back side down"); break;
- case FSD: Serial.print("Front side down"); break;
- case USD: Serial.print("Upside down"); break;
- default: Serial.print("Illegal state"); break;
- }
- }
- void checkFlipState()
- {
- updateAccelerometer();
- ORIENTATION newState = NOTKNOWN;
- if(accelerometer[0]>FACEPLANT)
- {
- lastFaceplant=millis();
- newState = FSD;
- }
- if(accelerometer[1]<LEFT_SIDE)
- {
- lastLeft=millis();
- newState = LSD;
- }
- if(accelerometer[1]>RIGHT_SIDE)
- {
- lastRight=millis();
- newState = RSD;
- }
- if(accelerometer[2]<UPSIDE_DOWN)
- {
- newState = USD;
- }
- if(accelerometer[0]<BACK_SIDE)
- {
- newState = BSD;
- }
- if(accelerometer[2]>RIGHTSIDE_UP)
- {
- newState = FACEUP;
- if(((millis()-lastFaceplant)<FLIP_TIMEOUT)&&(millis()-lastFaceplant>FLIP_DEBOUNCE))
- {
- lastFaceplant=millis()-FLIP_TIMEOUT;
- }
- if(((millis()-lastLeft)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
- {
- //Serial.println("turned to the left and back");
- lastChange=millis();
- lastLeft=millis()-FLIP_TIMEOUT;
- }
- if(((millis()-lastRight)<FLIP_TIMEOUT)&&(millis()-lastChange>FLIP_DEBOUNCE))
- {
- //Serial.println("turned to the right and back");
- lastChange=millis();
- lastRight=millis()-FLIP_TIMEOUT;
- }
- }
- // If it's changed...
- if ((newState != currentOrientation) && (newState != NOTKNOWN))
- {
- if (currentOrientation != NOTKNOWN) // Should only happen first time
- {
- Serial.print("Orientation state change from: ");
- printOrientation(currentOrientation);
- Serial.print(" to: ");
- printOrientation(newState);
- Serial.println();
- }
- currentOrientation=newState;
- if (currentOrientation == BSD) printAccelVals = !printAccelVals;
- }
- }
- // fills all pixels in the layer
- void fillLayer(uint8_t layer_index, LAYER layer)
- {
- int i;
- for (int m = 0; m < kCubeSize; m++)
- for (int n = 0; n < kCubeSize; n++)
- {
- switch (layer)
- {
- case X_LAYER:
- i = XYZ(layer_index, m, n);
- break;
- case Y_LAYER:
- i = XYZ(m, layer_index, n);
- break;
- case Z_LAYER:
- i = XYZ(m, n, layer_index);
- break;
- }
- leds[i] = CHSV(hue, 255, 255);
- }
- }
- void fillAndShowLayer(LAYER layer, int nIndex)
- {
- fillLayer(nIndex, layer);
- hue+=3;
- FastLED.show();
- fadeall();
- delay(50);
- }
- void lightLayers(LAYER layer, DIRECTION dir)
- {
- switch (dir)
- {
- case UP:
- {
- for (int m = 0; m < kCubeSize; m++)
- fillAndShowLayer(layer, m);
- }
- break;
- case DOWN:
- {
- for (int m = kCubeSize - 1; m >= 0; m--)
- fillAndShowLayer(layer, m);
- }
- break;
- }
- }
- void animateLayers()
- {
- switch (currentOrientation)
- {
- case FACEUP: lightLayers(Z_LAYER, DOWN); break;
- case LSD: lightLayers(X_LAYER, DOWN); break;
- case RSD: lightLayers(X_LAYER, UP); break;
- case BSD: lightLayers(Y_LAYER, DOWN); break;
- case FSD: lightLayers(Y_LAYER, UP); break;
- case USD: lightLayers(Z_LAYER, UP); break;
- default: Serial.println("Illegal state"); break;
- }
- }
- void setup() {
- Serial.begin(9600); // setup serial
- delay(3000);
- FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
- FastLED.setBrightness(MASTER_BRIGHTNESS);
- initAccelerometer();
- }
- void loop() {
- checkFlipState();
- animateLayers();
- }
Advertisement
Add Comment
Please, Sign In to add comment