├── BlinkyTileFastLED.ino ├── LICENSE ├── README.md └── images ├── ArduinoConnections.jpg ├── BlinkyTileAdapterBoard.jpg └── BlinkyTileConnector.jpg /BlinkyTileFastLED.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define LED_PIN 0 7 | #define NUM_LEDS 12 8 | #define LED_TYPE DMXSIMPLE 9 | #define COLOR_ORDER BGR 10 | 11 | #define PATTERN_SWITCH_PIN 3 12 | #define BRIGHTNESS_SWITCH_PIN 4 13 | 14 | CRGB leds[NUM_LEDS]; 15 | 16 | unsigned int patternCount = 7; 17 | unsigned int currentPatternIndex = 0; 18 | 19 | boolean ignorePatternSwitch = false; 20 | boolean ignoreBrightnessSwitch = false; 21 | 22 | // The brightness of our pixels (0 to 255). 23 | // 0 is off. 24 | // 16 is dim. 25 | // 64 is medium. 26 | // 128 is bright. 27 | // 255 is blindingly bright! 28 | byte brightness = 32; 29 | 30 | Adafruit_LSM303 lsm; 31 | 32 | boolean lsmAvailable = false; 33 | 34 | void setup() { 35 | // Serial.begin(9600); 36 | 37 | pinMode(PATTERN_SWITCH_PIN, INPUT_PULLUP); 38 | pinMode(BRIGHTNESS_SWITCH_PIN, INPUT_PULLUP); 39 | 40 | FastLED.addLeds(leds, NUM_LEDS); 41 | FastLED.setCorrection(TypicalLEDStrip); 42 | FastLED.setBrightness(brightness); 43 | 44 | lsmAvailable = lsm.begin(); 45 | } 46 | 47 | byte hue = 0; 48 | byte currentLed = 0; 49 | 50 | void loop() { 51 | uint16_t delay = 0; 52 | 53 | switch (currentPatternIndex) { 54 | case 0: 55 | default: 56 | delay = compass(); 57 | break; 58 | 59 | case 1: 60 | delay = tilt(); 61 | break; 62 | 63 | case 2: 64 | delay = force(); 65 | break; 66 | 67 | case 3: 68 | delay = colorPaletteExample(); 69 | break; 70 | 71 | case 4: 72 | delay = solidHueShift(); 73 | break; 74 | 75 | case 5: 76 | delay = sequenceHueShift(); 77 | break; 78 | 79 | case 6: 80 | delay = antiAliasedLightBar(); 81 | break; 82 | } 83 | 84 | FastLED.show(); 85 | FastLED.delay(delay); 86 | 87 | handleInput(); 88 | } 89 | 90 | void handleInput() { 91 | if (digitalRead(PATTERN_SWITCH_PIN) == LOW) { 92 | if (!ignorePatternSwitch) { 93 | ignorePatternSwitch = true; 94 | 95 | currentPatternIndex++; 96 | if (currentPatternIndex >= patternCount) 97 | currentPatternIndex = 0; 98 | } 99 | } 100 | else { 101 | ignorePatternSwitch = false; 102 | } 103 | 104 | if (digitalRead(BRIGHTNESS_SWITCH_PIN) == LOW) { 105 | if (!ignoreBrightnessSwitch) { 106 | ignoreBrightnessSwitch = true; 107 | 108 | brightness += 32; 109 | if (brightness < 32) 110 | brightness = 32; 111 | 112 | FastLED.setBrightness(brightness); 113 | } 114 | } 115 | else { 116 | ignoreBrightnessSwitch = false; 117 | } 118 | } 119 | 120 | uint16_t solidHueShift() { 121 | fill_solid(leds, NUM_LEDS, CHSV(hue, 255, 255)); 122 | hue++; 123 | return 30; 124 | } 125 | 126 | uint16_t sequenceHueShift() { 127 | fill_solid(leds, NUM_LEDS, CRGB::Black); 128 | leds[currentLed] = CHSV(hue, 255, 255); 129 | hue++; 130 | currentLed++; 131 | if (currentLed >= NUM_LEDS) { 132 | currentLed = 0; 133 | } 134 | return 120; 135 | } 136 | 137 | uint16_t force() { 138 | if (!lsmAvailable) { 139 | return colorPaletteExample(); 140 | } 141 | 142 | lsm.read(); 143 | 144 | float Pi = 3.14159; 145 | 146 | // Calculate the angle of the vector y,x 147 | float heading = (atan2(lsm.accelData.y, lsm.accelData.x) * 180) / Pi; 148 | 149 | // Normalize to 0-360 150 | if (heading < 0) 151 | { 152 | heading = 360 + heading; 153 | } 154 | 155 | uint8_t hue = map(heading, 0, 360, 0, 255); 156 | 157 | fill_solid(leds, NUM_LEDS, CHSV(hue, 255, 255)); 158 | 159 | return 60; 160 | } 161 | 162 | uint16_t compass() { 163 | if (!lsmAvailable) { 164 | return colorPaletteExample(); 165 | } 166 | 167 | lsm.read(); 168 | 169 | float Pi = 3.14159; 170 | 171 | // Calculate the angle of the vector y,x 172 | float heading = (atan2(lsm.magData.y, lsm.magData.x) * 180) / Pi; 173 | 174 | // Normalize to 0-360 175 | if (heading < 0) 176 | { 177 | heading = 360 + heading; 178 | } 179 | 180 | uint8_t hue = map(heading, 0, 360, 0, 255); 181 | 182 | fill_solid(leds, NUM_LEDS, CHSV(hue, 255, 255)); 183 | 184 | return 60; 185 | } 186 | 187 | // half segment size 188 | float s = 2048.0 / 5.0; // 409.6F 189 | // segment size 190 | float s2 = s * 2.0; // 819.2F 191 | 192 | byte topLed = 0; 193 | byte spinIndex = 0; 194 | 195 | byte tiltSpin[12][5] = 196 | { 197 | { 198 | 1, 2, 3, 4, 5 199 | } 200 | , // 0 201 | { 202 | 2, 0, 5, 6, 7 203 | } 204 | , // 1 205 | { 206 | 3, 0, 1, 7, 8 207 | } 208 | , // 2 209 | { 210 | 4, 0, 2, 8, 9 211 | } 212 | , // 3 213 | { 214 | 5, 0, 3, 9, 10 215 | } 216 | , // 4 217 | { 218 | 6, 1, 0, 4, 10 219 | } 220 | , // 5 221 | { 222 | 7, 1, 5, 10, 11 223 | } 224 | , // 6 225 | { 226 | 8, 2, 1, 6, 11 227 | } 228 | , // 7 229 | { 230 | 9, 3, 2, 7, 11 231 | } 232 | , // 8 233 | { 234 | 10, 4, 3, 8, 11 235 | } 236 | , // 9 237 | { 238 | 11, 6, 5, 4, 9 239 | } 240 | , // 10 241 | { 242 | 10, 9, 8, 7, 6 243 | } // 11 244 | }; 245 | 246 | uint16_t tilt() { 247 | if (lsmAvailable) { 248 | fill_solid(leds, NUM_LEDS, CRGB::Black); 249 | 250 | leds[topLed] += CRGB::Red; 251 | leds[tiltSpin[topLed][spinIndex]] += CRGB::Blue; 252 | } 253 | else { 254 | return colorPaletteExample(); 255 | } 256 | 257 | spinIndex++; 258 | if (spinIndex >= 5) 259 | spinIndex = 0; 260 | 261 | lsm.read(); 262 | 263 | float x = lsm.accelData.x; 264 | float y = lsm.accelData.y; 265 | float z = lsm.accelData.z; 266 | 267 | if (z >= 768) { 268 | // top 269 | topLed = 0; 270 | } 271 | else if (z >= 0) { 272 | // upper middle 273 | 274 | if (between(x, -1024.0F, -409.6) && between(y, -204.8F, 614.4F)) 275 | topLed = 1; 276 | else if (between(x, -409.6F, 409.6F) && between(y, 614.4F, 1024.0F)) 277 | topLed = 2; 278 | else if (between(x, 409.6F, 1024.0F) && between(y, -204.8F, 614.4F)) 279 | topLed = 3; 280 | else if (between(x, 0.0F, 819.2F) && between(y, -1024.0F, -204.8F)) 281 | topLed = 4; 282 | else if (between(x, -819.2F, 0.0F) && between(y, -1024.0, -204.8)) 283 | topLed = 5; 284 | } 285 | else if (z >= -768) { 286 | // lower middle 287 | 288 | if (between(x, -1024.0F, -409.6F) && between(y, -614.4F, 204.8F)) 289 | topLed = 6; 290 | else if (between(x, -819.2F, 0) && between(y, 204.8F, 1024.0F)) 291 | topLed = 7; 292 | else if (between(x, 0, 819.2F) && between(y, 204.8, 1024)) 293 | topLed = 8; 294 | else if (between(x, 409.6F, 1024.0F) && between(y, -614.4F, 204.8F)) 295 | topLed = 9; 296 | else if (between(x, -409.6F, 409.6F) && between(y, -1024.2F, -614.4F)) 297 | topLed = 10; 298 | } 299 | else // z < -512 300 | { 301 | // bottom 302 | topLed = 11; 303 | } 304 | 305 | return 60; 306 | } 307 | 308 | boolean between(float value, float minV, float maxV) { 309 | return value >= minV && value <= maxV; 310 | } 311 | 312 | int F16pos = 0; // position of the "fraction-based bar" 313 | int F16delta = 1; // how many 16ths of a pixel to move the Fractional Bar 314 | uint16_t Fhue16 = 0; // color for Fractional Bar 315 | 316 | int Width = 2; // width of each light bar, in whole pixels 317 | 318 | uint16_t antiAliasedLightBar() { 319 | // Update the "Fraction Bar" by 1/16th pixel every time 320 | F16pos += F16delta; 321 | 322 | // wrap around at end 323 | // remember that F16pos contains position in "16ths of a pixel" 324 | // so the 'end of the strip' is (NUM_LEDS * 16) 325 | if ( F16pos >= (NUM_LEDS * 16)) { 326 | F16pos -= (NUM_LEDS * 16); 327 | } 328 | 329 | // Draw everything: 330 | // clear the pixel buffer 331 | memset8( leds, 0, NUM_LEDS * sizeof(CRGB)); 332 | 333 | // advance to the next hue 334 | Fhue16 = Fhue16 + 19; 335 | 336 | // draw the Fractional Bar, length=4px 337 | drawFractionalBar( F16pos, Width, Fhue16 / 256); 338 | 339 | return 40; 340 | } 341 | 342 | // Draw a "Fractional Bar" of light starting at position 'pos16', which is counted in 343 | // sixteenths of a pixel from the start of the strip. Fractional positions are 344 | // rendered using 'anti-aliasing' of pixel brightness. 345 | // The bar width is specified in whole pixels. 346 | // Arguably, this is the interesting code. 347 | void drawFractionalBar( int pos16, int width, uint8_t hue) 348 | { 349 | int i = pos16 / 16; // convert from pos to raw pixel number 350 | uint8_t frac = pos16 & 0x0F; // extract the 'factional' part of the position 351 | 352 | // brightness of the first pixel in the bar is 1.0 - (fractional part of position) 353 | // e.g., if the light bar starts drawing at pixel "57.9", then 354 | // pixel #57 should only be lit at 10% brightness, because only 1/10th of it 355 | // is "in" the light bar: 356 | // 357 | // 57.9 . . . . . . . . . . . . . . . . . 61.9 358 | // v v 359 | // ---+---56----+---57----+---58----+---59----+---60----+---61----+---62----> 360 | // | | X|XXXXXXXXX|XXXXXXXXX|XXXXXXXXX|XXXXXXXX | 361 | // ---+---------+---------+---------+---------+---------+---------+---------> 362 | // 10% 100% 100% 100% 90% 363 | // 364 | // the fraction we get is in 16ths and needs to be converted to 256ths, 365 | // so we multiply by 16. We subtract from 255 because we want a high 366 | // fraction (e.g. 0.9) to turn into a low brightness (e.g. 0.1) 367 | uint8_t firstpixelbrightness = 255 - (frac * 16); 368 | 369 | // if the bar is of integer length, the last pixel's brightness is the 370 | // reverse of the first pixel's; see illustration above. 371 | uint8_t lastpixelbrightness = 255 - firstpixelbrightness; 372 | 373 | // For a bar of width "N", the code has to consider "N+1" pixel positions, 374 | // which is why the "<= width" below instead of "< width". 375 | 376 | uint8_t bright; 377 | for ( int n = 0; n <= width; n++) { 378 | if ( n == 0) { 379 | // first pixel in the bar 380 | bright = firstpixelbrightness; 381 | } 382 | else if ( n == width ) { 383 | // last pixel in the bar 384 | bright = lastpixelbrightness; 385 | } 386 | else { 387 | // middle pixels 388 | bright = 255; 389 | } 390 | 391 | leds[i] += CHSV( hue, 255, bright); 392 | i++; 393 | if ( i == NUM_LEDS) i = 0; // wrap around 394 | } 395 | } 396 | 397 | // ColorPalette example by Mark Kriegsman: https://github.com/FastLED/FastLED/blob/master/examples/ColorPalette/ColorPalette.ino 398 | uint16_t colorPaletteExample() { 399 | ChangePalettePeriodically(); 400 | 401 | static uint8_t startIndex = 0; 402 | startIndex++; /* motion speed */ 403 | 404 | FillLEDsFromPaletteColors(startIndex); 405 | 406 | return 10; 407 | } 408 | 409 | // This example shows several ways to set up and use 'palettes' of colors 410 | // with FastLED. 411 | // 412 | // These compact palettes provide an easy way to re-colorize your 413 | // animation on the fly, quickly, easily, and with low overhead. 414 | // 415 | // USING palettes is MUCH simpler in practice than in theory, so first just 416 | // run this sketch, and watch the pretty lights as you then read through 417 | // the code. Although this sketch has eight (or more) different color schemes, 418 | // the entire sketch compiles down to about 6.5K on AVR. 419 | // 420 | // FastLED provides a few pre-configured color palettes, and makes it 421 | // extremely easy to make up your own color schemes with palettes. 422 | // 423 | // Some notes on the more abstract 'theory and practice' of 424 | // FastLED compact palettes are at the bottom of this file. 425 | 426 | CRGBPalette16 currentPalette = RainbowColors_p; 427 | TBlendType currentBlending = LINEARBLEND; 428 | 429 | extern CRGBPalette16 myRedWhiteBluePalette; 430 | extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM; 431 | 432 | void FillLEDsFromPaletteColors(uint8_t colorIndex) 433 | { 434 | uint8_t brightness = 255; 435 | 436 | for (int i = 0; i < NUM_LEDS; i++) { 437 | leds[i] = ColorFromPalette(currentPalette, colorIndex, brightness, currentBlending); 438 | colorIndex += 3; 439 | } 440 | } 441 | 442 | 443 | // There are several different palettes of colors demonstrated here. 444 | // 445 | // FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, 446 | // OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. 447 | // 448 | // Additionally, you can manually define your own color palettes, or you can write 449 | // code that creates color palettes on the fly. All are shown here. 450 | 451 | void ChangePalettePeriodically() 452 | { 453 | uint8_t secondHand = (millis() / 1000) % 60; 454 | static uint8_t lastSecond = 99; 455 | 456 | if (lastSecond != secondHand) { 457 | lastSecond = secondHand; 458 | if (secondHand == 0) { 459 | currentPalette = HeatColors_p; 460 | currentBlending = LINEARBLEND; 461 | } 462 | if (secondHand == 5) { 463 | currentPalette = RainbowColors_p; 464 | currentBlending = LINEARBLEND; 465 | } 466 | if (secondHand == 10) { 467 | currentPalette = RainbowStripeColors_p; 468 | currentBlending = NOBLEND; 469 | } 470 | if (secondHand == 15) { 471 | currentPalette = RainbowStripeColors_p; 472 | currentBlending = LINEARBLEND; 473 | } 474 | if (secondHand == 20) { 475 | SetupPurpleAndGreenPalette(); 476 | currentBlending = LINEARBLEND; 477 | } 478 | if (secondHand == 25) { 479 | SetupTotallyRandomPalette(); 480 | currentBlending = LINEARBLEND; 481 | } 482 | if (secondHand == 30) { 483 | SetupBlackAndWhiteStripedPalette(); 484 | currentBlending = NOBLEND; 485 | } 486 | if (secondHand == 35) { 487 | SetupBlackAndWhiteStripedPalette(); 488 | currentBlending = LINEARBLEND; 489 | } 490 | if (secondHand == 40) { 491 | currentPalette = CloudColors_p; 492 | currentBlending = LINEARBLEND; 493 | } 494 | if (secondHand == 45) { 495 | currentPalette = PartyColors_p; 496 | currentBlending = LINEARBLEND; 497 | } 498 | if (secondHand == 50) { 499 | currentPalette = myRedWhiteBluePalette_p; 500 | currentBlending = NOBLEND; 501 | } 502 | if (secondHand == 55) { 503 | currentPalette = myRedWhiteBluePalette_p; 504 | currentBlending = LINEARBLEND; 505 | } 506 | } 507 | } 508 | 509 | // This function fills the palette with totally random colors. 510 | void SetupTotallyRandomPalette() 511 | { 512 | for (int i = 0; i < 16; i++) { 513 | currentPalette[i] = CHSV(random8(), 255, random8()); 514 | } 515 | } 516 | 517 | // This function sets up a palette of black and white stripes, 518 | // using code. Since the palette is effectively an array of 519 | // sixteen CRGB colors, the various fill_* functions can be used 520 | // to set them up. 521 | void SetupBlackAndWhiteStripedPalette() 522 | { 523 | // 'black out' all 16 palette entries... 524 | fill_solid(currentPalette, 16, CRGB::Black); 525 | // and set every fourth one to white. 526 | currentPalette[0] = CRGB::White; 527 | currentPalette[4] = CRGB::White; 528 | currentPalette[8] = CRGB::White; 529 | currentPalette[12] = CRGB::White; 530 | 531 | } 532 | 533 | // This function sets up a palette of purple and green stripes. 534 | void SetupPurpleAndGreenPalette() 535 | { 536 | CRGB purple = CHSV(HUE_PURPLE, 255, 255); 537 | CRGB green = CHSV(HUE_GREEN, 255, 255); 538 | CRGB black = CRGB::Black; 539 | 540 | currentPalette = CRGBPalette16( 541 | green, green, black, black, 542 | purple, purple, black, black, 543 | green, green, black, black, 544 | purple, purple, black, black); 545 | } 546 | 547 | 548 | // This example shows how to set up a static color palette 549 | // which is stored in PROGMEM (flash), which is almost always more 550 | // plentiful than RAM. A static PROGMEM palette like this 551 | // takes up 64 bytes of flash. 552 | const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = 553 | { 554 | CRGB::Red, 555 | CRGB::Gray, // 'white' is too bright compared to red and blue 556 | CRGB::Blue, 557 | CRGB::Black, 558 | 559 | CRGB::Red, 560 | CRGB::Gray, 561 | CRGB::Blue, 562 | CRGB::Black, 563 | 564 | CRGB::Red, 565 | CRGB::Red, 566 | CRGB::Gray, 567 | CRGB::Gray, 568 | CRGB::Blue, 569 | CRGB::Blue, 570 | CRGB::Black, 571 | CRGB::Black 572 | }; 573 | 574 | 575 | 576 | // Additional notes on FastLED compact palettes: 577 | // 578 | // Normally, in computer graphics, the palette (or "color lookup table") 579 | // has 256 entries, each containing a specific 24-bit RGB color. You can then 580 | // index into the color palette using a simple 8-bit (one byte) value. 581 | // A 256-entry color palette takes up 768 bytes of RAM, which on Arduino 582 | // is quite possibly "too many" bytes. 583 | // 584 | // FastLED does offer traditional 256-element palettes, for setups that 585 | // can afford the 768-byte cost in RAM. 586 | // 587 | // However, FastLED also offers a compact alternative. FastLED offers 588 | // palettes that store 16 distinct entries, but can be accessed AS IF 589 | // they actually have 256 entries; this is accomplished by interpolating 590 | // between the 16 explicit entries to create fifteen intermediate palette 591 | // entries between each pair. 592 | // 593 | // So for example, if you set the first two explicit entries of a compact 594 | // palette to Green (0,255,0) and Blue (0,0,255), and then retrieved 595 | // the first sixteen entries from the virtual palette (of 256), you'd get 596 | // Green, followed by a smooth gradient from green-to-blue, and then Blue. 597 | 598 | 599 | 600 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jason Coon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlinkyTile + FastLED 2 | BlinkyTile control using the FastLED library and an Arduino or Teensy 3 | 4 | [![Demo Video](https://lh5.googleusercontent.com/Q2ZHcTzfXk-wNXCsgP1aF5o-MZ586nFlKrrjJZYXIBFC=s192-p-no)](https://www.youtube.com/watch?v=ZVGWRow0m3g) 5 | 6 | This tutorial will guide you through connecting a BlinkyTile sculpture (I made the standard dodecahedron) to a microcontroller. The same basic instructions will apply to just about any microcontroller, but we'll be using an Arduino Uno. I've also tested with a [Teensy 3.1](http://www.pjrc.com/store/teensy31.html). 7 | 8 | **Note**: 9 | You should already have your BlinkyTile sculpture assembled and tested with the light buddy board. See the [BlinkyTile](http://blinkytile.com) page for more information and assembly instructions. 10 | 11 | Hardware 12 | -------- 13 | * [BlinkyTile Kit](http://blinkytile.com) 14 | * [Arduino Uno](https://www.adafruit.com/product/50) 15 | * [USB A-B cable for the Arduino](https://www.adafruit.com/products/62) 16 | * [Male to male jumper wires](https://www.adafruit.com/product/758) 17 | 18 | Circuit Wiring 19 | -------------- 20 | 1. Make sure your Arduino is disconnected from your computer and is not powered on. 21 | 2. Connect the cable to the BlinkyTile adapter board. 22 | ![BlinkyTile Adapter Board](https://raw.githubusercontent.com/pup05/BlinkyTileFastLED/master/images/BlinkyTileAdapterBoard.jpg) 23 | 3. Insert male-to-male jumper wires into the other end of the BlinkyTile adapter board cable. I used red for power, blue for data, skipped the address wire, and black for ground. Double-check your connections and ensure the proper order before proceeding. You can check them with the light buddy board, if you have one. 24 | ![](https://raw.githubusercontent.com/pup05/BlinkyTileFastLED/master/images/BlinkyTileConnector.jpg) 25 | 4. Connect the other end of the jumper wires to your Arduino. Red connects to 5V, black to either GND, and blue connects to Digital 0 (RX, **not A0!**). 26 | ![](https://raw.githubusercontent.com/pup05/BlinkyTileFastLED/master/images/ArduinoConnections.jpg) 27 | 5. Check your connections again. Seriously. :) 28 | 29 | Software 30 | -------- 31 | 1. We'll be using the Arduino software to program the microcontroller. Download and install 1.0.6 (**not 1.5.x**): http://arduino.cc/en/Main/Software 32 | 2. The FastLED library will be used to control the BlinkyTile LEDs. Download the latest version (3.0 or newer) from the releases page: https://github.com/FastLED/FastLED/releases 33 | 3. The DmxSimple library will be used by FastLED internally. Download it here: https://github.com/PaulStoffregen/DmxSimple 34 | 4. Follow these instructions to install the FastLED and DmxSimple libraries: http://arduino.cc/en/Guide/Libraries 35 | 36 | Code 37 | ----------- 38 | 1. Start the Arduino software if it's not already running (make sure you restart it after installing the libraries). 39 | 2. Create a new sketch (program) by clicking the New button, or the File->New menu. 40 | 3. Copy the code from here: https://raw.githubusercontent.com/pup05/BlinkyTileFastLED/master/BlinkyTileFastLED.ino 41 | 4. Paste it into the Arduino editor. 42 | 5. Click the Verify button. If it fails to compile with errors, ensure you followed the steps above. If you're still having problems, feel free to open an issue here: https://github.com/pup05/BlinkyTileFastLED/issues 43 | 44 | Upload 45 | ------ 46 | 1. Connect your Arduino to your computer's USB port using the proper cable. The ON light should turn on, but your BlinkyTile will probably not light up. 47 | 2. Click the Upload button. After it completes, your BlinkyTile sculpture should light up and start cycling through several different patterns. The cycle takes about a minute to complete before it restarts again. 48 | 49 | Conclusion 50 | ---------- 51 | That's all for now. In part two (coming soon), I'll walk you through creating your very own patterns using FastLED! 52 | -------------------------------------------------------------------------------- /images/ArduinoConnections.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasoncoon/BlinkyTileFastLED/0e44c64f70282fec92e6126bd4c0e04a2bde43d3/images/ArduinoConnections.jpg -------------------------------------------------------------------------------- /images/BlinkyTileAdapterBoard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasoncoon/BlinkyTileFastLED/0e44c64f70282fec92e6126bd4c0e04a2bde43d3/images/BlinkyTileAdapterBoard.jpg -------------------------------------------------------------------------------- /images/BlinkyTileConnector.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasoncoon/BlinkyTileFastLED/0e44c64f70282fec92e6126bd4c0e04a2bde43d3/images/BlinkyTileConnector.jpg --------------------------------------------------------------------------------