Files
gunner47-GyverLamp/firmware/GyverLamp_v1.4/effects.ino

395 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============= ЭФФЕКТЫ ===============
// ------------- конфетти --------------
void sparklesRoutine()
{
for (uint8_t i = 0; i < modes[0].scale; i++)
{
uint8_t x = random(0, WIDTH);
uint8_t y = random(0, HEIGHT);
if (getPixColorXY(x, y) == 0)
leds[getPixelNumber(x, y)] = CHSV(random(0, 255), 255, 255);
}
fader(70);
}
// функция плавного угасания цвета для всех пикселей
void fader(uint8_t step)
{
for (uint8_t i = 0; i < WIDTH; i++)
{
for (uint8_t j = 0; j < HEIGHT; j++)
{
fadePixel(i, j, step);
}
}
}
void fadePixel(uint8_t i, uint8_t j, uint8_t step) // новый фейдер
{
int32_t pixelNum = getPixelNumber(i, j);
if (getPixColor(pixelNum) == 0) return;
if (leds[pixelNum].r >= 30 ||
leds[pixelNum].g >= 30 ||
leds[pixelNum].b >= 30)
{
leds[pixelNum].fadeToBlackBy(step);
}
else
{
leds[pixelNum] = 0;
}
}
// ------------- огонь -----------------
#define SPARKLES 1 // вылетающие угольки вкл выкл
unsigned char line[WIDTH];
int32_t pcnt = 0;
//these values are substracetd from the generated values to give a shape to the animation
const unsigned char valueMask[8][16] PROGMEM =
{
{32 , 0 , 0 , 0 , 0 , 0 , 0 , 32 , 32 , 0 , 0 , 0 , 0 , 0 , 0 , 32 },
{64 , 0 , 0 , 0 , 0 , 0 , 0 , 64 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 64 },
{96 , 32 , 0 , 0 , 0 , 0 , 32 , 96 , 96 , 32 , 0 , 0 , 0 , 0 , 32 , 96 },
{128, 64 , 32 , 0 , 0 , 32 , 64 , 128, 128, 64 , 32 , 0 , 0 , 32 , 64 , 128},
{160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 160, 96 , 64 , 32 , 32 , 64 , 96 , 160},
{192, 128, 96 , 64 , 64 , 96 , 128, 192, 192, 128, 96 , 64 , 64 , 96 , 128, 192},
{255, 160, 128, 96 , 96 , 128, 160, 255, 255, 160, 128, 96 , 96 , 128, 160, 255},
{255, 192, 160, 128, 128, 160, 192, 255, 255, 192, 160, 128, 128, 160, 192, 255}
};
//these are the hues for the fire,
//should be between 0 (red) to about 25 (yellow)
const unsigned char hueMask[8][16] PROGMEM =
{
{1 , 11, 19, 25, 25, 22, 11, 1 , 1 , 11, 19, 25, 25, 22, 11, 1 },
{1 , 8 , 13, 19, 25, 19, 8 , 1 , 1 , 8 , 13, 19, 25, 19, 8 , 1 },
{1 , 8 , 13, 16, 19, 16, 8 , 1 , 1 , 8 , 13, 16, 19, 16, 8 , 1 },
{1 , 5 , 11, 13, 13, 13, 5 , 1 , 1 , 5 , 11, 13, 13, 13, 5 , 1 },
{1 , 5 , 11, 11, 11, 11, 5 , 1 , 1 , 5 , 11, 11, 11, 11, 5 , 1 },
{0 , 1 , 5 , 8 , 8 , 5 , 1 , 0 , 0 , 1 , 5 , 8 , 8 , 5 , 1 , 0 },
{0 , 0 , 1 , 5 , 5 , 1 , 0 , 0 , 0 , 0 , 1 , 5 , 5 , 1 , 0 , 0 },
{0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 }
};
void fireRoutine()
{
if (loadingFlag)
{
loadingFlag = false;
//FastLED.clear();
generateLine();
}
if (pcnt >= 100)
{
shiftUp();
generateLine();
pcnt = 0;
}
drawFrame(pcnt);
pcnt += 30;
}
// Randomly generate the next line (matrix row)
void generateLine()
{
for (uint8_t x = 0; x < WIDTH; x++)
{
line[x] = random(64, 255);
}
}
void shiftUp()
{
for (uint8_t y = HEIGHT - 1; y > 0; y--)
{
for (uint8_t x = 0; x < WIDTH; x++)
{
uint8_t newX = x;
if (x > 15) newX = x - 15;
if (y > 7) continue;
matrixValue[y][newX] = matrixValue[y - 1][newX];
}
}
for (uint8_t x = 0; x < WIDTH; x++)
{
uint8_t newX = x;
if (x > 15) newX = x - 15;
matrixValue[0][newX] = line[newX];
}
}
// draw a frame, interpolating between 2 "key frames"
// @param pcnt percentage of interpolation
void drawFrame(int32_t pcnt)
{
int32_t nextv;
//each row interpolates with the one before it
for (unsigned char y = HEIGHT - 1; y > 0; y--)
{
for (unsigned char x = 0; x < WIDTH; x++)
{
uint8_t newX = x;
if (x > 15) newX = x - 15;
if (y < 8)
{
nextv =
(((100.0 - pcnt) * matrixValue[y][newX]
+ pcnt * matrixValue[y - 1][newX]) / 100.0)
- pgm_read_byte(&(valueMask[y][newX]));
CRGB color = CHSV(
modes[1].scale * 2.5 + pgm_read_byte(&(hueMask[y][newX])), // H
255, // S
(uint8_t)max(0, nextv) // V
);
leds[getPixelNumber(x, y)] = color;
}
else if (y == 8 && SPARKLES)
{
if (random(0, 20) == 0 && getPixColorXY(x, y - 1) != 0) drawPixelXY(x, y, getPixColorXY(x, y - 1));
else drawPixelXY(x, y, 0);
}
else if (SPARKLES)
{
// старая версия для яркости
if (getPixColorXY(x, y - 1) > 0)
drawPixelXY(x, y, getPixColorXY(x, y - 1));
else drawPixelXY(x, y, 0);
}
}
}
//first row interpolates with the "next" line
for (unsigned char x = 0; x < WIDTH; x++)
{
uint8_t newX = x;
if (x > 15) newX = x - 15;
CRGB color = CHSV(
modes[1].scale * 2.5 + pgm_read_byte(&(hueMask[0][newX])), // H
255, // S
(uint8_t)(((100.0 - pcnt) * matrixValue[0][newX] + pcnt * line[newX]) / 100.0) // V
);
leds[getPixelNumber(newX, 0)] = color;
}
}
uint8_t hue;
// ------------- радуга ----------------
void rainbowVertical()
{
hue += 2;
for (uint8_t j = 0; j < HEIGHT; j++)
{
CHSV thisColor = CHSV((uint8_t)(hue + j * modes[2].scale), 255, 255);
for (uint8_t i = 0; i < WIDTH; i++)
drawPixelXY(i, j, thisColor);
}
}
void rainbowHorizontal()
{
hue += 2;
for (uint8_t i = 0; i < WIDTH; i++)
{
CHSV thisColor = CHSV((uint8_t)(hue + i * modes[3].scale), 255, 255);
for (uint8_t j = 0; j < HEIGHT; j++)
drawPixelXY(i, j, thisColor); //leds[getPixelNumber(i, j)] = thisColor;
}
}
// ------------- цвета -----------------
void colorsRoutine()
{
hue += modes[4].scale;
for (int32_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = CHSV(hue, 255, 255);
}
}
// ------------- цвет ------------------
void colorRoutine()
{
for (int32_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = CHSV(modes[14].scale * 2.5, 255, 255);
}
}
// ------------- снегопад 2.0 ----------
void snowRoutine()
{
// сдвигаем всё вниз
for (uint8_t x = 0; x < WIDTH; x++)
{
for (uint8_t y = 0; y < HEIGHT - 1; y++)
{
drawPixelXY(x, y, getPixColorXY(x, y + 1));
}
}
for (uint8_t x = 0; x < WIDTH; x++)
{
// заполняем случайно верхнюю строку
// а также не даём двум блокам по вертикали вместе быть
if (getPixColorXY(x, HEIGHT - 2) == 0 && (random(0, 100 - modes[15].scale) == 0))
drawPixelXY(x, HEIGHT - 1, 0xE0FFFF - 0x101010 * random(0, 4));
else
drawPixelXY(x, HEIGHT - 1, 0x000000);
}
}
// ------------- матрица ---------------
void matrixRoutine()
{
for (uint8_t x = 0; x < WIDTH; x++)
{
// заполняем случайно верхнюю строку
uint32_t thisColor = getPixColorXY(x, HEIGHT - 1);
if (thisColor == 0)
drawPixelXY(x, HEIGHT - 1, 0x00FF00 * (random(0, 100 - modes[16].scale) == 0));
else if (thisColor < 0x002000)
drawPixelXY(x, HEIGHT - 1, 0);
else
drawPixelXY(x, HEIGHT - 1, thisColor - 0x002000);
}
// сдвигаем всё вниз
for (uint8_t x = 0; x < WIDTH; x++)
{
for (uint8_t y = 0; y < HEIGHT - 1; y++)
{
drawPixelXY(x, y, getPixColorXY(x, y + 1));
}
}
}
// ------------- светляки --------------
#define LIGHTERS_AM 100
int32_t lightersPos[2][LIGHTERS_AM];
int8_t lightersSpeed[2][LIGHTERS_AM];
CHSV lightersColor[LIGHTERS_AM];
uint8_t loopCounter;
int32_t angle[LIGHTERS_AM];
int32_t speedV[LIGHTERS_AM];
int8_t angleSpeed[LIGHTERS_AM];
void lightersRoutine()
{
if (loadingFlag)
{
loadingFlag = false;
randomSeed(millis());
for (uint8_t i = 0; i < LIGHTERS_AM; i++)
{
lightersPos[0][i] = random(0, WIDTH * 10);
lightersPos[1][i] = random(0, HEIGHT * 10);
lightersSpeed[0][i] = random(-10, 10);
lightersSpeed[1][i] = random(-10, 10);
lightersColor[i] = CHSV(random(0, 255), 255, 255);
}
}
FastLED.clear();
if (++loopCounter > 20) loopCounter = 0;
for (uint8_t i = 0; i < modes[17].scale; i++)
{
if (loopCounter == 0) // меняем скорость каждые 255 отрисовок
{
lightersSpeed[0][i] += random(-3, 4);
lightersSpeed[1][i] += random(-3, 4);
lightersSpeed[0][i] = constrain(lightersSpeed[0][i], -20, 20);
lightersSpeed[1][i] = constrain(lightersSpeed[1][i], -20, 20);
}
lightersPos[0][i] += lightersSpeed[0][i];
lightersPos[1][i] += lightersSpeed[1][i];
if (lightersPos[0][i] < 0) lightersPos[0][i] = (WIDTH - 1) * 10;
if (lightersPos[0][i] >= WIDTH * 10) lightersPos[0][i] = 0;
if (lightersPos[1][i] < 0)
{
lightersPos[1][i] = 0;
lightersSpeed[1][i] = -lightersSpeed[1][i];
}
if (lightersPos[1][i] >= (HEIGHT - 1) * 10)
{
lightersPos[1][i] = (HEIGHT - 1) * 10;
lightersSpeed[1][i] = -lightersSpeed[1][i];
}
drawPixelXY(lightersPos[0][i] / 10, lightersPos[1][i] / 10, lightersColor[i]);
}
}
/*
void lightersRoutine()
{
if (loadingFlag)
{
loadingFlag = false;
randomSeed(millis());
for (uint8_t i = 0; i < LIGHTERS_AM; i++)
{
lightersPos[0][i] = random(0, WIDTH * 10);
lightersPos[1][i] = random(0, HEIGHT * 10);
lightersColor[i] = CHSV(random(0, 255), 255, 255);
speedV[i] = random(5, 10);
angle[i] = random(0, 360);
angleSpeed[i] = random(-10, 10);
}
}
FastLED.clear();
if (++loopCounter > 20) loopCounter = 0;
for (uint8_t i = 0; i < modes[17].scale; i++)
{
if (loopCounter == 0) // меняем скорость каждые 255 отрисовок
{
angleSpeed[i] += random(-3, 4);
angleSpeed[i] = constrain(angleSpeed[i], -15, 15);
}
lightersPos[0][i] += speedV[i] * cos(radians(angle[i]));
lightersPos[1][i] += speedV[i] * sin(radians(angle[i]));
if (lightersPos[0][i] < 0) lightersPos[0][i] = (WIDTH - 1) * 10;
if (lightersPos[0][i] >= WIDTH * 10) lightersPos[0][i] = 0;
if (lightersPos[1][i] < 0)
{
lightersPos[1][i] = 0;
angle[i] = 360 - angle[i];
}
else
{
angle[i] += angleSpeed[i];
}
if (lightersPos[1][i] >= (HEIGHT - 1) * 10)
{
lightersPos[1][i] = (HEIGHT - 1) * 10;
angle[i] = 360 - angle[i];
}
else
{
angle[i] += angleSpeed[i];
}
if (angle[i] > 360) angle[i] = 360 - angle[i];
if (angle[i] < 0) angle[i] = 360 + angle[i];
drawPixelXY(lightersPos[0][i] / 10, lightersPos[1][i] / 10, lightersColor[i]);
}
}
*/