Stuck! Switching between different functions using a button.

I have the following code where I run 8 different animations on an LED strip. All animations are defined in a function. I toggle between animations using a button switch, when I push the button it switches to the next animation. However there is an issue with the 8th animation the cylon()

When I reach this animation, there is a small line of light that travels back and forth on the strip, I believe because of this intensive animation my pushing the button does not register and I am usually stuck on this animation. Is there a way to overcome this problem?

full code is here: http://codepaste.net/uh5xs6

FULL CODE IS HERE

Wrong place for it. It should be HERE. Use Reply (NOT the quick reply field) and the Additional Options link to attach your code here.

Is there a way to overcome this problem?

Yes.

IT gets stuck in the 9000 character limit!

here is a modified paste:

***deleted header code





////SETUP
void setup() {
  Serial.begin(57600);
  pinMode(buttonPin, INPUT);
  delay(3000); // 3 second delay for recovery
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness( BRIGHTNESS );
  
  // TGAN_Potentiometer_1
  for (int thisReading1 = 0; thisReading1 < numReadings1; thisReading1++)
    readings1[thisReading1] = 0;
  // TGAN_Potentiometer_1


  // TGAN_Potentiometer_2
  for (int thisReading2 = 0; thisReading2 < numReadings2; thisReading2++)
    readings2[thisReading2] = 0;
  // TGAN_Potentiometer_2




}



// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm, cylon };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))


void loop()
{

  // TGAN_Potentiometer_1
  total1 = total1 - readings1[index1];
  readings1[index1] = analogRead(pot1PinA0);
  total1 = total1 + readings1[index1];
  index1 = index1 + 1;
  if (index1 >= numReadings1)
    index1 = 0;
  average1 = total1 / numReadings1;

  pot1Value = analogRead(pot1PinA0);
  Pot1MappedOutputValue = map(average1, 0, 1023, 0, 145);
  // TGAN_Potentiometer_1


  // TGAN Potentiometer2--------------------
  total2 = total2 - readings2[index2];
  readings2[index2] = analogRead(pot2PinA3);
  total2 = total2 + readings2[index2];
  index2 = index2 + 1;
  if (index2 >= numReadings3)
    index2 = 0;
  average2 = total2 / numReadings2;

  pot2Value = analogRead(pot2PinA3);
  Pot2MappedOutputValue = map(pot2Value, 0, 1023, 0, 155);
  // TGAN Potentiometer2



  // TGAN Potentiometer3--------------------
  total3 = total3 - readings3[index3];
  readings3[index3] = analogRead(pot3PinA5);
  total3 = total3 + readings3[index3];
  index3 = index3 + 1;
  if (index3 >= numReadings3)
    index3 = 0;
  average3 = total3 / numReadings2;

  pot3Value = analogRead(pot3PinA5);
  Pot3MappedOutputValue = map(pot3Value, 0, 1023, 6, 255);
  // TGAN Potentiometer3


  buttonState = analogRead(buttonPin);

  int oldPot1MappedOutputValue;
 int oldPot2MappedOutputValue;
  int oldPot3MappedOutputValue;
  
  if (Pot1MappedOutputValue != oldPot1MappedOutputValue) 
  {
    Serial.print("pot1Value: "); Serial.print(pot1Value); Serial.print(" / Pot1MappedOutputValue: "); Serial.println(Pot1MappedOutputValue);
  }
  oldPot1MappedOutputValue = Pot1MappedOutputValue;


 if (Pot2MappedOutputValue != oldPot2MappedOutputValue) 
  {
   Serial.print("                                           pot2Value: "); Serial.print(pot2Value); Serial.print(" / Pot2MappedOutputValue: "); Serial.println(Pot2MappedOutputValue);
  }
  oldPot2MappedOutputValue = Pot2MappedOutputValue;

  
 if (Pot3MappedOutputValue != oldPot3MappedOutputValue) 
  {
 Serial.print("                                                                      pot3Value: "); Serial.print(pot3Value); Serial.print(" / Pot3MappedOutputValue: "); Serial.println(Pot3MappedOutputValue);
  }
  oldPot3MappedOutputValue = Pot3MappedOutputValue;

  
 

  Serial.print(" ***** Button Push Counter: "); Serial.println(buttonPushCounter);
Serial.print(" ***** digitalRead(buttonPin);: "); Serial.println(buttonState);



  // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();

  uint8_t bright = beatsin8(Pot1MappedOutputValue, DIMMEST, Pot3MappedOutputValue);
  FastLED.setBrightness( bright );
  FastLED.show();  // send the 'leds' array out to the actual LED strip
  FastLED.delay(1000 / FRAMES_PER_SECOND);  // insert a delay to keep the framerate modest

  // do some periodic updates
  EVERY_N_MILLISECONDS( 5 ) {
    gHue = gHue + 5; // slowly cycle the "base color" through the rainbow
  }
  ButtonSwitch();
}



void ButtonSwitch() {
  if (buttonState != lastButtonState) {
    if (buttonState == 1023) {
      nextPattern();
      //buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } else {
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  lastButtonState = buttonState;
  if (buttonPushCounter % 7 == 0) {
    buttonPushCounter = 0;
  } else {
  }
};

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

void rainbow()
{
  // FastLED's built-in rainbow generator

  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

void rainbowWithGlitter()
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter)
{
  if ( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void confetti()
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16(Pot2MappedOutputValue, 0, NUM_LEDS);
  leds[pos] += CHSV( gHue, 255, 192);
}

void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = Pot2MappedOutputValue;
  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 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 cylon() {
  static uint8_t hue = 0;
  for (int i = 0; i < NUM_LEDS; i++) { // First slide the led in one direction
    leds[i] = CHSV(hue++, 255, 255);   // Set the i'th led to red
    FastLED.show();  // Show the leds
    //  leds[i] = CRGB::Black;   // now that we've shown the leds, reset the i'th led to black
    fadeall();
    delay(122); // Wait a little bit before we loop around and do it again
  }
  fadeall();
  Serial.print("Backward");
  for (int i = (NUM_LEDS) - 1; i >= 0; i--) { // Now go in the other direction.
    leds[i] = CHSV(hue++, 255, 255);  // Set the i'th led to red
    FastLED.show(); // Show the leds
    //    leds[i] = CRGB::Black;  // now that we've shown the leds, reset the i'th led to black
    fadeall();
    delay(10);  // Wait a little bit before we loop around and do it again
  }


}

void fadeall() {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i].nscale8(250);  // Reduce color to 95% (250/256ths) of its previous value  eventually fading to full black

  }

  if (buttonState == 1023) {
    gPatterns[0]();
  }
}

Well, the obvious difference with the Cylon animation is that it has delay(122) in it. The others don’t delay nearly that long.

You really need to get rid of all delays and switch to using timing like Blink_Without_Delay. That seems like a major pain to re-write now but it will pay off immediately with better responsiveness and more abilities for your program.

The delay() happens in a loop, so there is no telling how long the function actually takes to execute, since you couldn't follow directions and post your code properly.

That codepaste site is actually more convenient than attaching an .ino file which has to be downloaded. Likewise with pastebin.

@nervusvagus, there is a great deal of code in your loop() function. Can you not move almost all of that into other functions? Have a look at Planning and Implementing a Program

Why are you using analogRead() to detect a button state?

I reckon you should take ALL the delay()s out of your program. See how timing is managed without blocking using millis() in the above link or in the shorter demo Several Things at a Time

You have several FOR loops. If any of them takes more than a few microseconds I would replace it with IF and some counting code and let loop() do the iteration.

...R

That codepaste site is actually more convenient than attaching an .ino file which has to be downloaded. Likewise with pastebin.

Not if you can’t access them. My employer blocks access to those sites, because there is no proof that the code has been scanned for viruses.

PaulS: Not if you can't access them.

Fair point. Let's encourage people to do both - use codepaste (or pastebin) AND attach files.

...R