/* Arduino and MPU6050 Accelerometer and Gyroscope Sensor Tutorial by Dejan, https://howtomechatronics.com */ #include #include #include #define LED_PIN 7 byte mode = 2; // 0 for acceleration, 1 for fire, 2 for waterfall, 3 pride, 4 glitter, 5 off const byte NUM_MODES = 6; const byte debug = 3; const byte STRIPS = 6; const byte NUM_LEDS = 10; const byte FRAMES_PER_SECOND = 30; const float range = 0.5; //accelleration range in g const byte BRIGHTNESS = 50; const byte COOLING = 80; const byte SPARKING = 50; uint8_t gHue = 0; float accelerationHistory [STRIPS]; MPU6050 mpu(Wire); CRGB leds[NUM_LEDS * STRIPS]; CRGBPalette16 gPal; CRGB flagcolors[6] = {CRGB::Red, CRGB::DarkOrange, CRGB::Yellow, CRGB::DarkGreen, CRGB::Blue, CRGB::DarkViolet}; const byte modeSwitchPin = 2; void setup() { Serial.begin(19200); //setup LEDs FastLED.addLeds(leds, NUM_LEDS*STRIPS).setCorrection( TypicalLEDStrip ); FastLED.setBrightness( BRIGHTNESS ); pinMode(modeSwitchPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(modeSwitchPin), setMode, RISING); for (int i = 0; i stripEnd)){ for (int i = stripStart; i <= stripEnd; i++) { leds[i] = CRGB(0, 0, 64); } } else { for (int i = stripStart; i <= ledcutoff; i++) { leds[i] = CRGB(64, 0, 0); } for (int i = ledcutoff; i <= stripEnd; i++) { leds[i] = CRGB(0, 64, 0); } } } void enableLEDsOnAcceleration(float accCombined){ // draw all stored accelerations for (int i = 0; i < STRIPS; i++){ drawAccelerationOnStrip(i, accelerationHistory[i]); } //shift them to the front for (int i = 0; i < STRIPS-1; i++) { accelerationHistory[i] = accelerationHistory[i+1]; } //add new entry at the end accelerationHistory[STRIPS-1] = accCombined; } void calculateFire(int strip){ // Array of temperature readings at each simulation cell static byte heat[STRIPS][NUM_LEDS]; // Step 1. Cool down every cell a little for( int i = 0; i < NUM_LEDS; i++) { heat[strip][i] = qsub8( heat[strip][i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); } // Step 2. Heat from each cell drifts 'up' and diffuses a little for( int k= NUM_LEDS - 1; k >= 2; k--) { heat[strip][k] = (heat[strip][k - 1] + heat[strip][k - 2] + heat[strip][k - 2] ) / 3; } // Step 3. Randomly ignite new 'sparks' of heat near the bottom if( random8() < SPARKING ) { int y = random8(7); heat[strip][y] = qadd8( heat[strip][y], random8(160,255) ); } // Step 4. Map from heat cells to LED colors for( int j = 0; j < NUM_LEDS; j++) { // Scale the heat value from 0-255 down to 0-240 // for best results with color palettes. byte colorindex = scale8( heat[strip][j], 240); CRGB color = ColorFromPalette( gPal, colorindex); int pixelnumber = (strip * NUM_LEDS) + j; leds[pixelnumber] = color; } } void drawFire(){ if (mode == 1) { gPal = CRGBPalette16( CRGB::Black, CRGB::Red, CRGB::Yellow, CRGB::White); } else { gPal = CRGBPalette16( CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White); } for (int i = 0; i < STRIPS; i++){ calculateFire(i); } } void drawPride(){ for (int strip = 0; strip < STRIPS; strip++){ CRGB color = flagcolors[strip]; for( int j = 0; j < NUM_LEDS; j++) { int pixelnumber = (strip * NUM_LEDS) + j; leds[pixelnumber] = color; } } } void drawGlitter(){ fadeToBlackBy( leds, STRIPS*NUM_LEDS, 10); int pos = random16(STRIPS*NUM_LEDS); leds[pos] += CHSV( gHue + random8(64), 200, 255); } void drawOff(){ fadeToBlackBy( leds, STRIPS*NUM_LEDS, 10); } void setMode(){ mode++; if (mode >= NUM_MODES) { mode = 0; } if (debug <= 3) { Serial.print("Blinkmode:\t"); Serial.println(mode); } } void loop() { if (mode == 0) { // === Read acceleromter data === // float accCombined = calculateOrientationData(); enableLEDsOnAcceleration(accCombined); } else if ((mode == 1) || (mode == 2)) { random16_add_entropy( random()); drawFire(); } else if (mode == 3) { drawPride(); } else if (mode == 4) { drawGlitter(); } else if (mode == 5) { drawOff(); } FastLED.show(); gHue++; FastLED.delay(1000 / FRAMES_PER_SECOND); }