307 lines
8.1 KiB
C
307 lines
8.1 KiB
C
// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Selection of effects from the FastLED library & Macetech RGB Shades
|
|
|
|
// Triple Sine Waves
|
|
void threeSine() {
|
|
|
|
static byte sineOffset = 0; // counter for current position of sine waves
|
|
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 20;
|
|
}
|
|
|
|
// Draw one frame of the animation into the LED array
|
|
for (byte x = 0; x < kMatrixWidth; x++) {
|
|
for (int y = 0; y < kMatrixHeight; y++) {
|
|
|
|
// Calculate "sine" waves with varying periods
|
|
// sin8 is used for speed; cos8, quadwave8, or triwave8 would also work here
|
|
byte sinDistanceR = qmul8(abs(y * (255 / kMatrixHeight) - sin8(sineOffset * 9 + x * 16)), 2);
|
|
byte sinDistanceG = qmul8(abs(y * (255 / kMatrixHeight) - sin8(sineOffset * 10 + x * 16)), 2);
|
|
byte sinDistanceB = qmul8(abs(y * (255 / kMatrixHeight) - sin8(sineOffset * 11 + x * 16)), 2);
|
|
|
|
leds[XY(x, y, 0, 0)] = CRGB(255 - sinDistanceR, 255 - sinDistanceG, 255 - sinDistanceB);
|
|
}
|
|
}
|
|
|
|
sineOffset++; // byte will wrap from 255 to 0, matching sin8 0-255 cycle
|
|
|
|
}
|
|
|
|
|
|
|
|
// Solid Colors
|
|
// Create your own!
|
|
void SolidWhite() //for the porto-potty
|
|
{
|
|
fill_solid( leds, NUM_LEDS, CRGB::White);
|
|
}
|
|
|
|
void SolidRed() //for startup, good for saving battery
|
|
{
|
|
fill_solid( leds, NUM_LEDS, CRGB::Red);
|
|
}
|
|
|
|
|
|
|
|
// RGB Plasma
|
|
void plasma() {
|
|
|
|
static byte offset = 0; // counter for radial color wave motion
|
|
static int plasVector = 0; // counter for orbiting plasma center
|
|
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 10;
|
|
}
|
|
|
|
// Calculate current center of plasma pattern (can be offscreen)
|
|
int xOffset = cos8(plasVector / 256);
|
|
int yOffset = sin8(plasVector / 256);
|
|
|
|
// Draw one frame of the animation into the LED array
|
|
for (int x = 0; x < kMatrixWidth; x++) {
|
|
for (int y = 0; y < kMatrixHeight; y++) {
|
|
byte color = sin8(sqrt(sq(((float)x - 7.5) * 10 + xOffset - 127) + sq(((float)y - 2) * 10 + yOffset - 127)) + offset);
|
|
leds[XY(x, y, 0, 0)] = CHSV(color, 255, 255);
|
|
}
|
|
}
|
|
|
|
offset++; // wraps at 255 for sin8
|
|
plasVector += 16; // using an int for slower orbit (wraps at 65536)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scanning pattern left/right, using global hue cycle
|
|
void rider() {
|
|
|
|
static byte riderPos = 0;
|
|
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 5;
|
|
riderPos = 0;
|
|
}
|
|
|
|
// Draw one frame of the animation into the LED array
|
|
for (byte x = 0; x < kMatrixWidth; x++) {
|
|
int brightness = abs(x * (256 / kMatrixWidth) - triwave8(riderPos) * 2 + 127) * 3;
|
|
if (brightness > 255) brightness = 255;
|
|
brightness = 255 - brightness;
|
|
CRGB riderColor = CHSV(cycleHue, 255, brightness);
|
|
for (byte y = 0; y < kMatrixHeight; y++) {
|
|
leds[XY(x, y, 0, 0)] = riderColor;
|
|
}
|
|
}
|
|
|
|
riderPos++; // byte wraps to 0 at 255, triwave8 is also 0-255 periodic
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fills saturated colors into the array from alternating directions
|
|
void colorFill() {
|
|
|
|
static byte currentColor = 0;
|
|
static byte currentRow = 0;
|
|
static byte currentDirection = 0;
|
|
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 45;
|
|
currentColor = 0;
|
|
currentRow = 0;
|
|
currentDirection = 0;
|
|
currentPalette = RainbowColors_p;
|
|
}
|
|
|
|
// test a bitmask to fill up or down when currentDirection is 0 or 2 (0b00 or 0b10)
|
|
if (!(currentDirection & 1)) {
|
|
effectDelay = 45; // slower since vertical has fewer pixels
|
|
for (byte x = 0; x < kMatrixWidth; x++) {
|
|
byte y = currentRow;
|
|
if (currentDirection == 2) y = kMatrixHeight - 1 - currentRow;
|
|
leds[XY(x, y, 0, 0)] = currentPalette[currentColor];
|
|
}
|
|
}
|
|
|
|
// test a bitmask to fill left or right when currentDirection is 1 or 3 (0b01 or 0b11)
|
|
if (currentDirection & 1) {
|
|
effectDelay = 20; // faster since horizontal has more pixels
|
|
for (byte y = 0; y < kMatrixHeight; y++) {
|
|
byte x = currentRow;
|
|
if (currentDirection == 3) x = kMatrixWidth - 1 - currentRow;
|
|
leds[XY(x, y, 0, 0)] = currentPalette[currentColor];
|
|
}
|
|
}
|
|
|
|
currentRow++;
|
|
|
|
// detect when a fill is complete, change color and direction
|
|
if ((!(currentDirection & 1) && currentRow >= kMatrixHeight) || ((currentDirection & 1) && currentRow >= kMatrixWidth)) {
|
|
currentRow = 0;
|
|
currentColor += random8(3, 6);
|
|
if (currentColor > 15) currentColor -= 16;
|
|
currentDirection++;
|
|
if (currentDirection > 3) currentDirection = 0;
|
|
effectDelay = 300; // wait a little bit longer after completing a fill
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Random pixels scroll sideways, using current hue
|
|
#define rainDir 0
|
|
void sideRain() {
|
|
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 30;
|
|
}
|
|
|
|
scrollArray(rainDir);
|
|
byte randPixel = random8(kMatrixHeight);
|
|
for (byte y = 0; y < kMatrixHeight; y++) leds[XY((kMatrixWidth - 1) * rainDir, y, 0, 0)] = CRGB::Black;
|
|
leds[XY((kMatrixWidth - 1)*rainDir, randPixel, 0, 0)] = CHSV(cycleHue, 255, 255);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CONFETTI: pixels with random locations and random colors selected from a palette
|
|
// Create your own confetti modes using the built in Palettes (see utils.h) or create your own
|
|
// Use with the fadeAll function (see .ino) to allow old pixels to decay
|
|
void confetti() {
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 10;
|
|
selectRandomPalette();
|
|
}
|
|
|
|
// scatter random colored pixels at several random coordinates
|
|
for (byte i = 0; i < 4; i++) {
|
|
leds[XY(random16(kMatrixWidth), random16(kMatrixHeight), 0, 0)] = ColorFromPalette(currentPalette, random16(255), 255); //CHSV(random16(255), 255, 255);
|
|
random16_add_entropy(1);
|
|
}
|
|
}
|
|
|
|
//Palette for myConfetti
|
|
const TProgmemPalette16 MyColors_p PROGMEM =
|
|
{
|
|
CRGB:: Crimson,
|
|
CRGB:: Maroon,
|
|
CRGB:: Red,
|
|
CRGB:: OrangeRed,
|
|
|
|
CRGB:: Crimson,
|
|
CRGB:: Maroon,
|
|
CRGB:: Red,
|
|
CRGB:: OrangeRed,
|
|
|
|
CRGB:: Crimson,
|
|
CRGB:: Maroon,
|
|
CRGB:: Red,
|
|
CRGB:: OrangeRed,
|
|
|
|
CRGB:: Crimson,
|
|
CRGB:: Maroon,
|
|
CRGB:: Red,
|
|
CRGB:: OrangeRed,
|
|
};
|
|
|
|
void myConfetti() {
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 15;
|
|
}
|
|
|
|
|
|
// scatter random colored pixels at several random coordinates
|
|
for (byte i = 0; i < 4; i++) {
|
|
leds[XY(random16(kMatrixWidth), random16(kMatrixHeight), 0, 0)] = ColorFromPalette(MyColors_p, random16(255), 255); //CHSV(random16(255), 255, 255);
|
|
random16_add_entropy(1);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Example from the NoisePlusPalette FastLED example sketch. See utils.h
|
|
void NoisePlusPalette() {
|
|
|
|
fillnoise8();
|
|
|
|
mapNoiseToLEDsUsingPalette();
|
|
|
|
}
|
|
|
|
|
|
// Draw slanting bars scrolling across the array, using current hue
|
|
void slantBars() {
|
|
|
|
static byte slantPos = 0;
|
|
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 5;
|
|
}
|
|
|
|
for (byte x = 0; x < kMatrixWidth; x++) {
|
|
for (byte y = 0; y < kMatrixHeight; y++) {
|
|
leds[XY(x, y, 0, 0)] = CHSV(cycleHue, 255, quadwave8(x * 32 + y * 32 + slantPos));
|
|
}
|
|
}
|
|
|
|
slantPos -= 4;
|
|
|
|
}
|
|
|
|
|
|
//from Mark Kriegsman
|
|
void swirly()
|
|
{
|
|
// startup tasks
|
|
if (effectInit == false) {
|
|
effectInit = true;
|
|
effectDelay = 15;
|
|
}
|
|
|
|
// 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 = beatsin8(2,10,255);
|
|
blur2d(leds, kMatrixWidth, kMatrixHeight, blurAmount, myXYMap);
|
|
|
|
// 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, 0, 0)] += CHSV( ms / 11, 200, 255);
|
|
leds[XY(j, i, 0, 0)] += CHSV( ms / 13, 200, 255);
|
|
leds[XY(ni,nj, 0, 0)] += CHSV( ms / 17, 200, 255);
|
|
leds[XY(nj,ni, 0, 0)] += CHSV( ms / 29, 200, 255);
|
|
leds[XY(i,nj, 0, 0)] += CHSV( ms / 37, 200, 255);
|
|
leds[XY(ni, j, 0, 0)] += CHSV( ms / 41, 200, 255);
|
|
|
|
FastLED.show();
|
|
}
|