Modify neopixel code

Please can someone tell me how to modify this code so that each function loops continually until the button is pressed to change to the next sequence.
At the moment the code stops and the end of each function until the button is pushed.

#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN   2    // Digital IO pin connected to the button.  This will be
// driven with a pull-up resistor so the switch should
// pull the pin to ground momentarily.  On a high -> low
// transition the button press logic will execute.

#define PIXEL_PIN    9   // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 12   // number of neopixel (change this accordingly)

// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Get current button state.
  bool newState = digitalRead(BUTTON_PIN);

  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if (newState == LOW) {
      showType++;
      if (showType > 9)
        showType = 0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
}

void startShow(int i) {
  switch (i) {
    case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
      break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red
      break;
    case 2: colorWipe(strip.Color(0, 255, 0), 50);  // Green
      break;
    case 3: colorWipe(strip.Color(0, 0, 255), 50);  // Blue
      break;
    case 4: theaterChase(strip.Color(127, 127, 127), 50); // White
      break;
    case 5: theaterChase(strip.Color(127,   0,   0), 50); // Red
      break;
    case 6: theaterChase(strip.Color(  0,   0, 127), 50); // Blue
      break;
    case 7: rainbow(20);
      break;
    case 8: rainbowCycle(20);
      break;
    case 9: theaterChaseRainbow(50);
      break;
  }
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Welcome to the forum, and thank you for trying to use code tags. You did it slightly wrong but I have fixed it

Hello,

The problem is in the loop.
The oldState is LOW at the end and no longer runs into the IF condition after a run.
I have check only the loop function and changed some rows and conditions.

void loop() {
  bool newState = digitalRead(BUTTON_PIN);

  if(newState == HIGH) {
    delay(20);
    newState = digitalRead(BUTTON_PIN);
    if(newState == HIGH) {
      // set to the next show
      showType++;
      if (showType > 9){
        showType = 0;
      } 
    }
  }

  // run show by actual showtype
  startShow(showType);
}

Codexier,m3any thanks for responding.
Sorry I made an error in my initial posting I posted 'at the moment the code stops....' however I should have put that I need the code to loop (keep playing) at the end of each sequence (colorwipe,theaterchase,etc)until the button is pressed and then it will move to the next sequence.
I have placed your modified code and now the whole sequences loop continually the button does not do anything when pressed,unless I have probably misunderstood something with the code.
Apologies once again as you can tell I am very new to all this.

Test that button by holding it down, hold it down until the end of the pattern your code is performing, and see if it does change at the end to the next pattern.

Your sequences are paying no attention to the button.

a7

The button now does not do anything when pressed,before it would run the first sequence then stop until button was pressed then moved to the next sequence.
I just do not want each sequence to stop but keep looping until the button is pressed and then move to next sequence where the process repeats.

Moved to programming questions, the home of programming questions :smiley:

No further responses and after lots of searching I discovered the link below which achieves the desired result via a different program.

So now you are using an interrupt, the EEPROM and a portion of assembler code to reset the Arduino, none of which are necessary, but good luck with your project

For anyone wondering and smart enough not to waste time investigating, this is the idea exploited in the solutin:

Eventually I found a sweet little piece of assembler code (unlike the C language Arduino uses) that resets the Arduino and starts over again – we basically let the Arduino jump back to address 0 (zero) so it starts over again. This works great…

I don’t argue with success. If you are happy with that, so am I.

a7

Don't need assembler for that. You can do just as "good" of a hack job in C++:

void (*reset)() = nullptr;

Invoked with:

  reset();

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.