Disco Doll Dance Floor

I made this for my daughter to have a dance party with her LOL dolls.
19
46
0
470
updated March 7, 2024

Description

PDF

This model uses a 60 LEDs a meter WS2812b strip and a SPI LED controller. Each strip is 10 leds and there's 10 strips. So it's a 10x10 matrix ran in a zig zag pattern. 

Alternatively you can get a 16x16 LED matrix and use the 16x16 model.

You can also program an arduino with adafruit or fastLED. Here's a nice dual rainbow animation for a 16x16 WS2812B matrix from fastLED.

#include <FastLED.h>
#define LED_PIN  13

#define COLOR_ORDER GRB

#define CHIPSET     WS2812B

#define BRIGHTNESS 10

 

// Helper functions for an two-dimensional XY matrix of pixels.

// Simple 2-D demo code is included as well.

//

//     XY(x,y) takes x and y coordinates and returns an LED index number,

//             for use like this:  leds[ XY(x,y) ] == CRGB::Red;

//             No error checking is performed on the ranges of x and y.

//

//     XYsafe(x,y) takes x and y coordinates and returns an LED index number,

//             for use like this:  leds[ XY(x,y) ] == CRGB::Red;

//             Error checking IS performed on the ranges of x and y, and an

//             index of "-1" is returned.  Special instructions below

//             explain how to use this without having to do your own error

//             checking every time you use this function.  

//             This is a slightly more advanced technique, and

//             it REQUIRES SPECIAL ADDITIONAL setup, described below.

 

// Params for width and height

const uint8_t kMatrixWidth = 16;

const uint8_t kMatrixHeight = 16;

 

// Param for different pixel layouts

const bool    kMatrixSerpentineLayout = true;

// Set 'kMatrixSerpentineLayout' to false if your pixels are

// laid out all running the same way, like this:

//

//     0 >  1 >  2 >  3 >  4

//                         |

//     .----<----<----<----'

//     |

//     5 >  6 >  7 >  8 >  9

//                         |

//     .----<----<----<----'

//     |

//    10 > 11 > 12 > 13 > 14

//                         |

//     .----<----<----<----'

//     |

//    15 > 16 > 17 > 18 > 19

//

// Set 'kMatrixSerpentineLayout' to true if your pixels are

// laid out back-and-forth, like this:

//

//     0 >  1 >  2 >  3 >  4

//                         |

//                         |

//     9 <  8 <  7 <  6 <  5

//     |

//     |

//    10 > 11 > 12 > 13 > 14

//                        |

//                        |

//    19 < 18 < 17 < 16 < 15

//

// Bonus vocabulary word: anything that goes one way

// in one row, and then backwards in the next row, and so on

// is call "boustrophedon", meaning "as the ox plows."

 

// This function will return the right 'led index number' for

// a given set of X and Y coordinates on your matrix.  

// IT DOES NOT CHECK THE COORDINATE BOUNDARIES.  

// That's up to you.  Don't pass it bogus values.

//

// Use the "XY" function like this:

//

//    for( uint8_t x = 0; x < kMatrixWidth; x++) {

//      for( uint8_t y = 0; y < kMatrixHeight; y++) {

//      

//        // Here's the x, y to 'led index' in action:

//        leds[ XY( x, y) ] = CHSV( random8(), 255, 255);

//      

//      }

//    }

//

//

uint16_t XY( uint8_t x, uint8_t y)

{

  uint16_t i;

 

  if( kMatrixSerpentineLayout == false) {

    i = (y * kMatrixWidth) + x;

  }

 

  if( kMatrixSerpentineLayout == true) {

    if( y & 0x01) {

      // Odd rows run backwards

      uint8_t reverseX = (kMatrixWidth - 1) - x;

      i = (y * kMatrixWidth) + reverseX;

    } else {

      // Even rows run forwards

      i = (y * kMatrixWidth) + x;

    }

  }

 

  return i;

}


 

// Once you've gotten the basics working (AND NOT UNTIL THEN!)

// here's a helpful technique that can be tricky to set up, but

// then helps you avoid the needs for sprinkling array-bound-checking

// throughout your code.

//

// It requires a careful attention to get it set up correctly, but

// can potentially make your code smaller and faster.

//

// Suppose you have an 8 x 5 matrix of 40 LEDs.  Normally, you'd

// delcare your leds array like this:

//    CRGB leds[40];

// But instead of that, declare an LED buffer with one extra pixel in

// it, "leds_plus_safety_pixel".  Then declare "leds" as a pointer to

// that array, but starting with the 2nd element (id=1) of that array:

//    CRGB leds_with_safety_pixel[41];

//    CRGB* const leds( leds_plus_safety_pixel + 1);

// Then you use the "leds" array as you normally would.

// Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]",

// AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0].

// leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel".

//

// Now instead of using the XY function above, use the one below, "XYsafe".

//

// If the X and Y values are 'in bounds', this function will return an index

// into the visible led array, same as "XY" does.

// HOWEVER -- and this is the trick -- if the X or Y values

// are out of bounds, this function will return an index of -1.

// And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0],

// it's a totally safe and legal place to access.  And since the 'safety pixel'

// falls 'outside' the visible part of the LED array, anything you write

// there is hidden from view automatically.

// Thus, this line of code is totally safe, regardless of the actual size of

// your matrix:

//    leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255);

//

// The only catch here is that while this makes it safe to read from and

// write to 'any pixel', there's really only ONE 'safety pixel'.  No matter

// what out-of-bounds coordinates you write to, you'll really be writing to

// that one safety pixel.  And if you try to READ from the safety pixel,

// you'll read whatever was written there last, reglardless of what coordinates

// were supplied.


 

#define NUM_LEDS (kMatrixWidth * kMatrixHeight)

CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];

CRGB* const leds( leds_plus_safety_pixel + 1);


 

uint16_t XYsafe( uint8_t x, uint8_t y)

{

  if( x >= kMatrixWidth) return -1;

  if( y >= kMatrixHeight) return -1;

  return XY(x,y);

}



 

// Demo that USES "XY" follows code below


 

void loop()

{

    uint32_t ms = millis();

    int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth));

    int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight));

    DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);

    if( ms < 5000 ) {

      FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));

    } else {

      FastLED.setBrightness(BRIGHTNESS);

    }

    FastLED.show();

}


 

void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)

{

  byte lineStartHue = startHue8;

  for( byte y = 0; y < kMatrixHeight; y++) {

    lineStartHue += yHueDelta8;

    byte pixelHue = lineStartHue;      

    for( byte x = 0; x < kMatrixWidth; x++) {

      pixelHue += xHueDelta8;

      leds[ XY(x, y)]  = CHSV( pixelHue, 255, 255);

    }

  }

}



 

void setup() {

  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);

  FastLED.setBrightness( BRIGHTNESS );

}


 

Tags



Model origin

The author marked this model as their own original creation.

License