|
|
Line 1: |
Line 1: |
− | =Code Sample=
| |
− | ==Forward==
| |
− | <pre>
| |
− | #include <FastLED.h>
| |
− |
| |
− | #define LED_PIN A0
| |
− |
| |
− | #define COLOR_ORDER GRB
| |
− | #define CHIPSET WS2811
| |
− |
| |
− | #define BRIGHTNESS 255
| |
− |
| |
− | // 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[ XYsafe(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 = 8;
| |
− | const uint8_t kMatrixHeight = 8;
| |
− |
| |
− | // Param for different pixel layouts
| |
− | const bool kMatrixSerpentineLayout = true;
| |
− | const bool kMatrixVertical = false;
| |
− |
| |
− | // 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) {
| |
− | if (kMatrixVertical == false) {
| |
− | i = (y * kMatrixWidth) + x;
| |
− | } else {
| |
− | i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
| |
− | }
| |
− | }
| |
− |
| |
− | if( kMatrixSerpentineLayout == true) {
| |
− | if (kMatrixVertical == false) {
| |
− | 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;
| |
− | }
| |
− | } else { // vertical positioning
| |
− | if ( x & 0x01) {
| |
− | i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
| |
− | } else {
| |
− | i = kMatrixHeight * (kMatrixWidth - x) - (y+1);
| |
− | }
| |
− | }
| |
− | }
| |
− |
| |
− | 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( uint8_t startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
| |
− | {
| |
− | uint8_t lineStartHue = startHue8;
| |
− | for( uint8_t y = 0; y < kMatrixHeight; y++) {
| |
− | lineStartHue += yHueDelta8;
| |
− | uint8_t pixelHue = lineStartHue;
| |
− | for( uint8_t 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 );
| |
− | }
| |
− | </pre>
| |
− | [[Image:1-froward-1.gif|337*337]]
| |
− | [[Image:1-froward-2.gif|337*337]]
| |
− |
| |
| =Download resource= | | =Download resource= |
− | *[http://s3.amazonaws.com/s3.image.smart/download/101-20-146/17DOF%20Robot%20Assemble%20Guide.docx 17DOF Robot Assemble Guide] | + | *[http://s3.amazonaws.com/s3.image.smart/download/101-50-FLM/Arduino_control_LED_matrix_panel_simple_guide.docx Arduino Control LED Matrix Panel Simple Guide] |
| + | *[http://s3.amazonaws.com/s3.image.smart/download/101-50-FLM/Flexible_LED_Matrix_Panel.MP4 Flexible LED Matrix Panel.MP4] |
| + | *[http://s3.amazonaws.com/s3.image.smart/download/101-50-FLM/sample_code.zip Sample Code] |