#include "FastLED.h"
// Matrix size
#define NUM_ROWS 16
#define NUM_COLS 16
#define WIDTH NUM_COLS
#define HEIGHT NUM_ROWS
#define NUM_LEDS NUM_ROWS * NUM_COLS
#define MATRIX_TYPE 1
// LEDs pin
#define DATA_PIN 3
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS];
//PaletteTester
byte type;
byte pal;
#define WIDTH NUM_COLS
#define HEIGHT NUM_ROWS
void fillAll(CRGB color) {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = color;
}
}
void drawPixelXY(uint8_t x, uint8_t y, CRGB color)
{
if (x < 0 || x > (WIDTH - 1) || y < 0 || y > (HEIGHT - 1)) return;
uint32_t thisPixel = XY((uint8_t)x, (uint8_t)y);
leds[thisPixel] = color;
}
// The 16 bit version of our coordinates
static uint16_t x;
static uint16_t y;
static uint16_t z;
uint16_t speed = 20; // speed is set dynamically once we've started up
uint16_t scale = 30; // scale is set dynamically once we've started up
// This is the array that we keep our computed noise values in
#define MAX_DIMENSION (max(WIDTH, HEIGHT))
#if (WIDTH > HEIGHT)
uint8_t noise[WIDTH][WIDTH];
#else
uint8_t noise[HEIGHT][HEIGHT];
#endif
static const TProgmemRGBPalette16 StepkosColors_p FL_PROGMEM = {0x0000ff, 0x0f00f0, 0x1e00e1, 0x2d00d2, 0x3c00c3, 0x4b00b4, 0x5a00a5, 0x690096, 0x780087, 0x870078, 0x9600cd, 0xa50050, 0xb40041, 0xc30032, 0xd20023, 0xe10014};
static const TProgmemRGBPalette16 AutumnColors_p FL_PROGMEM = {0xbc2300, 0xc84416, 0xdc642c, 0xe69664, 0xfbb979, 0xca503d, 0x882c1c, 0x9a3631, 0xa9624e, 0xcc9762, 0xdcc0b5, 0xc1a29f, 0x826468, 0x4a3334, 0x231a1a, 0x161113};
static const TProgmemRGBPalette16 NeonColors_p FL_PROGMEM = {0x9694ac, 0x979b9b, 0x888b8c, 0x767680, 0x696f77, 0x6c736f, 0x4097b8, 0x00b1d0, 0x0f93ec, 0x3572ff, 0x4157ff, 0x6162ff, 0x686cff, 0x7473ff, 0x8689e5, 0x9e9dc6};
static const TProgmemRGBPalette16 EveningColors_p FL_PROGMEM = {0x1e0443, 0x6d0081, 0x8200ac, 0x8200ac, 0x8200ac, 0x8200ac, 0x8200ac, 0x8200ac, 0x7900a1, 0x820055, 0xc80000, 0xe57b00, 0xff9d5a, 0xc58b32, 0xd8d400, 0xffff00};
static const TProgmemRGBPalette16 WoodColors_p FL_PROGMEM = {0xcdb1a5, 0x7a4000, 0xcdb1a5, 0x7a4000, 0xcdb1a5, 0x7a4000, 0xcdb1a5, 0x7a4000, 0xcdb1a5, 0x7a4000, 0xcdb1a5, 0x7a4000, 0xcdb1a5, 0x7a4000, 0xcdb1a5, 0x7a4000};
static const TProgmemRGBPalette16 ZeebraColors_p FL_PROGMEM = {CRGB::White, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::White, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::White, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::White, CRGB::Black, CRGB::Black, CRGB::Black};
static const TProgmemRGBPalette16 WaterfallColors_p FL_PROGMEM = {0x000000, 0x060707, 0x101110, 0x151717, 0x1C1D22, 0x242A28, 0x363B3A, 0x313634, 0x505552, 0x6B6C70, 0x98A4A1, 0xC1C2C1, 0xCACECF, 0xCDDEDD, 0xDEDFE0, 0xB2BAB9};
static const TProgmemRGBPalette16 MercuryColors_p FL_PROGMEM = {0xffffff, 0xeeeeee, 0xdddddd, 0xcccccc, 0xbbbbbb, 0xaaaaaa, 0x999999, 0x888888, 0x777777, 0x666666, 0x555555, 0x444444, 0x333333, 0x222222, 0x111111, 0x000000};
static const TProgmemRGBPalette16 StepkosFireColors_p FL_PROGMEM = {0x000000, 0x0e0070, 0x1d00ad, 0x2d00c8, 0x3c00c3, 0x4b00b4, 0x5a00a5, 0x690096, 0x780087, 0x870078, 0x9600cd, 0xa50050, 0xb40041, 0xc30032, 0xd20023, 0xe10014};
static const TProgmemRGBPalette16 LakeColors_p FL_PROGMEM = {0x611de9, 0x7d7cf0, 0xa784f9, 0x8cb1ed, 0x7fffd4, 0x5ad5ec, 0x3399ff, 0x66afff, 0x50ffc1, 0x61d1e5, 0x68ff8d, 0x98ff61, 0xccff47, 0x7eff00, 0x53ff00, 0x00ff00};
static const TProgmemRGBPalette16 OrangeColors_p FL_PROGMEM = {0xffff00, 0xfff100, 0xffe100, 0xffd100, 0xffc100, 0xffb100, 0xffa100, 0xff9100, 0xff8100, 0xff7100, 0xff6100, 0xff5100, 0xff4100, 0xff3100, 0xff2100, 0xff1100};
static const TProgmemRGBPalette16 AcidColors_p FL_PROGMEM = {0xffff00, 0xd2b328, 0xd25228, 0x711323, 0x6c000c, 0x5a0c00, 0x6d373a, 0xaa5a62, 0x604564, 0x313164, 0x332765, 0x3a2465, 0x4b1665, 0x4b0069, 0x31004c, 0x200046};
static const TProgmemRGBPalette16 Hol_LightsColors_p FL_PROGMEM = {0x00ff00, 0x00c040, 0x008080, 0x0040c0, 0x0000ff, 0x4000c0, 0x800080, 0xc00040, 0xff0000, 0xff4000, 0xff8000, 0xd6c000, 0xffff00, 0xc0ff00, 0x80ff00, 0x40ff00};
extern const TProgmemRGBPalette16 AuroraColors_p1 FL_PROGMEM ={0x000000,0x162c2c, 0x55abab, 0x00FFFF, 0x55ABAB, 0x2c5555,0x162c2c, 0x000000, 0x000000, 0x000000,0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00000};
extern const TProgmemRGBPalette16 AuroraColors_p FL_PROGMEM ={0x000000, 0x003333, 0x006666, 0x009999, 0x00cccc,0x00ffff, 0x33ffff, 0x66ffff, 0x99ffff,0xccffff, 0xffffff, 0xffccff, 0xff99ff, 0xff66ff, 0xff33ff, 0xff00ff};
const TProgmemRGBPalette16 *palette_arr[] = {
&AuroraColors_p,
&PartyColors_p,
&OceanColors_p,
&LavaColors_p,
&HeatColors_p,
&ZeebraColors_p,
&WaterfallColors_p,
&CloudColors_p,
&ForestColors_p,
&RainbowColors_p,
&RainbowStripeColors_p,
&StepkosColors_p,
&AutumnColors_p,
&NeonColors_p,
&AcidColors_p,
&MercuryColors_p,
&EveningColors_p,
&LakeColors_p,
&OrangeColors_p,
&WoodColors_p,
&AuroraColors_p1,
&Hol_LightsColors_p
};
const TProgmemRGBPalette16 *curPalette = palette_arr[0];
void setCurrentPalette(uint8_t palIdx) {
curPalette = palette_arr[palIdx];
}
uint8_t hue;
CRGB color;
bool loadingFlag = true;
int rad[(HEIGHT + WIDTH) / 8];
byte posx[(HEIGHT + WIDTH) / 8], posy[(HEIGHT + WIDTH) / 8];
void drawCircle(int x0, int y0, int radius, const CRGB &color) {
int a = radius, b = 0;
int radiusError = 1 - a;
if (radius == 0) {
drawPixelXY(x0, y0, color);
return;
}
while (a >= b) {
drawPixelXY(a + x0, b + y0, color);
drawPixelXY(b + x0, a + y0, color);
drawPixelXY(-a + x0, b + y0, color);
drawPixelXY(-b + x0, a + y0, color);
drawPixelXY(-a + x0, -b + y0, color);
drawPixelXY(-b + x0, -a + y0, color);
drawPixelXY(a + x0, -b + y0, color);
drawPixelXY(b + x0, -a + y0, color);
b++;
if (radiusError < 0)
radiusError += 2 * b + 1;
else
{
a--;
radiusError += 2 * (b - a + 1);
}
}
}
void Enoise() {
if (loadingFlag)
{ loadingFlag = false;
setCurrentPalette(pal);
}
static bool eff =1;
EVERY_N_MILLISECONDS(25000) { eff^=1; } //speed of effect change
uint32_t ms = millis();
for (byte y = 0; y < NUM_ROWS; y++) {
for (byte x = 0; x < NUM_COLS; x++) {
uint16_t pixelHue = inoise16 ((uint32_t)x*5000, (uint32_t)y*5000+ms*10,ms*20);
uint8_t pixelHue8 = inoise8 (x*15, y*15+ms/8,ms/70);
leds[XY(x, y)] = ColorFromPalette(*curPalette, pixelHue8+ms/20, 255, LINEARBLEND);}
}
}
void drop() {
if (loadingFlag)
{ loadingFlag = false;
setCurrentPalette(pal);
for (int i = 0; i < ((HEIGHT + WIDTH) / 8) - 1; i++)
{
posx[i] = random(WIDTH);
posy[i] = random(HEIGHT);
rad[i] = random(-1, (HEIGHT + WIDTH) / 2);
}
}
fillAll(ColorFromPalette(*curPalette, hue));
hue++;
for (uint8_t i = 0; i < ((HEIGHT + WIDTH) / 8) - 1; i++)
{
drawCircle(posx[i], posy[i], rad[i], ColorFromPalette(*curPalette, (256 / 16) * 8.5 - rad[i] * 5 + hue));
drawCircle(posx[i], posy[i], rad[i] - 1, ColorFromPalette(*curPalette, (256 / 16) * 7.5 - rad[i] * 5 + hue));
if (rad[i] >= (HEIGHT + WIDTH) / 2) {
rad[i] = -1;
posx[i] = random(WIDTH);
posy[i] = random(HEIGHT);
}
else
rad[i]++;
}
}
void rainbowHorVertRoutine(bool isVertical)
{ if (loadingFlag)
{ loadingFlag = false;
setCurrentPalette(pal);
} hue += 4;
for (uint8_t i = 0U; i < (isVertical ? WIDTH : HEIGHT); i++)
{
for (uint8_t j = 0U; j < (isVertical ? HEIGHT : WIDTH); j++)
{
drawPixelXY((isVertical ? i : j), (isVertical ? j : i), ColorFromPalette(*curPalette, (uint8_t)(hue + i * 10)));
}
}
}
// Yaroslaw Turbin, 22.06.2020
// https://vk.com/ldirko
// https://pastebin.com/eKqe4zzA
void Fire() {
if (loadingFlag)
{ loadingFlag = false;
setCurrentPalette(pal);
}
uint8_t speedy = 1;
uint8_t _scale = 120;
uint32_t a = millis();
for (byte i = 0U; i < WIDTH; i++) {
for (byte j = 0U; j < HEIGHT; j++) {
drawPixelXY((WIDTH - 1) - i, j, ColorFromPalette(*curPalette, qsub8(inoise8(i * _scale, j * _scale + a, a / speedy), abs8(j - (HEIGHT - 1)) * 255 / (HEIGHT - 1)), 255));
}
}
}
//Metaballs
//16x16 rgb led matrix demo
//Yaroslaw Turbin 02.09.2020
//https://vk.com/ldirko
//https://www.reddit.com/user/ldirko/
uint8_t bx[5];
uint8_t by[5];
void meta() {
if (loadingFlag)
{ loadingFlag = false;
setCurrentPalette(pal);
}
for (uint8_t a = 0; a < 5; a++) {
bx[a] = beatsin8(15 + a * 2, 0, NUM_COLS - 1, 0, a * 32);
by[a] = beatsin8(18 + a * 2, 0, NUM_ROWS - 1, 0, a * 32);
}
for (int i = 0; i < NUM_COLS; i++) {
for (int j = 0; j < NUM_ROWS; j++) {
byte sum = dist(i, j, bx[0], by[0]);
for (uint8_t a = 1; a < 5; a++) {
sum = qadd8(sum, dist(i, j, bx[a], by[a]));
}
leds[XY (i, j)] = ColorFromPalette(*curPalette, sum + 220, BRIGHTNESS);
}
}
blur2d(leds, NUM_COLS, NUM_ROWS, 32 );
}
// (c) kostyamat 05.02.2021
// idea from https://www.reddit.com/r/FastLED/comments/jyly1e/challenge_fastled_sketch_that_fits_entirely_in_a/
// Thanks to https://www.reddit.com/user/ldirko/ Yaroslaw Turbin aka ldirko // особая благодарность https://www.reddit.com/user/ldirko/ Yaroslaw Turbin aka ldirko
unsigned long timer;
float adjastHeight;
uint16_t adjScale;
uint16_t _scale;
void aurora() {
if (loadingFlag)
{ loadingFlag = false;
setCurrentPalette(pal);
adjastHeight = map((float)HEIGHT, 8, 32, 28, 12);
adjScale = map((int)WIDTH, 8, 32, 310, 127);
}
byte _speed = 16;
_scale = adjScale-55;
for (byte x = 0; x < WIDTH; x++) {
for (byte y = 0; y < HEIGHT; y++) {
timer++;
uint16_t i = x*y;
leds[XY(x, y)]=
ColorFromPalette(*curPalette,
qsub8(
inoise8(i % 2 + x * _scale,
y * 16 + timer % 16,
timer / _speed
),
fabs((float)HEIGHT/2. - (float)y) * adjastHeight
)
);
//CRGB temColor = leds[XY(x, y)];
//leds[XY(x, y)].g = temColor.r;
//leds[XY(x, y)].r = temColor.g;
//leds[XY(x, y)].g /= 6;
//leds[XY(x, y)].r += leds[XY(x, y)].r < 206 ? 48 : 0;
// leds[XY(x, y)].b += 48;
//leds[XY(x, y)].g += leds[XY(x, y)].g < 206 ? 48 : 0;
}}}
//loop
byte dist (uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
int a = y2 - y1;
int b = x2 - x1;
a *= a;
b *= b;
byte dist = 220 / sqrt16(a + b);
return dist;
}
void Wave() {
if (loadingFlag)
{ loadingFlag = false;
setCurrentPalette(pal);
}
FastLED.clear();
for(byte i=0; i < NUM_COLS; i++) {
byte thisVal = inoise8(i * 45 ,millis(), millis());
byte thisMax = map(thisVal, 0, 255, 0, NUM_ROWS);
for(byte j = 0; j < thisMax; j++) {
leds[XY(i, j)] = ColorFromPalette(*curPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND);
leds[XY((NUM_COLS-1)-i, (NUM_ROWS-1)-j)] = ColorFromPalette(*curPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND);
}}
}
void draw() {
switch (type) {
case 0: Enoise(); break;
case 1: drop(); break;
case 2: rainbowHorVertRoutine(true); break;
case 3: meta(); break;
case 4: Fire(); break;
case 5: aurora();break;
case 6: Wave();break;
}
}
void setup() {
//Serial.begin(250000);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
pinMode(2, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
}
void loop() {
bool buttonPressed = digitalRead(2) == LOW;
bool buttonPressed2 = digitalRead(4) == LOW;
draw();
if (buttonPressed) {
if (pal >= 21) {
pal = 0;
} else {
pal += 1;
}
FastLED.clear();
loadingFlag = true;
delay(100);
} else if (buttonPressed2) {
if (type >= 6) {
type = 0;
} else {
type += 1;
}
FastLED.clear();
loadingFlag = true;
delay(100);
} else {
FastLED.show();
FastLED.delay(1000 / 60);
}
//static int frame = 0;
//if (frame++ % 32 == 0)
// Serial.println(FastLED.getFPS());
} //loop
uint16_t XY (uint8_t x, uint8_t y) {
return (y * NUM_COLS + x);
}
FPS: 0
Power: 0.00W
Power: 0.00W