Question about changing LED color patterns with a momentary push button

Hi!

My project involves attaching 5 LEDs to a board and programming the LEDs to change color when a momentary push button is pressed.
I am using the following:

Since the GEMMA isn’t fully 100% Arduino-compatible, I am open to using the more compatible Adafruit FLORA (http://www.adafruit.com/products/659#Description) if necessary, although I’d like to stick with the GEMMA if possible because of its smaller size.

I’ve never programmed before, so all my code is cobbled together from tutorials and projects I’ve seen online. It compiles fine in the Arduino IDE, but I can’t get the different color patterns to show when I press the push button. The only color I get is the color from the first pattern.

If someone could help me understand how to get the other color patterns to show up, I would be greatly appreciative. Thank you!

#include <Adafruit_NeoPixel.h>

    int buttonPin = 0;    // momentary push button on pin 0
    int oldButtonVal = 0;
    
    #define PIN 1    // Parameter 1 = number of pixels in strip
                          // Parameter 2 = pin number (most are valid)
                          // Parameter 3 = pixel type flags, add together as needed:
                          // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
                          // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
                          // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
                          // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(5, PIN, NEO_GRB + NEO_KHZ800);
    
    int nPatterns = 8;
    int lightPattern = 1;

// the setup routine runs once when you press reset:
    void setup() {
    strip.begin();
    strip.show();                // initialize all pixels to 'off'    
// initialize the BUTTON pin as an input
    pinMode(buttonPin, INPUT);
    digitalWrite(buttonPin, HIGH);  // button pin is HIGH, so it drops to 0 if pressed
}


// Pattern 1 - White light, all LEDs in the strip are white
    void pattern1() {
        strip.setPixelColor(0, strip.Color(255, 255, 255)); // White
        strip.setPixelColor(1, strip.Color(255, 255, 255));
        strip.setPixelColor(2, strip.Color(255, 255, 255));
        strip.setPixelColor(3, strip.Color(255, 255, 255));
        strip.setPixelColor(4, strip.Color(255, 255, 255));
    strip.show();
    }
    
// Pattern 2 - Red light, all LEDs in the strip are red
    void pattern2() {
        strip.setPixelColor(0, strip.Color(255, 0, 0)); // Red
        strip.setPixelColor(1, strip.Color(255, 0, 0));
        strip.setPixelColor(2, strip.Color(255, 0, 0));
        strip.setPixelColor(3, strip.Color(255, 0, 0));
        strip.setPixelColor(4, strip.Color(255, 0, 0));
    strip.show();
    }
    
// Pattern 3 - Orange light, all LEDs in the strip are orange
    void pattern3() {
        strip.setPixelColor(0, strip.Color(255, 128, 0)); // Orange
        strip.setPixelColor(1, strip.Color(255, 128, 0));
        strip.setPixelColor(2, strip.Color(255, 128, 0));
        strip.setPixelColor(3, strip.Color(255, 128, 0));
        strip.setPixelColor(4, strip.Color(255, 128, 0));
    strip.show();
    }

// Pattern 4 - Yellow light, all LEDs in the strip are yellow
    void pattern4() {
        strip.setPixelColor(0, strip.Color(255, 255, 0)); // Yellow
        strip.setPixelColor(1, strip.Color(255, 255, 0));
        strip.setPixelColor(2, strip.Color(255, 255, 0));
        strip.setPixelColor(3, strip.Color(255, 255, 0));
        strip.setPixelColor(4, strip.Color(255, 255, 0));
    strip.show();
    }
    
// Pattern 5 - Green light, all LEDs in the strip are green
    void pattern5() {
        strip.setPixelColor(0, strip.Color(0, 255, 0)); // Green
        strip.setPixelColor(1, strip.Color(0, 255, 0));
        strip.setPixelColor(2, strip.Color(0, 255, 0));
        strip.setPixelColor(3, strip.Color(0, 255, 0));
        strip.setPixelColor(4, strip.Color(0, 255, 0));
    strip.show();
    }

// Pattern 6 - Blue light, all LEDs in the strip are blue
    void pattern6() {
        strip.setPixelColor(0, strip.Color(0, 0, 255)); // Blue
        strip.setPixelColor(1, strip.Color(0, 0, 255));
        strip.setPixelColor(2, strip.Color(0, 0, 255));
        strip.setPixelColor(3, strip.Color(0, 0, 255));
        strip.setPixelColor(4, strip.Color(0, 0, 255));
    strip.show();
    }
    
// Pattern 7 - Violet light, all LEDs in the strip are violet
    void pattern7() {
        strip.setPixelColor(0, strip.Color(127, 0, 255)); // Violet
        strip.setPixelColor(1, strip.Color(127, 0, 255));
        strip.setPixelColor(2, strip.Color(127, 0, 255));
        strip.setPixelColor(3, strip.Color(127, 0, 255));
        strip.setPixelColor(4, strip.Color(127, 0, 255));
    strip.show();
    }

// Pattern 8 - Rainbow light, all LEDs in the strip are different colors
    void pattern8() {
        strip.setPixelColor(0, strip.Color(255, 0, 255)); // Red
        strip.setPixelColor(1, strip.Color(255, 255, 0)); // Yellow
        strip.setPixelColor(2, strip.Color(0, 255, 0)); // Green
        strip.setPixelColor(3, strip.Color(0, 0, 255)); // Blue
        strip.setPixelColor(4, strip.Color(127, 0, 255)); // Violet
    strip.show();
    }


// the loop routine runs over and over again forever;
void loop() {
  // read that state of the pushbutton value;
  int buttonVal = digitalRead(buttonPin);
  if (buttonVal == LOW && oldButtonVal == HIGH) {// button has just been pressed
    lightPattern == lightPattern + 1;
  }
  if (lightPattern > nPatterns) lightPattern = 1;
  oldButtonVal = buttonVal;
  
  switch(lightPattern) {
    case 1:
      pattern1();
      break;
    case 2:
      pattern2();
      break;
    case 3:
      pattern3();
      break;
    case 4:
      pattern4();
      break;
    case 5:
      pattern5();
      break;
    case 6:
      pattern6();
      break;
    case 7:
      pattern7();
      break;
    case 8:
      pattern8();
      break;
  }
}

IMG_1377.JPG

IMG_1378.JPG

IMG_1380.JPG

There's your problem:

 lightPattern == lightPattern + 1;

You said "==" (comparison) when you meant "=" (assignment).

Thank you so much! I'm so ecstatic! It works now!

Thank you, thank you, thank you! :slight_smile:

Is there a way to do this with an event listener of some kind? I’m new to Arduino code. I modified your code to add some of the standard strand test options. The button is not terribly responsive. And once it hits the rainbow section, the button does nothing.

Any help?

#include <Adafruit_NeoPixel.h>

    int buttonPin = 0;    // momentary push button on pin 0
    int oldButtonVal = 0;
    
    #define PIN 1    // Parameter 1 = number of pixels in strip
                          // Parameter 2 = pin number (most are valid)
                          // Parameter 3 = pixel type flags, add together as needed:
                          // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
                          // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
                          // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
                          // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);
    
    int nPatterns = 8;
    int lightPattern = 1;

// the setup routine runs once when you press reset:
  void setup() {
    strip.begin();
    strip.show();                // initialize all pixels to 'off'  
    strip.setBrightness(64); // initialize brightness  
    
// initialize the BUTTON pin as an input
    pinMode(buttonPin, INPUT);
    digitalWrite(buttonPin, HIGH);  // button pin is HIGH, so it drops to 0 if pressed
}

// the loop routine runs over and over again forever;
void loop() {
  // read that state of the pushbutton value;
  int buttonVal = digitalRead(buttonPin);
  if (buttonVal == LOW && oldButtonVal == HIGH) {// button has just been pressed
    lightPattern = lightPattern + 1;
  }
  if (lightPattern > nPatterns) lightPattern = 1;
  oldButtonVal = buttonVal;
  
  switch(lightPattern) {
    case 1:
      //pattern1();
      colorWipe(strip.Color(255, 0, 0), 50); // Red
      break;
    case 2:
      //pattern2();
      colorWipe(strip.Color(0, 255, 0), 50); // Green
      break;
    case 3:
      //pattern3();
      colorWipe(strip.Color(0, 0, 255), 50); // Blue
      break;
    case 4:
      //pattern4();
      rainbow(20);
      break;
    case 5:
      //pattern5();
      rainbowCycle(20);
      break;
    case 6:
      pattern6();
      break;
    case 7:
      pattern7();
      break;
    case 8:
      pattern8();
      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);
  }
}

// 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) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}


// Pattern 1 - White light, all LEDs in the strip are white
    void pattern1() {
        strip.setPixelColor(0, strip.Color(255, 255, 255)); // White
        strip.setPixelColor(1, strip.Color(255, 255, 255));
        strip.setPixelColor(2, strip.Color(255, 255, 255));
        strip.setPixelColor(3, strip.Color(255, 255, 255));
        strip.setPixelColor(4, strip.Color(255, 255, 255));
    strip.show();
    }
    
// Pattern 2 - Red light, all LEDs in the strip are red
    void pattern2() {
        strip.setPixelColor(0, strip.Color(255, 0, 0)); // Red
        strip.setPixelColor(1, strip.Color(255, 0, 0));
        strip.setPixelColor(2, strip.Color(255, 0, 0));
        strip.setPixelColor(3, strip.Color(255, 0, 0));
        strip.setPixelColor(4, strip.Color(255, 0, 0));
    strip.show();
    }
    
// Pattern 3 - Orange light, all LEDs in the strip are orange
    void pattern3() {
        strip.setPixelColor(0, strip.Color(255, 128, 0)); // Orange
        strip.setPixelColor(1, strip.Color(255, 128, 0));
        strip.setPixelColor(2, strip.Color(255, 128, 0));
        strip.setPixelColor(3, strip.Color(255, 128, 0));
        strip.setPixelColor(4, strip.Color(255, 128, 0));
    strip.show();
    }

// Pattern 4 - Yellow light, all LEDs in the strip are yellow
    void pattern4() {
        strip.setPixelColor(0, strip.Color(255, 255, 0)); // Yellow
        strip.setPixelColor(1, strip.Color(255, 255, 0));
        strip.setPixelColor(2, strip.Color(255, 255, 0));
        strip.setPixelColor(3, strip.Color(255, 255, 0));
        strip.setPixelColor(4, strip.Color(255, 255, 0));
    strip.show();
    }
    
// Pattern 5 - Green light, all LEDs in the strip are green
    void pattern5() {
        strip.setPixelColor(0, strip.Color(0, 255, 0)); // Green
        strip.setPixelColor(1, strip.Color(0, 255, 0));
        strip.setPixelColor(2, strip.Color(0, 255, 0));
        strip.setPixelColor(3, strip.Color(0, 255, 0));
        strip.setPixelColor(4, strip.Color(0, 255, 0));
    strip.show();
    }

// Pattern 6 - Blue light, all LEDs in the strip are blue
    void pattern6() {
        strip.setPixelColor(0, strip.Color(0, 0, 255)); // Blue
        strip.setPixelColor(1, strip.Color(0, 0, 255));
        strip.setPixelColor(2, strip.Color(0, 0, 255));
        strip.setPixelColor(3, strip.Color(0, 0, 255));
        strip.setPixelColor(4, strip.Color(0, 0, 255));
    strip.show();
    }
    
// Pattern 7 - Violet light, all LEDs in the strip are violet
    void pattern7() {
        strip.setPixelColor(0, strip.Color(127, 0, 255)); // Violet
        strip.setPixelColor(1, strip.Color(127, 0, 255));
        strip.setPixelColor(2, strip.Color(127, 0, 255));
        strip.setPixelColor(3, strip.Color(127, 0, 255));
        strip.setPixelColor(4, strip.Color(127, 0, 255));
    strip.show();
    }

// Pattern 8 - Rainbow light, all LEDs in the strip are different colors
    void pattern8() {
        strip.setPixelColor(0, strip.Color(255, 0, 255)); // Red
        strip.setPixelColor(1, strip.Color(255, 255, 0)); // Yellow
        strip.setPixelColor(2, strip.Color(0, 255, 0)); // Green
        strip.setPixelColor(3, strip.Color(0, 0, 255)); // Blue
        strip.setPixelColor(4, strip.Color(127, 0, 255)); // Violet
    strip.show();
    }

drumminhands:
The button is not terribly responsive. And once it hits the rainbow section, the button does nothing.

That is because your patterns use delay() for timing. You have to change them to use the "BlinkWithoutDelay" style of timing. Each pattern will need to keep track of where it is in the pattern and when it needs to go to the next step. Each time the pattern is called it will either be time to go to the next step or it will just return.

Fantastic. Thank you. I'll play with that.

Also, I discovered interrupts in some searches. Would that help me out, or just cause a bigger headache?
http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/

Thanks in advance.

drumminhands:
Fantastic. Thank you. I'll play with that.

Also, I discovered interrupts in some searches. Would that help me out, or just cause a bigger headache?
http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/

Thanks in advance.

Interrupts won't help in this case. You only have a few microseconds in the ISR to do anything before you start to cause timing problems elsewhere. That would give you time to set a flag saying that the button had been pushed. Then you would need to add code in all your pattern loops to exit if the button had been pushed. Any delay longer than about 1/10th of a second would cause that check to be less than responsive. And you could always just check the button directly rather than look for an interrupt-set flag.

The right thing to do is get rid of the delay() calls and return to loop() quickly so the button can be checked frequently.

Awesome. I'll play with that, and when I get working code, post it back here. Thank you.

I had a good night of coding, and this seems to work. One issue with my math on the color wipe function (see the note in the code). Does anyone see anything else weird that I should fix?

/* modified from
 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 https://github.com/adafruit/Adafruit_NeoPixel
 */

#include <Adafruit_NeoPixel.h>

#define PIN 1
#define numPixelsInStrip 8

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixelsInStrip, PIN, NEO_GRB + NEO_KHZ800);

long previousMillis; // will store last time pixel was updated
int neoPixelToChange = 0; //track which neoPixel to change
int neoPixel_j = 0; //stores values for program cycles

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(32); // initialize brightness
}

void loop() {
  // Some example procedures showing how to display to the pixels:

  //allColor(strip.Color(0,255,0));
  //colorWipe(strip.Color(0,0,255), 100); // blue
  //rainbow(20);
  rainbowCycle(20);
}

// Fill all the dots with one color
void allColor(uint32_t c) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
  }
} // note for a random color, use:
  // allColor((unsigned long)random(0x01000000)); // random color
  
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  
  unsigned long currentMillis = millis();
  
  //only do this if some of the pixels still need to be lit
  if (neoPixelToChange <= strip.numPixels()){
    
    if(currentMillis - previousMillis > wait * neoPixelToChange) { //appears to be an exponential growth delay but works
      
      // save the last time you changed a NeoPixel 
      previousMillis = currentMillis;  
    
      //change a pixel
      strip.setPixelColor(neoPixelToChange, c);
      strip.show();
      neoPixelToChange++;
    }
  }
}

void rainbow(uint8_t wait) {
    
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > wait) {
    
    // save the last time you changed a NeoPixel 
    previousMillis = currentMillis; 

    //change the colors of the pixels
    uint16_t i;

    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+neoPixel_j) & 255));
    }
    strip.show();
    neoPixel_j = (neoPixel_j + 1) % 255; //increment j until all colors are used, then start over
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > wait) {
    
    // save the last time you changed a NeoPixel 
    previousMillis = currentMillis; 

    //change the colors of the pixels
    uint16_t i;

    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + neoPixel_j) & 255));
    }
    strip.show();
    neoPixel_j = (neoPixel_j + 1) % 1279; // 5 cycles of all colors on wheel, then start over
  }
}

// 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) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}