Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!




Question - Modified...
 
Share:
Notifications
Clear all

Question - Modified version of the FLORA Umbrella project

2 Posts
1 Users
0 Likes
351 Views
 Hans
(@hans)
Famed Member Admin
Joined: 9 years ago
Posts: 2311
Topic starter  

Hey there

this is the second time I’ve been trying to write this message, the previous one was marked as spam so I apologize if I’m a little brief.

I’d like to begin just by thanking you for all this work that you put into these effects I really appreciate it and it has been very helpful in helping me learn to code using the fast LED library.

 

I am currently working on a modified version of the FLORA Umbrella project.

essentially it is using the flora controller, the fast LED library, and the one button library. I am trying to create a sketch that can toggle through various effects using auxiliary button. I have been successful in using your code to create other projects, in successful in this project with adding other effects. However when attempting to add the theater chase rainbow effect to the pattern toggling sketch I encounter several problems. First it often takes several coggles to reach the theater effect, meaning that I have to cycle through all the other effects multiple times before I see the theater effect. Once I do reach the theater effect it will no longer allow me to toggle through effects. Another problem I have encountered is that sometimes it won’t even reach the theater chase effect it will actually just freeze end require a restart to continue usage. Not sure where I’m going wrong in the code I’ve tried to trim it down and figure out what it is the essentials but can’t seem to figure out what is stopping this from working and also causing this to freeze.

 

Here is my code,

#include <OneButton.h>
#include <FastLED.h>

#define NUM_LEDS 240
#define LED_PIN 6
#define BTN_PIN 10  
#define NUM_COLORS 5
static const CRGB TwinkleColors [NUM_COLORS] = 
{
    CRGB::Red,
    CRGB::Blue,
    CRGB::Purple,
    CRGB::Green,
    CRGB::Yellow
};     
CRGB leds[NUM_LEDS];
uint8_t patternCounter = 0;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
  
// Push button connected between pin 7 and GND (no resistor required)
OneButton btn = OneButton(BTN_PIN, true, true);
void setup() {
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(50);
  Serial.begin(57600);
   FastLED.clear(true);
  btn.attachClick(nextPattern);
}
void loop() {
  
  switch (patternCounter) {
    case 0:
      movingDots();
      break;
    case 1:
      rainbowBeat();
      break;
    case 2:
      redWhiteBlue();
      break;
    case 3:
      DrawComet();
      break;
    case 4:
      juggle();
      break;
    case 5:
      bpm();
      break; 
    case 6:
      theaterChaseRainbow(50);
      break;
  }
  
  FastLED.show();
  btn.tick();
}
void nextPattern() {
  patternCounter = (patternCounter + 1) % 7; // Change the number after the % to the number of patterns you have
}

void movingDots() {
  
  uint16_t posBeat = beatsin16(30, 0, NUM_LEDS - 1, 0, 0);
  uint16_t posBeat2 = beatsin16(60, 0, NUM_LEDS - 1, 0, 0);
  uint16_t posBeat3 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
  uint16_t posBeat4 = beatsin16(60, 0, NUM_LEDS - 1, 0, 32767);
  // Wave for LED color
  uint8_t colBeat = beatsin8(45, 0, 255, 0, 0);
  leds[(posBeat + posBeat2) / 2] = CHSV(colBeat, 255, 255);
  leds[(posBeat3 + posBeat4) / 2] = CHSV(colBeat, 255, 255);
  fadeToBlackBy(leds, NUM_LEDS, 10);
}

void rainbowBeat() {
  
  uint16_t beatA = beatsin16(30, 0, 255);
  uint16_t beatB = beatsin16(20, 0, 255);
  fill_rainbow(leds, NUM_LEDS, (beatA+beatB)/2, 8);
}

void redWhiteBlue() {
  uint16_t sinBeat = beatsin16(30, 0, NUM_LEDS - 1, 0, 0);
  uint16_t sinBeat2 = beatsin16(30, 0, NUM_LEDS - 1, 0, 21845);
  uint16_t sinBeat3 = beatsin16(30, 0, NUM_LEDS - 1, 0, 43690);
  leds[sinBeat] = CRGB::Pink;
  leds[sinBeat2] = CRGB::Aqua;
  leds[sinBeat3] = CRGB::Green;
  
  fadeToBlackBy(leds, NUM_LEDS, 10);
}
void DrawComet()
{
    const byte fadeAmt = 28;
    const int cometSize = 80;
    const int deltaHue = 4;
    static byte hue = HUE_RED;
    static int iDirection = 1;
    static int iPos = 0;
    hue += deltaHue;
    iPos += iDirection;
    if (iPos == (NUM_LEDS - cometSize) || iPos == 0)
        iDirection *= -1;
    
    for (int i = 0; i < cometSize; i++)
        leds[iPos + i].setHue(hue);
    
    // Randomly fade the LEDs
    for (int j = 0; j < NUM_LEDS; j++)
        if (random(10) > 5)
            leds[j] = leds[j].fadeToBlackBy(fadeAmt);
    delay(10);
}
void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16(i+7,0,NUM_LEDS)] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}
void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 100;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
  }
}
void theaterChaseRainbow(int SpeedDelay) {
  byte *c;
  for (int j=0; j<256; j++) {
    for (int q=0; q<3; q++) {
      for (int i=2; i<NUM_LEDS-2; i=i+3) {
        c = Wheel(j);
        setPixel(i+q, *c, *(c+1), *(c+2));
      }
      showStrip();
      delay(SpeedDelay);
    }
  }
}
byte * Wheel(byte WheelPos) {
  static byte c[3];
 
  if(WheelPos < 85) {
   c[0]=WheelPos * 3;
   c[1]=255 - WheelPos * 3;
   c[2]=0;
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   c[0]=255 - WheelPos * 3;
   c[1]=0;
   c[2]=WheelPos * 3;
  } else {
   WheelPos -= 170;
   c[0]=0;
   c[1]=WheelPos * 3;
   c[2]=255 - WheelPos * 3;
  }
  return c;
}
void showStrip() {
   FastLED.show();
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
}

 

Thank you in advanced for any help!

p.s Trying to finish this for an even next week so hoping to get this fixed by then <3 I’ll def post photos/vids when I finish it!


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 9 years ago
Posts: 2311
Topic starter  

Hi Jack,

sorry that I had to move the code here - as mentioned in the form, we'd prefer folks to not post long code examples in the comments, since it takes up so much space.
No harm done though - all good ... 

So coming to your problem: 

Each of the effects you had before can run one step at a time, each time an effect is called.
So the effect is accomplished by running through the loop in "loop()" (the switch section).

The theatre effect however, runs the entire effect and only returns from the effect back to the "loop()" after the effect has been completed.
Therefor making it impossible to read the button push.

More details on this can be found in the follow-up article I had written: Arduino – All LEDStrip effects in one (NeoPixel and FastLED)
Here I've described the challenges you're looking at right now 🙂 

If the code there doesn't do the trick (looks like you already are using the code from there), then you could add a "break" in the  effect loop.
I haven't used the OneButton library (looks quite useful though!), so I do not really know how that is done.

Example:

void theaterChaseRainbow(int SpeedDelay) {
  byte *c;
  for (int j=0; j<256; j++) {
    for (int q=0; q<3; q++) {
      for (int i=2; i<NUM_LEDS-2; i=i+3) {
        c = Wheel(j);
        setPixel(i+q, *c, *(c+1), *(c+2));
      }
      showStrip();

      // --->>>> HERE: return if button was pressed
      // something like this pseudo code: 
      // if(button pressed) { return; }

      delay(SpeedDelay);
    }
  }
}

 

 it could be that you'd need to call "btn.tick();" there and/or see if patternCounter is still "6" (eg. has not yet changed).

For readability I'd also change the "nextPattern" function to something like this (not many people work work with modulo calculations in this fashion ... as far as I know):

void nextPattern() {
   if(patternCounter<7)  { 
      patternCounter++;   // increase by 1 if not yet at last effect
    } else  {
       patternCounter=0;  // go back to first effect if going beyond last effect
    }
}

 

 Not sure if all this will resolve the issue, but it should get you started 😊 


   
ReplyQuote

Like what you see and you'd like to help out? 

The best way to help is of course by assisting others with their questions here in the forum, but you can also help us out in other ways:

- Do your shopping at Amazon, it will not cost you anything extra but may generate a small commission for us,
- send a cup of coffee through PayPal ($5, $10, $20, or custom amount),
- become a Patreon,
- donate BitCoin (BTC), or BitCoinCash (BCH).

Share: