Help with interrupts

Hey, hopefully this request is in the correct location, I am looking for help with an interrupt issue. I am trying to get a program running that is interrupted when a button is pushed, and there is going to be a number of buttons.

I am using IDE version 1.0.6 and have a BareBones Arduino from ModernDevices.com that a friend set me up with. It has a Atmel 328 processor on it. For the sake of testing I have two buttons (normal open, momentary closed) and a digital RGB led strip wired to the Arduino. The LED strip works great. The idea is that on a button press the LED strip will change colors. Buttons are wired so that the input pin on the Arduino is low and button pulls it high.

Here is my code.

#include "LPD8806.h"
#include "SPI.h" 

// Light strand setup
int nLEDs = 32;
int dataPin  = 2;
int clockPin = 3;
int maxPower = 25; //Maximum brightness of LEDs
LPD8806 strip = LPD8806(nLEDs, dataPin, clockPin);

volatile unsigned int color = 0;
volatile unsigned int pattern = 0;

// Button constants
int bluePin = 8;
int redPin = 9;

//int yellowPin = 3;
//int greenPin = 5;
//int whitePin = 9;
//int blackPin = 11;

void setup() {
  // Start up the LED strip
  strip.begin();
  Serial.begin(9600);
  
  //Setup the interrupts
  cli();		// switch interrupts off while messing with their settings  
  PCICR =0x01;          // Enable PCINT1-7 interrupt
  PCMSK0 = 0b00001111;
  sei();		// turn interrupts back on

  // Update the strip, to start they are all 'off'
  strip.show();
  
  //Button setups
  pinMode(bluePin, INPUT);
  pinMode(redPin, INPUT);
  
  Serial.println("Setup Complete");
}
ISR(PCINT0_vect) {    // Interrupt service routine. Every single PCINT8..14 
  if (digitalRead(8)==0)  color=1;//Serial.println("8");
  if (digitalRead(9)==0)  color=2;//Serial.println("9");
  if (digitalRead(10)==0)  color=3;//Serial.println("10");
}

// Fill the dots progressively along the strip.
void colorWipe(uint32_t c, uint8_t wait) {
  int i;

  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}
void loop() {
  if (color == 0) {
    //null
  } else if (color == 1) {
    Serial.println("Strip is BLUE.");
    colorWipe(strip.Color(  0,   0, 127), 50); // Blue
  } else if (color == 2) {
    Serial.println("Strip is RED.");
    colorWipe(strip.Color(127,   0,   0), 50); // Red
  } else if (color == 3) {
    //null
  } else if (color == 4) {
    //null
  }
}

Once this is all figured out I am going to have 5 or 6 buttons, each one can interrupt the program. Because of this I am trying to use the second interrupt setup that I found on the following page. Using attachinterrupt() seems to only work on certain pins, and on the 328 there is only 2 int pins from what I can tell.

http://www.geertlangereis.nl/Electronics/Pin_Change_Interrupts/PinChange_en.html

I used the Atmel datasheet to tweak this for my processor chip. The problem is that I should be able to press the button on 8 and the led strip goes blue and the button on 9 and it goes red. This isn't what is happening. Pressing button on 8 does nothing, no led change and no serial output. The button on 9 the strip goes blue and I get serial output says the strip is blue. I have double and triple checked the wiring and it is correct. Buttons are pulled to ground and a press puts them high. I can put a meter on the pins and confirm that the buttons are working as expected.

What am I missing here in regards to interrupts and how to configure them? I feel like it is my code that is the problem and not the wiring of the project. Thanks in advance for any help or pointers.

Philip

 delay(wait);

Interrupts?

You say

Buttons are pulled to ground and a press puts them high.

Code says

ISR(PCINT0_vect) {    // Interrupt service routine. Every single PCINT8..14 
  if (digitalRead(8)==0)  color=1;//Serial.println("8");
  if (digitalRead(9)==0)  color=2;//Serial.println("9");
  if (digitalRead(10)==0)  color=3;//Serial.println("10");
}

@AWOL - the delay is not in the ISR.

Mark

If the buttons are being pressed by a human then I can think of no reason why interrupts would be necessary. Polling will be plenty fast enough if the rest of the code is properly organized.

There may be some ideas in the demo several things at a time

...R

@holes -I can see that.
I'm asking why the OP thinks interrupts are necessary.

@AWOL - that delay is there because the original code for that feature in the in the LED sample strip had it there. Still learning Arduino programming, is there a better way to get this done?

@Robin2 - I will redo it and see how it works with a straight button press. Final version will also have a encoder in place that will be the main item being watched. The button presses will interrupt this, the program will deal with the button and then back to watching the encoder.

Philip

The button presses will interrupt this, the program will deal with the button and then back to watching the encoder.

You've got it backwards. Typically, encoders drive interrupts pins/interrupt handlers, and the loop() function checks switches.

You say the buttons pull high when pressed - so you are using external pull-down resistors?

Your interrupt routine looks for buttons pulling low, not high.

Final version will also have a encoder in place that will be the main item being watched. The button presses will interrupt this, the program will deal with the button and then back to watching the encoder.

If your loop speed is racing along at 100ms/iteration and your reaction time to press a button is say 25-50ms, then perhaps an interrupt will be beneficial. This Reaction Time Test will help determine if an interrupt is required.