pushbutton code help

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
mariec
 
Posts: 4
Joined: Wed Aug 14, 2013 2:57 pm

pushbutton code help

Post by mariec »

I'm working on my first real project, a nightlight for my daughter, and am running into what I think is a coding problem. I have a Gemma running a strip of 10 neopixels and a pushbutton. I am a total coding newbie and have mashed this code together from different places in order to change the display when the button is pressed. The problem I am having is the display doesn't seem to change when running something complex like Rainbow or Rainbowcycle. I'm not sure where I am going wrong. Any help or pointers would be greatly appreciated.
Thanks!

Code: Select all

#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(10, PIN, NEO_GRB + NEO_KHZ800);
    
    int nPatterns = 6;
    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 - Red light, all LEDs in the strip are red
    void pattern1(uint8_t wait) {
  uint16_t i, j;

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

// Pattern 2 - Rainbow
void pattern2(uint8_t wait) {
  strip.setBrightness(60);
  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);
  }
}    

    
// Pattern 3 - Cyan light, all LEDs in the strip are cyan
    void pattern3(uint8_t wait) {
  uint16_t i, j;

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

// Pattern 4 - Green light, all LEDs in the strip are green
    void pattern4(uint8_t wait) {
  uint16_t i, j;

    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(24, 139, 34));
    }
    strip.show();
    delay(wait);
    }
    
// Pattern 5 - Orange light, all LEDs in the strip are green
    void pattern5(uint8_t wait) {
  uint16_t i, j;

    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(255, 69, 0));
    }
    strip.show();
    delay(wait);
    }

// Pattern 6 - Rainbowcycle
void pattern6(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);
    }
}

// Pattern 7 - Violet light, all LEDs in the strip are violet
    void pattern7(uint8_t wait) {
  uint16_t i, j;

    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, strip.Color(199, 21, 133));
    }
    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);
  }
}    

// 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(20);
      break;
    case 2:
      pattern2(10);
      break;
    case 3:
      pattern3(20);
      break;
    case 4:
      pattern4(20);
      break;
    case 5:
      pattern5(20);
      break;
    case 6:
      pattern6(10);
      break;
    case 7:
      pattern7(20);
      break;
  }
}

1chicagodave
 
Posts: 564
Joined: Wed Jun 19, 2013 3:35 am

Re: pushbutton code help

Post by 1chicagodave »

The term is "blocking". Arduino can only, literally, run one instruction at a time. Even though it can perform millions of them each second....they all happen one at a time.

While in a for loop

Code: Select all

    for(i=0; i< strip.numPixels(); i++) 
{
      strip.setPixelColor(i, strip.Color(255, 0, 0));
}
...or in a delay(), nothing else can happen. This includes checking to see if you pressed a button. There are no calls to see if the button is pressed in any of the pattern functions. So, while one of those is running, it will not sense the button push. It will only check once during a brief time between cycles of the pattern function.

There may be better ways to solve this. But right now I can think of two things to try.

One would be adding a

Code: Select all

  int buttonVal = digitalRead(buttonPin);
...and then instructions on what to do...into every pattern function or for loop. But that has its drawbacks.

A better, yet slightly more advanced, solution would be to use an interrupt. That will "interrupt" the code whenever the button is pressed.
You can google 'Arduino pin change interrupt' for examples & help. Also, try these:
http://playground.arduino.cc/Code/Interrupts
http://www.gammon.com.au/forum/?id=11488

....and you may want to look at this too:
http://arduino.cc/en/Tutorial/Debounce

Good luck!

User avatar
adafruit_support_bill
 
Posts: 88092
Joined: Sat Feb 07, 2009 10:11 am

Re: pushbutton code help

Post by adafruit_support_bill »

Some good advice from ChicagoDave. Given all the "delay()" calls in your code, I think interrupts will give you the most reliable button-press detection. Still, in order to break out of your pattern loops early, you will need to add some checks in your loops to see if the button press has been detected.

The easiest way to do that is to set a 'flag' variable in your interrupt routine to indicate that a button has been pressed. In your pattern loops, check the flag on each pass. If you see that it is set, reset it and exit the loop.

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”