#include <FastLED.h>
#include <Bounce2.h>
#define LED_PIN 14
#define BUTTON1_PIN 17
#define BUTTON2_PIN 27
#define COLOR_ORDER GRB
#define CHIPSET WS2812B
#define NUM_LEDS 300
const uint8_t MATRIX_WIDTH = 13;
const uint8_t MATRIX_HEIGHT = 23;
uint8_t brightnessMap[3] = {64, 128, 255};
uint8_t brightness = brightnessMap[2];
CRGB leds[NUM_LEDS + 1];
typedef uint16_t (*PatternFunctionPointer)();
typedef PatternFunctionPointer PatternList[];
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
int currentPatternIndex = 0;
PatternFunctionPointer currentPattern;
int currentPaletteIndex = 1;
Bounce button1 = Bounce();
Bounce button2 = Bounce();
#define WIDTH MATRIX_WIDTH
#define HEIGHT MATRIX_HEIGHT
#define LED_ROWS MATRIX_HEIGHT
#define LED_COLS MATRIX_WIDTH
byte scale = 64;
byte speed = 32;
static uint32_t t;
CRGBPalette16 gPalR = HeatColors_p;
CRGBPalette16 gPalG { CRGB::Black, CRGB::DarkGreen, CRGB::Green, CRGB::LightGreen};
CRGBPalette16 gPalB {CRGB::Black, CRGB::Blue, CRGB::LightBlue, CRGB::Aqua};
CRGBPalette16 gPals[3] = {gPalR, gPalG, gPalB};
uint8_t gPal_idx = 0;
uint16_t fire() {
t += speed;
for (byte x = 0; x < LED_COLS; x++) {
for (byte y = 0; y < LED_ROWS; y++) {
int16_t Bri = inoise8(x * scale, (y * scale) - t) - (y * (255 / LED_ROWS));
byte Col = Bri;// inoise8(x * scale, (y * scale) - t) - (y * (255 / LED_ROWS));
if (Bri < 0) Bri = 0; if(Bri != 0) Bri = 256 - (Bri * 0.2);
nblend(leds[XY(x, (LED_ROWS-1)-y)], ColorFromPalette(gPals[gPal_idx], Col, Bri), speed);}
}
return 1;
}
const PatternList patterns = {
fire,
/*fire,
fire,
solid,
multicolorPerlin,
lavat,
lavalamp,
stars,
storm,
hourglass,
//fire2012WithPalette,
leapers,
//zebra,
wind,
//twister,
//fire_old_school,
ocean3D,
//matrix
waterfall,
snakes,
aurora,
plasma,
whirls,
watercolor,
boiling,
fire2012WithPalette,
fire2012WithPalette,
fire2012WithPalette,
torch,
torch2,
torch3,
coral_reef,
teeth_and_blood,
fire_and_cold,
candy_dreams,
texan_night,
desert_winds,
lava_lamp1,
lava_lamp2,
fireNoise,
fireNoise_rev2,
lavaNoise,
partyNoise,
blackAndGreenNoise,
blackAndFireNoise,
blackAndMagentaNoise,
*/
};
const int patternCount = ARRAY_SIZE(patterns);
void setup() {
delay(500); // sanity delay
Serial.begin(115200);
Serial.println("setup start");
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setCorrection(TypicalLEDStrip);
FastLED.setBrightness(brightness);
// FastLED.setDither(false);
FastLED.setDither(brightness < 255);
button1.attach(BUTTON1_PIN);
button1.interval(5);
button2.attach(BUTTON2_PIN);
button2.interval(5);
currentPattern = patterns[currentPatternIndex];
}
void loop() {
// Add entropy to random number generator; we use a lot of it.
random16_add_entropy(esp_random());
currentPattern();
FastLED.show(); // display this frame
if (button1.update())
{
if (button1.rose())
{
move(1);
}
}
if (button2.update())
{
if (button2.rose())
{
turn_off();
}
}
}
void turn_off()
{
fill_solid(leds, NUM_LEDS, CRGB::Black);
FastLED.show();
while (true)
{
button1.update();
button2.update();
if (button1.rose() || button2.rose())
return;
}
}
void dimAll(byte value)
{
for (int i = 0; i < NUM_LEDS; i++) {
leds[i].nscale8(value);
}
}
void move(int delta)
{
moveTo(currentPatternIndex + delta);
}
void moveTo(int index)
{
currentPatternIndex = index;
gPal_idx = index;
if (currentPatternIndex >= patternCount)
{
currentPatternIndex = 0;
gPal_idx = 0;
}
else if (currentPatternIndex < 0)
{
currentPatternIndex = patternCount - 1;
}
currentPattern = patterns[currentPatternIndex];
fill_solid(leds, NUM_LEDS, CRGB::Black);
}
uint16_t XY(uint8_t x, uint8_t y) // maps the matrix to the strip
{
uint16_t i;
i = (y * MATRIX_WIDTH) + (MATRIX_WIDTH - x);
i = (NUM_LEDS - 1) - i;
if (i > NUM_LEDS)
i = NUM_LEDS;
return i;
}