``````// Here's one last, really fun one from Mark Kriegsman

#include <FastLED.h>

#define DATA_PIN    3
#define LED_COLS    16
#define LED_ROWS    16
#define BRIGHTNESS  255
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB

#define NUM_LEDS    LED_ROWS * LED_COLS

// Define the array of leds
CRGB leds[NUM_LEDS];

void setup() {
FastLED.setBrightness(BRIGHTNESS);
}

uint16_t XY(uint8_t x, uint8_t y) {
return (y * LED_ROWS + x);
}

// Code above draw() only runs once, to set up our variables
uint32_t hue = 0;

const uint8_t kMatrixWidth = LED_COLS;
const uint8_t kMatrixHeight = LED_ROWS;
const uint8_t kBorderWidth = 2;

void draw() {
// Apply some blurring to whatever's already on the matrix
// Note that we never actually clear the matrix, we just constantly
// blur it repeatedly. Since the blurring is 'lossy', there's
// an automatic trend toward black -- by design.
uint8_t blurAmount = 20; // beatsin8(2, 10, 255);
blur2d(leds, kMatrixWidth, kMatrixHeight, blurAmount);

// Use two out-of-sync sine waves
uint8_t i = beatsin8(27, kBorderWidth, kMatrixHeight - kBorderWidth);
uint8_t j = beatsin8(41, kBorderWidth, kMatrixWidth - kBorderWidth);

// Also calculate some reflections
uint8_t ni = (kMatrixWidth - 1) - i;
uint8_t nj = (kMatrixWidth - 1) - j;

// The color of each point shifts over time, each at a different speed.
uint16_t ms = millis();

leds[XY(i, j)] += CHSV(ms / 11, 200, 255);
leds[XY(j, i)] += CHSV(ms / 13, 200, 255);
leds[XY(ni, nj)] += CHSV(ms / 17, 200, 255);
leds[XY(nj, ni)] += CHSV(ms / 29, 200, 255);
leds[XY(i, nj)] += CHSV(ms / 37, 200, 255);
leds[XY(ni, j)] += CHSV(ms / 41, 200, 255);

FastLED.show();