/*
A set of animations for my Celtic Trinity symbol
Future expantion may include push button control
for brightness and animation choice
*/
#include <FastLED.h>
#define VOLTS 5 // MAX 5v power
#define PWR_LIMIT 1000 // 1Amp limit
#define LED_PIN 7 // data pin
#define NUM_LEDS 129 // total number of pixels
#define BRIGHTNESS 255 // brightness of display
#define FRAMES_PER_SECOND 100
#define INTERVAL 75
#define NUM_COLORS 3
#define COLOR_INTERVAL 1000
// define variables for timing
//unsigned long previousTime = 0;
//unsigned long currentTime = 0;
unsigned long lastColorChange = 0;
// define variable for storing current index of the symbols
int colorIndex = 0;
// define variable for storing current state of test function
int state = 0;
CRGB leds [NUM_LEDS]; // initialize all pixels
// pixel order of main and ring sections including gaps
int symbol []= {0,1,2,3,111,112,4,5,6,7,8,9,10,11,12,113,114,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,115,116,28,29,30,31,
32,33,34,35,36,117,118,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,119,120,52,53,54,55,56,57,58,59,60,121,122,61,62,
63,64,65,66,67,68,69,70,71};
int symbol1[]= {0,1,2,3,111,112,4,5,6,7,8,9,10,11,12,113,114,13,14,15,
16,17,18,19,20,21,22,23};
int symbol2[]= {24,25,26,27,115,116,28,29,30,31,32,33,34,35,36,117,118,
37,38,39,40,41,42,43,44,45,46,47};
int symbol3[]= {48,49,50,51,119,120,52,53,54,55,56,57,58,59,60,121,122,61,62,
63,64,65,66,67,68,69,70,71};
int ring []= {72,73,74,75,76,77,78,79,80,81,82,83,84,123,124,85,86,87,88,
89,90,91,92,93,94,95,96,97,125,126,98,99,100,101,102,103,
104,105,106,107,108,109,110,127,128};
int ring1[]= {72,73,74,75,76,77,78,79,80,81,82,83,84};
int ring2[]= {85,86,87,88,89,90,91,92,93,94,95,96,97};
int ring3[]= {98,99,100,101,102,103,104,105,106,107,108,109,110};
void setup() {
/*********************************************************************************
******************************* only runs once at start **************************
*********************************************************************************/
FastLED.setMaxPowerInVoltsAndMilliamps( VOLTS, PWR_LIMIT);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS); // type, data pin, clolour..
// ..order, num of pixels
FastLED.setBrightness(BRIGHTNESS); // set brightness level
FastLED.clear();
Serial.begin(115200);
}
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = {xant247,test2,rainbow,rainbowTwinkle,confetti,sinelon};
int secondsPerPattern[] = {10, 9, 15, 10, 15, 15};
char * names[] = {"xant","test2","rainbow","rainbowTwinkle","confetti","sinelon"};
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color"
void loop() {
/*********************************************************************************
******************************* main code runs repeatedly ************************
*********************************************************************************/
gPatterns[gCurrentPatternNumber]();
FastLED.show();
// FastLED.delay(1000/FRAMES_PER_SECOND);
EVERY_N_MILLISECONDS( 20 ) {
gHue++; // slowly cycle base color through rainbow
}
//EVERY_N_SECONDS(secondsPerPattern[gCurrentPatternNumber]) {
static long lastChangeMs = 0;
if(millis() - lastChangeMs >= secondsPerPattern[gCurrentPatternNumber]*1000L){
lastChangeMs = millis();
nextPattern(); // change patterns periodically
Serial.print(gCurrentPatternNumber);
Serial.print("#, ");
Serial.print(names[gCurrentPatternNumber]);
Serial.print(" for ");
Serial.print(secondsPerPattern[gCurrentPatternNumber]);
Serial.println("s");
}
}
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
void nextPattern()
{
// add one to the current pattern number, and wrap around at the end
gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}
void xant247(void) {
int symbolStart = 0;
int symbolLength = (NUM_LEDS - 57);
int ringStart = symbolStart + symbolLength;
int ringLength = NUM_LEDS - symbolLength - 18;
EVERY_N_MILLISECONDS( 1000 / FRAMES_PER_SECOND ) {
drawSinelon(symbolStart, symbolLength);
drawWhiteCycle( ringStart, ringLength);
// Now, here's where we call FastLED.show()
// send the 'leds' array out to the actual LED strip
FastLED.show();
}
EVERY_N_MILLISECONDS( 10 ) {
gHue--; // slowly cycle the "base color" through the rainbow
}
}
void rainbowTwinkle(void) {
int symbolStart = 0;
int symbolLength = (NUM_LEDS - 57);
int ringStart = symbolStart + symbolLength;
int ringLength = NUM_LEDS - symbolLength - 18;
EVERY_N_MILLISECONDS( 1000 / FRAMES_PER_SECOND ) {
drawRainbow(symbolStart, symbolLength);
drawTwinkles( ringStart, ringLength);
// Now, here's where we call FastLED.show()
// send the 'leds' array out to the actual LED strip
FastLED.show();
}
EVERY_N_MILLISECONDS( 10 ) {
gHue--; // slowly cycle the "base color" through the rainbow
}
}
void drawWhiteCycle(int startpixel, int pixelcount) {
fadeToBlackBy( leds + startpixel, pixelcount, 2);
int pos = beat8(13, 0) * (pixelcount - 1) / 255;
pos = pixelcount - 1 - pos; // to reverse direction;
leds[pos + startpixel] = CRGB::White;
}
void drawSinelon(int startpixel, int pixelcount) {
// colour changing dot sweeping back and forth around the arcs, with fading tail
fadeToBlackBy( leds + startpixel, pixelcount, 30);
int pos = beatsin16( 13, 0, pixelcount - 1 );
leds[pos + startpixel] += CHSV( gHue, 255, 192);
}
void drawTwinkles(int startpixel, int pixelcount) {
// random colored speckles that blink in and fade smoothly
fadeToBlackBy( leds + startpixel, pixelcount, 30);
int pos = random16( pixelcount);
leds[pos + startpixel] += CHSV( gHue -32 + random8(64), 200, 255);
}
void drawRainbow(int startpixel, int pixelcount) {
// FastLED's built-in rainbow generator
fill_rainbow_circular( leds + startpixel, pixelcount, gHue, 60);
}
void confetti() {
fadeToBlackBy( leds, NUM_LEDS, 20);
int pos = random16(NUM_LEDS);
leds[pos] += CHSV( gHue + random8(80), 200, 255);
FastLED.show();
}
void rainbow() {
fill_rainbow( leds, NUM_LEDS, gHue++, 10);
}
void sinelon() {
fadeToBlackBy( leds, NUM_LEDS, 10);
int pos = beatsin16( 13, 0, NUM_LEDS - 58 );
leds[pos] += CHSV( gHue, 255, 192);
}
void test2() {
// Clear the LED strip
FastLED.clear();
// Get the current time in milliseconds
unsigned long currentTime = millis();
// Check if the interval has passed since the last color change
if (currentTime - lastColorChange >= COLOR_INTERVAL) {
// Update the last color change time
lastColorChange = currentTime;
// Increment the color index
colorIndex = (colorIndex + 1) % NUM_COLORS;
}
// Use a switch-case statement to assign the appropriate color to each segment
switch (colorIndex) {
case 0: // Red, yellow, blue
fill_solid(&leds[72], 13, CRGB::Red);
fill_solid(&leds[85], 13, CRGB::Yellow);
fill_solid(&leds[98], 13, CRGB::Blue);
break;
case 1: // Blue, red, yellow
fill_solid(&leds[72], 13, CRGB::Blue);
fill_solid(&leds[85], 13, CRGB::Red);
fill_solid(&leds[98], 13, CRGB::Yellow);
break;
case 2: // Yellow, blue, red
fill_solid(&leds[72], 13, CRGB::Yellow);
fill_solid(&leds[85], 13, CRGB::Blue);
fill_solid(&leds[98], 13, CRGB::Red);
break;
}
// Show the LED strip
FastLED.show();
}