From 8541ce1840c0db74ff8b7c2f1dc803b61e4cda5a Mon Sep 17 00:00:00 2001 From: Mel <146559663+mel-interactive@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:41:25 +0100 Subject: [PATCH 1/4] attempt to merge all the animations into one file --- finalanimation.ino | 316 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 finalanimation.ino diff --git a/finalanimation.ino b/finalanimation.ino new file mode 100644 index 0000000..dd67ede --- /dev/null +++ b/finalanimation.ino @@ -0,0 +1,316 @@ +#include + +#define NUM_LEDS 480 +#define LED_PIN 6 +#define BRIGHTNESS 190 +#define LED_STRIP WS2812B +#define SECTIONS_COUNT 4 +#define LEDS_PER_SECTION 60 +#define FRAME_TIME 33 // ~30fps +#define RING_COUNT 3 // Number of rings +#define RING_DELAY 500 // Delay before starting next ring (milliseconds) +#define repeatCounter 3 + + + +CRGB leds[NUM_LEDS]; +CRGB originalColors[NUM_LEDS]; + +// Colors defined with #define to save memory +#define YELLOW CRGB(255, 163, 3) +#define BLUE CRGB(0, 0, 255) +#define PINK CRGB(250, 5, 148) +#define PURPLE CRGB(255, 0, 255) +#define LILAC CRGB(221,117,244) + +int amountOfSections = 4; +int currentSensorCount = 0; +int previousSensorCount = 0; + +unsigned long lightTimer = millis(); +unsigned long startTime = millis(); +bool idleComplete = false; +bool isActivating = false; + +// Section structure and definitions +struct Section { + uint8_t start; + uint8_t end; +}; + +const Section sections[SECTIONS_COUNT] = { + { 0, 120 }, + { 121, 240 }, + { 241, 360 }, + { 361, 480 } +}; + +// Timing variables +unsigned long lastFrameTime = 0; +unsigned long lastCyanPixelTime = 0; + +//HELPER FUNCTION FOR TRANSITIONS +void fadeToColor(CRGB endColor, uint8_t steps, uint8_t delayMs) { + for (uint8_t fadeValue = 0; fadeValue <= steps; fadeValue++) { + float progress = fadeValue / (float)steps; + for (int i = 0; i < NUM_LEDS; i++) { + leds[i] = blend(originalColors[i], endColor, progress * 255); + } + FastLED.show(); + delay(delayMs); + } +} + + +void IdleAnimation() { + if ((millis() - lightTimer) > 33) { + static byte fade = 0; + static byte up = 1; + + fade += (up ? 5 : -5); + + if (fade >= 255 || fade <= 0) { + up = (up == 1) ? 0 : 1; + } + fill_solid(leds, NUM_LEDS, CRGB(fade, fade, 255)); + FastLED.show(); + lightTimer = millis(); + } +} + + +void FirstStage() { + if ((millis() - lightTimer) > 33) { + int maxStep = (sections[0].end - sections[0].start) / 2; + + // Yellow filling inward + for (int step = maxStep; step >= 0; step--) { + for (int s = 0; s < 4; s++) { + leds[sections[s].start + step] = YELLOW; + leds[sections[s].end - step] = YELLOW; + } + delay(20); + FastLED.show(); + } + + // Yellow moving outward + for (int step = 0; step <= maxStep; step++) { + for (int s = 0; s < 4; s++) { + leds[sections[s].start + step] = YELLOW; + leds[sections[s].end - step] = YELLOW; + } + delay(20); + FastLED.show(); + } + + // Brightness pulsing effect - repeat 3 times + for (int repeat = 0; repeat < repeatCounter; repeat++) { + { + // Dim from full brightness to 0 + for (int pulse = 190; pulse >= 100; pulse -= 15) { + FastLED.setBrightness(pulse); + FastLED.show(); + delay(30); + } + // Brighten from 0 back to full brightness + for (int pulse = 100; pulse <= 190; pulse += 15) { + FastLED.setBrightness(pulse); + FastLED.show(); + delay(30); + } + } + // Fade to lilac, then blue + fadeToColor(LILAC, 150,20); + fadeToColor(BLUE, 150,100); + + + lightTimer = millis(); + } +} + +void SecondStage() { + unsigned long currentTime = millis(); + if (currentTime - lastFrameTime >= FRAME_TIME) { + lastFrameTime = currentTime; + + fillInward(PINK, 20); + fillOutward(PINK, 20); + spreadFromMiddle(YELLOW, 20); + delay(20); + + saveCurrentColors(); + multipleRingAnimation(80); + + if (currentTime - lastCyanPixelTime >= 500) { + fadeToColor(BLUE, 150, 20); + lastCyanPixelTime = currentTime; + } + } +} + +//SECOND STAGE HELPER FUNCTIONS +void fillInward(CRGB color, uint8_t delayMs) { + for (int step = LEDS_PER_SECTION / 2; step >= 0; step--) { + for (uint8_t s = 0; s < SECTIONS_COUNT; s++) { + leds[sections[s].start + step] = color; + leds[sections[s].end - step] = color; + } + FastLED.show(); + delay(delayMs); + } +} + +void fillOutward(CRGB color, uint8_t delayMs) { + for (int step = 0; step <= LEDS_PER_SECTION / 2; step++) { + for (uint8_t s = 0; s < SECTIONS_COUNT; s++) { + leds[sections[s].start + step] = color; + leds[sections[s].end - step] = color; + } + FastLED.show(); + delay(delayMs); + } +} + +void spreadFromMiddle(CRGB color, uint8_t delayMs) { + for (int step = 0; step <= LEDS_PER_SECTION / 2; step++) { + for (uint8_t s = 0; s < SECTIONS_COUNT; s++) { + int sectionMiddle = sections[s].start + (LEDS_PER_SECTION / 2); + if ((sectionMiddle + step) <= sections[s].end) + leds[sectionMiddle + step] = color; + if ((sectionMiddle - step) >= sections[s].start) + leds[sectionMiddle - step] = color; + } + FastLED.show(); + delay(delayMs); + } +} + +void saveCurrentColors() { + memcpy(originalColors, leds, sizeof(originalColors)); +} + +void multipleRingAnimation(uint8_t delayMs) { + uint8_t ringPositions[RING_COUNT] = {0}; + bool ringActive[RING_COUNT] = {true, false, false}; + uint8_t completedRings = 0; // Counter for completed rings + + unsigned long ringStartTime = millis(); // Start time for the ring delay + + while (true) { + bool activeRings = false; + unsigned long currentTime = millis(); + + for (int ring = 0; ring < RING_COUNT; ring++) { + if (ringActive[ring]) { + activeRings = true; + uint8_t currentPosition = ringPositions[ring]; + + for (int section = 0; section < SECTIONS_COUNT; section++) { + uint8_t sectionStart = sections[section].start; + uint8_t clearPos = (currentPosition - 1) % LEDS_PER_SECTION; + + // Clear the previous position + for (int offset = -2; offset <= 2; offset++) { // Wider clear area + int clearPixel = (clearPos + offset + LEDS_PER_SECTION) % LEDS_PER_SECTION; + leds[sectionStart + clearPixel] = originalColors[sectionStart + clearPixel]; + } + + // Set new 5-pixel-wide position + int ringPixel = (currentPosition % LEDS_PER_SECTION); + for (int offset = -2; offset <= 2; offset++) { // Thicker ring + int newPixel = (ringPixel + offset + LEDS_PER_SECTION) % LEDS_PER_SECTION; + leds[sectionStart + newPixel] = PURPLE; + } + } + + ringPositions[ring]++; + if (ringPositions[ring] >= LEDS_PER_SECTION) { + ringActive[ring] = false; // Ring is completed + completedRings++; // Increment completed rings counter + } + } else if (ring > 0 && (currentTime - ringStartTime >= ring * RING_DELAY)) { + ringActive[ring] = true; // Activate the next ring after the delay + } + } + + // Exit the loop if all rings have been completed + if (completedRings >= RING_COUNT) break; + + FastLED.show(); + delay(delayMs); + } + + // Restore original colors at the end + memcpy(leds, originalColors, sizeof(originalColors)); // Use originalColors size for clarity + FastLED.show(); +} + + +void ThirdStage(int previousCount) { + if ((millis() - lightTimer) > 33) { + static int shift = 0; + static unsigned long lastUpdate = 0; + CRGB colors[3] = { CRGB(0, 255, 255), CRGB(252, 3, 94), CRGB(255, 163, 3) }; + + for (int s = 0; s < amountOfSections; s++) { + int sectionLength = sections[s].end - sections[s].start + 1; + + for (int pos = sectionLength - 1; pos >= 0; pos--) { + int ledIndex = sections[s].end - pos; + + int gradientPos = map((pos + shift) % sectionLength, 0, sectionLength - 1, 0, 255); + + CRGB color; + if (gradientPos < 128) { + color = blend(colors[0], colors[1], gradientPos * 2); + } else { + color = blend(colors[1], colors[2], (gradientPos - 128) * 2); + } + + if (currentSensorCount != previousCount) { + leds[ledIndex] = blend(leds[ledIndex], color, 45); + } else { + leds[ledIndex] = color; + } + } + } + FastLED.show(); + shift = (shift + 2) % sections[0].end; + lightTimer = millis(); + } +} + +void ActivateResponse() { + // Prevent re-entry if already animating + if (isActivating) { + return; + } + + isActivating = true; // Set the flag to true indicating is running + + // Original brightness + uint8_t originalBrightness = BRIGHTNESS; + // New brightness + uint8_t targetBrightness = min(originalBrightness + 30, 255); // Increase by 30, but cap at 255 + + // Set brightness to the target + FastLED.setBrightness(targetBrightness); + FastLED.show(); + delay(50); // Briefly display the increased brightness + + // Gradually reduce brightness back to original + for (int i = 0; i <= 30; i++) { + // Calculate the current brightness based on the elapsed time + uint8_t currentBrightness = targetBrightness - (targetBrightness - originalBrightness) * i / 30; + FastLED.setBrightness(currentBrightness); + FastLED.show(); + delay(5); // Adjusted delay for smoother fading + } + + // Restore original brightness + FastLED.setBrightness(originalBrightness); + FastLED.show(); + + isActivating = false; // Reset the flag after animation completes +} + From b758fcf8fff8c28f902f342ff9390b6f74a34e8f Mon Sep 17 00:00:00 2001 From: Jip Voss <147500500+Splatking@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:07:38 +0100 Subject: [PATCH 2/4] Update finalanimation.ino Added Feedback in the top comment! --- finalanimation.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/finalanimation.ino b/finalanimation.ino index dd67ede..7a898e8 100644 --- a/finalanimation.ino +++ b/finalanimation.ino @@ -1,3 +1,5 @@ +//WATCH OUT WITH FOR LOOPS! TRY TO NOT USE THEM AT ALL!!! + #include #define NUM_LEDS 480 From 9d6720e8442cf22d86a01d93d32a9b44dd68b5ef Mon Sep 17 00:00:00 2001 From: yaskfuri Date: Mon, 4 Nov 2024 16:36:22 +0100 Subject: [PATCH 3/4] melissa's change --- .../finalanimation.ino | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) rename finalanimation.ino => finalanimation/finalanimation.ino (97%) diff --git a/finalanimation.ino b/finalanimation/finalanimation.ino similarity index 97% rename from finalanimation.ino rename to finalanimation/finalanimation.ino index 7a898e8..62a033b 100644 --- a/finalanimation.ino +++ b/finalanimation/finalanimation.ino @@ -12,6 +12,7 @@ #define RING_COUNT 3 // Number of rings #define RING_DELAY 500 // Delay before starting next ring (milliseconds) #define repeatCounter 3 +#define delayMs 20 @@ -41,10 +42,10 @@ struct Section { }; const Section sections[SECTIONS_COUNT] = { - { 0, 120 }, - { 121, 240 }, - { 241, 360 }, - { 361, 480 } + { 0, 115 }, + { 116, 230 }, + { 231, 345 }, + { 346, 460 } }; // Timing variables @@ -65,7 +66,7 @@ void fadeToColor(CRGB endColor, uint8_t steps, uint8_t delayMs) { void IdleAnimation() { - if ((millis() - lightTimer) > 33) { + if ((millis() - lightTimer) > FRAME_TIME) { static byte fade = 0; static byte up = 1; @@ -82,7 +83,7 @@ void IdleAnimation() { void FirstStage() { - if ((millis() - lightTimer) > 33) { + if ((millis() - lightTimer) > FRAME_TIME) { int maxStep = (sections[0].end - sections[0].start) / 2; // Yellow filling inward @@ -249,7 +250,7 @@ void multipleRingAnimation(uint8_t delayMs) { void ThirdStage(int previousCount) { - if ((millis() - lightTimer) > 33) { + if ((millis() - lightTimer) > FRAME_TIME) { static int shift = 0; static unsigned long lastUpdate = 0; CRGB colors[3] = { CRGB(0, 255, 255), CRGB(252, 3, 94), CRGB(255, 163, 3) }; From 07d820ed9933d96e11d56579c4d7e4d570ae90fe Mon Sep 17 00:00:00 2001 From: Mel <146559663+mel-interactive@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:05:36 +0100 Subject: [PATCH 4/4] refactored, tested, not optimized --- refactoredlightcode.ino | 312 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 refactoredlightcode.ino diff --git a/refactoredlightcode.ino b/refactoredlightcode.ino new file mode 100644 index 0000000..2c515da --- /dev/null +++ b/refactoredlightcode.ino @@ -0,0 +1,312 @@ +#include + +#define NUM_LEDS 460 +#define LED_PIN 5 +#define BRIGHTNESS 190 +#define LED_STRIP WS2812B +#define SECTIONS_COUNT 4 +#define LEDS_PER_SECTION 60 +#define FRAME_TIME 33 +#define RING_COUNT 3 +#define RING_DELAY 500 +#define REPEAT_COUNTER 3 +#define DELAY_MS 10 + +CRGB leds[NUM_LEDS]; + + +// Colors defined with #define to save memory +#define YELLOW CRGB(255, 163, 3) +#define BLUE CRGB(0, 0, 255) +#define PINK CRGB(250, 5, 148) +#define PURPLE CRGB(255, 0, 255) +#define LILAC CRGB(221, 117, 244) + +// Brightness and timer variables +unsigned long lightTimer = millis(); +unsigned long lastFrameTime = 0; +unsigned long lastCyanPixelTime = 0; +uint8_t baseBrightness = 120; +uint8_t brightnessRange = 80; +bool isActivating = false; + +// Section structure and definitions +struct Section { + uint8_t start; + uint8_t end; +}; + +const Section sections[SECTIONS_COUNT] = { + { 0, 115 }, + { 116, 230 }, + { 231, 345 }, + { 346, 459 } +}; + +int currentSensorCount = 0; +int previousSensorCount = 0; + +// Setup function +void setup() { + FastLED.addLeds(leds, NUM_LEDS); + FastLED.setBrightness(BRIGHTNESS); + Serial.begin(9600); +} + +void loop() { + SecondStage(); +} + +// Helper function: Set color to a specific LED range recursively +void setColorRecursive(CRGB color, uint8_t section, int step, bool inward) { + if ((inward && step < 0) || (!inward && step > LEDS_PER_SECTION / 2)) return; + + leds[sections[section].start + step] = color; + leds[sections[section].end - step] = color; + FastLED.show(); + delay(DELAY_MS); + + setColorRecursive(color, section, step + (inward ? -1 : 1), inward); +} + +// Idle mode function +void Idle() { + // Calculate brightness using a sine wave for smooth oscillation + uint8_t oscillation = sin8(millis() / 10); // Adjust speed as necessary + uint8_t currentBrightness = baseBrightness + map(oscillation, 0, 255, -brightnessRange, brightnessRange); + + // Set the brightness before filling the LEDs with color + FastLED.setBrightness(currentBrightness); + + // Fill the LEDs with blue color + fill_solid(leds, NUM_LEDS, BLUE); + + // Update the LEDs display every FRAME_TIME milliseconds + if (millis() - lightTimer > FRAME_TIME) { + FastLED.show(); + lightTimer = millis(); // Reset the timer for the next frame + } +} + + +// First stage animation +void FirstStage() { + if (millis() - lightTimer > FRAME_TIME) { + int maxStep = (sections[0].end - sections[0].start) / 2; + + // Process each section without using for loop + setColorRecursive(YELLOW, 0, maxStep, true); + setColorRecursive(YELLOW, 0, 0, false); + setColorRecursive(YELLOW, 1, maxStep, true); + setColorRecursive(YELLOW, 1, 0, false); + setColorRecursive(YELLOW, 2, maxStep, true); + setColorRecursive(YELLOW, 2, 0, false); + setColorRecursive(YELLOW, 3, maxStep, true); + setColorRecursive(YELLOW, 3, 0, false); + + pulseBrightness(REPEAT_COUNTER); + fadeToColor(BLUE, 150, 100); + lightTimer = millis(); + } +} + +// Recursive brightness pulsing effect +void pulseBrightness(int repeat) { + if (repeat <= 0) return; + adjustBrightness(190, 60, -15); + adjustBrightness(60, 190, 15); + pulseBrightness(repeat - 1); +} + +void adjustBrightness(int start, int end, int step) { + if ((step > 0 && start > end) || (step < 0 && start < end)) return; + + FastLED.setBrightness(start); + FastLED.show(); + delay(30); + + adjustBrightness(start + step, end, step); +} + +void fadeToColor(CRGB targetColor, int durationMs, int stepDelayMs) { + // Avoiding for loop + uint8_t brightness = 0; + while (brightness <= 190) { + fill_solid(leds, NUM_LEDS, targetColor); + FastLED.setBrightness(brightness); + FastLED.show(); + delay(stepDelayMs); + brightness += 5; + } +} + +void spreadFromMiddle(uint8_t section, CRGB color, uint8_t delayMs, int step = 0) { + int sectionMiddle = sections[section].start + (LEDS_PER_SECTION / 2); + if (step > LEDS_PER_SECTION / 2) return; + + if ((sectionMiddle + step) <= sections[section].end) + leds[sectionMiddle + step] = color; + if ((sectionMiddle - step) >= sections[section].start) + leds[sectionMiddle - step] = color; + + FastLED.show(); + delay(delayMs); + spreadFromMiddle(section, color, delayMs, step + 1); +} + + +void multipleRingAnimation(uint8_t delayMs, uint8_t ring = 0) { + if (ring >= RING_COUNT) return; + + static uint8_t ringPositions[RING_COUNT] = {0}; + static bool ringActive[RING_COUNT] = {true, false, false}; + static uint8_t completedRings = 0; + + unsigned long ringStartTime = millis(); + bool activeRings = false; + + if (ringActive[ring]) { + activeRings = true; + uint8_t currentPosition = ringPositions[ring]; + uint8_t sectionStart; + + // Process each section without using for loop + for (int section = 0; section < SECTIONS_COUNT; section++) { + sectionStart = sections[section].start; + uint8_t clearPos = (currentPosition - 1) % LEDS_PER_SECTION; + + // Clear previous positions directly from leds array + int clearPixel; + for (int offset = -2; offset <= 2; offset++) { + clearPixel = (clearPos + offset + LEDS_PER_SECTION) % LEDS_PER_SECTION; + leds[sectionStart + clearPixel] = CRGB::Black; // Clear to black or whatever default color + } + + // Set current ring pixel + int ringPixel = (currentPosition % LEDS_PER_SECTION); + for (int offset = -2; offset <= 2; offset++) { + int newPixel = (ringPixel + offset + LEDS_PER_SECTION) % LEDS_PER_SECTION; + leds[sectionStart + newPixel] = PURPLE; + } + } + + ringPositions[ring]++; + if (ringPositions[ring] >= LEDS_PER_SECTION) { + ringActive[ring] = false; + completedRings++; + } + } else if (ring > 0 && (millis() - ringStartTime >= ring * RING_DELAY)) { + ringActive[ring] = true; + } + + if (completedRings < RING_COUNT) { + FastLED.show(); + delay(delayMs); + multipleRingAnimation(delayMs, ring + 1); + } else { + // No need to restore original colors, just clear or set to default if needed + fill_solid(leds, NUM_LEDS, CRGB::Black); // or reset to a desired state + FastLED.show(); + } +} + +// Second stage animation +void SecondStage() { + unsigned long currentTime = millis(); + if (currentTime - lastFrameTime >= FRAME_TIME) { + lastFrameTime = currentTime; + + // Process each section without using for loop + setColorRecursive(PINK, 0, LEDS_PER_SECTION / 2, true); + setColorRecursive(PINK, 0, 0, false); + spreadFromMiddle(0, YELLOW, DELAY_MS); + + setColorRecursive(PINK, 1, LEDS_PER_SECTION / 2, true); + setColorRecursive(PINK, 1, 0, false); + spreadFromMiddle(1, YELLOW, DELAY_MS); + + setColorRecursive(PINK, 2, LEDS_PER_SECTION / 2, true); + setColorRecursive(PINK, 2, 0, false); + spreadFromMiddle(2, YELLOW, DELAY_MS); + + setColorRecursive(PINK, 3, LEDS_PER_SECTION / 2, true); + setColorRecursive(PINK, 3, 0, false); + spreadFromMiddle(3, YELLOW, DELAY_MS); + + // Directly call multipleRingAnimation without restoring original colors + multipleRingAnimation(DELAY_MS); + + // Implement color fade effect + if (currentTime - lastCyanPixelTime >= 500) { + fadeToColor(BLUE, 150, 20); + lastCyanPixelTime = currentTime; + } + } +} + + +void ThirdStage(int previousCount) { + if ((millis() - lightTimer) > FRAME_TIME) { + static int shift = 0; + CRGB colors[3] = { CRGB(0, 255, 255), CRGB(252, 3, 94), CRGB(255, 163, 3) }; + + // Process each section without using for loop + for (int s = 0; s < SECTIONS_COUNT; s++) { + int sectionLength = sections[s].end - sections[s].start + 1; + int pos = sectionLength - 1; + + while (pos >= 0) { + int ledIndex = sections[s].end - pos; + int gradientPos = map((pos + shift) % sectionLength, 0, sectionLength - 1, 0, 255); + + CRGB color; + if (gradientPos < 128) { + color = blend(colors[0], colors[1], gradientPos * 2); + } else { + color = blend(colors[1], colors[2], (gradientPos - 128) * 2); + } + + if (currentSensorCount != previousCount) { + leds[ledIndex] = blend(leds[ledIndex], color, 45); + } else { + leds[ledIndex] = color; + } + pos--; + } + } + FastLED.show(); + shift = (shift + 2) % sections[0].end; + lightTimer = millis(); + } +} + +// ActivateResponse without for loop +void ActivateResponseRecursive(uint8_t targetBrightness, uint8_t originalBrightness, int step = 0) { + if (step > 30) { + FastLED.setBrightness(originalBrightness); + FastLED.show(); + isActivating = false; + return; + } + + uint8_t currentBrightness = targetBrightness - (targetBrightness - originalBrightness) * step / 30; + FastLED.setBrightness(currentBrightness); + FastLED.show(); + delay(5); + + ActivateResponseRecursive(targetBrightness, originalBrightness, step + 1); +} + +void ActivateResponse() { + if (isActivating) return; + + isActivating = true; + uint8_t originalBrightness = BRIGHTNESS; + uint8_t targetBrightness = min(originalBrightness + 30, 255); + + FastLED.setBrightness(targetBrightness); + FastLED.show(); + delay(50); + + ActivateResponseRecursive(targetBrightness, originalBrightness); +}