Hello, everyone.
I've playing with a programmable LED strip and since I have a 3D printer I printed my own version of the Nano Leaf and run the strip through it, it looks great.
The thing is, I don't want the same effect to run all the time and don't want them on a timer either, so I thought about using a touch sensor (TTP223) to change between one effect and the next.
After a lot of playing around it seems that the only way to get this to work (or at least the only I'e found) is using a State Machine to keep an eye on the button state and change the effect when it detects a HIGH signal.
The program compiles without errors and the Serial Monitor shows when the button is touched and also to which effect it moved... but the LEDs are frozen from the start of the program. Basically, the program fails to call the corresponding effect.
Each effect works perfectly on its own, I tested this by commenting or uncommenting the corresponding function within the loop.
I can't figure it out.
I have the main code and each effect on different tabs within the IDE (it seems more organized this way). I don't think you can upload different tabs here so I'll paste the whole code together and I'll separate each TAB with a comment.
#include <FastLED.h>
#include <Arduino.h>
#define NUM_LEDS 151
#define LED_PIN 3
#define BUTT_PIN 5
#define BRIGHTNESS 255
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 60
CRGBPalette16 currentPalette(CRGB::Black);
CRGBPalette16 targetPalette(PartyColors_p);
void changeEffect();
void setup() {
delay(3000); // power-up safety delay
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
Serial.begin(9600);
}
void loop() {
fadeAnimationWrapper();
//cylon();
//sparkles();
//changeEffect();
}
void changeEffect() {
enum class effectState : uint8_t {
sparkles,
fadeAnimationWrapper,
cylon,
};
static effectState currEffect = effectState::sparkles;
static effectState prevEffect = effectState::sparkles;
static int buttonState = LOW;
static int prevButtonState = LOW;
buttonState = digitalRead(BUTT_PIN);
if (buttonState != prevButtonState) {
if (buttonState == HIGH) {
Serial.println("Button Pressed!");
switch (currEffect) {
case effectState::sparkles:
currEffect = effectState::fadeAnimationWrapper;
Serial.println("Fade Running!!");
break;
case effectState::fadeAnimationWrapper:
currEffect = effectState::cylon;
Serial.println("Cylon Running!!");
break;
case effectState::cylon:
currEffect = effectState::sparkles;
Serial.println("Sparkles Running!!");
break;
}
prevEffect = currEffect;
}
prevButtonState = buttonState;
}
}
// END OF TAB 1 - MAIN CODE
// START OF TAB 2 - CYLON EFFECT
#include <FastLED.h>
#define CLOCK_PIN 13
void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }
void cylon() {
static uint8_t hue = 0;
Serial.print("x");
// First slide the led in one direction
for(int i = 0; i < NUM_LEDS; i++) {
// Set the i'th led to red
leds[i] = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
// Now go in the other direction.
for(int i = (NUM_LEDS)-1; i >= 0; i--) {
// Set the i'th led to red
leds[i] = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
}
// END OF TAB 2 - CYLON EFFECT
// START OF TAB 3 - FADE ANIMATION EFFECT
void fadeAnimationWrapper() {
fadeAnimation(random(256), random(256), random(256));
}
void fadeAnimation(int red, int green, int blue) {
float r, g, b;
uint32_t startTime = millis();
uint32_t totalTime = 1000; // total time for fade in and out, in milliseconds
// Define array of durations for fade in and fade out
uint32_t fadeInDurations[] = {600, 800, 1000, 1200, 1600, 2000, 2500};
uint32_t fadeOutDurations[] = {600, 800, 1000, 1200, 1600, 2000, 2500};
int numFadeInDurations = sizeof(fadeInDurations) / sizeof(fadeInDurations[0]);
int numFadeOutDurations = sizeof(fadeOutDurations) / sizeof(fadeOutDurations[0]);
// Randomly select duration for fade in and fade out
uint32_t fadeInTime = fadeInDurations[random(numFadeInDurations)];
uint32_t fadeOutTime = fadeOutDurations[random(numFadeOutDurations)];
// FADE IN
while (millis() - startTime <= fadeInTime) {
float progress = (float)(millis() - startTime) / (float)fadeInTime;
r = progress * red;
g = progress * green;
b = progress * blue;
fill_solid(leds, NUM_LEDS, CRGB(r, g, b));
FastLED.show();
}
// FADE OUT
startTime = millis(); // reset start time for fade out
while (millis() - startTime <= fadeOutTime) {
float progress = 1.0 - ((float)(millis() - startTime) / (float)fadeOutTime);
r = progress * red;
g = progress * green;
b = progress * blue;
fill_solid(leds, NUM_LEDS, CRGB(r, g, b));
FastLED.show();
}
}
// END OF TAB 3 - FADE ANIMATION EFECT
// START OF TAB 4 - SPARKLES EFFECT
void sparkles()
{
ChangePalettePeriodically();
uint8_t maxChanges = random(48); // values 0-48 (Max colors at play)
nblendPaletteTowardPalette( currentPalette, targetPalette, maxChanges);
static uint8_t startIndex = 0;
startIndex = startIndex + 1; /* motion speed */
FillLEDsFromPaletteColors( startIndex);
FastLED.show();
FastLED.delay(1000 / UPDATES_PER_SECOND);
}
void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
uint8_t brightness = 255;
for( int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette( currentPalette, colorIndex + sin8(i*16), brightness);
colorIndex += 3;
}
}
void ChangePalettePeriodically()
{
uint8_t secondHand = (millis() / 1000) % 60;
switch(secondHand) {
case 0:
targetPalette = RainbowColors_p;
break;
case 10:
targetPalette = CRGBPalette16( CHSV(HUE_GREEN, 255, 255), CHSV(HUE_PURPLE, 255, 255), CRGB::Black, CRGB::Black, CHSV(HUE_PURPLE, 255, 255), CHSV(HUE_GREEN, 255, 255), CRGB::Black, CRGB::Black, CHSV(HUE_PURPLE, 255, 255), CHSV(HUE_GREEN, 255, 255), CRGB::Black, CRGB::Black, CHSV(HUE_PURPLE, 255, 255), CHSV(HUE_GREEN, 255, 255), CRGB::Black, CRGB::Black );
break;
case 20:
targetPalette = CRGBPalette16( CRGB::Black, CRGB::Black, CRGB::Black, CRGB::White, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::White, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::White, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::White );
break;
case 30:
targetPalette = LavaColors_p;
break;
case 40:
targetPalette = CloudColors_p;
break;
case 50:
targetPalette = PartyColors_p;
break;
}
}
Thank you!!
