Interrupt problems with a Seeeduino

Hello,

I'm working on a project that involves using buttons to light up several LED panels. Depending on which button is pressed, it will light up a different image(s) on the LEDs. After some research, I decided to go with interrupts to handle the button pushes (I will need to do some pin change interrupts on the other pins I will be using). For now, I just wanted to test the regular interrupts on pins 2 and 3. I'm using a Seeeduino, and I guess I just assumed the interrupt pins were pins 2 and 3 (I couldn't find any other board or example that was different so I went with those two).

Now, the interrupt at pin 3 (interrupt1) works just fine. No problems. The interrupt at pin 2 (interrupt0) seems to be resetting the Seeeduino whenever I press it. It is being powered off my laptop at the moment via USB, and my computer makes that annoying sound whenever a USB device is plugged in or unplugged. And the LEDs are being turned off (this is how I have them start up when the Seeeduino is turned on). So my best guess is that the board is getting reset for some reason.

I have to do a few more tests to flesh out what the problem might be, but do you guys have any ideas? I'll post my code tomorrow if you need it (it's late here). Thanks for any help!

The interrupt at pin 2 (interrupt0) seems to be resetting the Seeeduino whenever I press it

How do you have the button wired?

I’m guessing that you have the push buttons wired between pin 2 and GND and between pin 3 and GND, and that you have configured pins 2 and 3 and inputs with the internal pullup resistor enabled. If so, are you sure you don’t have a short between pin 2 and Vcc, or have accidentally initialized pin 2 as a digital output?

yep I have it wired essentially how dc42 put it only I’m using external resistors.

I tried it again with new buttons/wires, and now whenever I click a button to run its ISR, it’s running both ISR that I have implemented. Here’s the ISRs code:

void button0ISR(){
  ledState=1;
  breakLoopFlag = true;
  Serial.print("ledState= ");
  Serial.println(ledState);
  Serial.print("breakLoopFlag= ");
  Serial.println(breakLoopFlag);
}

void button1ISR(){
  ledState = 2;
  breakLoopFlag = true;
  Serial.print("ledState= ");
  Serial.println(ledState);
  Serial.print("breakLoopFlag= ");
  Serial.println(breakLoopFlag);
}

Any thoughts? It doesn’t look like there’s any short circuits. I checked every line. I’m going to be using this Pin Change Library anyway http://www.arduino.cc/playground/Main/PinChangeInt. So is it even worth it to try to get this working? I kind of just wanted to get a feel for interrupts before I use this library mostly. And now it’s bugging me :stuck_out_tongue:

Any thoughts?

Yup. You forgot to post the rest of the sketch.

So is it even worth it to try to get this working?

That is entirely your decision. If you'd like to understand why it is not working, there is a high probability you will get an answer. If you'd prefer to move on, no one here is going to stop you.

Here’s the buttonTest sketch I’ve been using to test the buttons and interrupts:

/*
A test program to test the interrupt function with buttons.
 */

#include "NEWLedControl.h"


LedControl lc=LedControl(12,11,10,4);

volatile  int ledState;
boolean breakLoopFlag;
byte currentLED[32];

const int sizeOfClearScreen = 32;
byte ClearScreen[sizeOfClearScreen] = {
  B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
  B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
  B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
  B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
;

const int sizeOfSmiley = 32;
byte Smiley[sizeOfSmiley] = {
  B00000000,B00000000,B00000000,B00000000,B00111000,B00111000,B00111000,B00000000,
  B00000000,B00111000,B00111000,B00111000,B00000000,B00000000,B00000000,B00000000,
  B00000000,B00000000,B00000000,B00111000,B01111000,B11111000,B11111000,B11111000,
  B11111000,B11111000,B11111000,B01111000,B00111000,B00000000,B00000000,B00000000};
;

const int sizeOfHearts = 32;
byte Heart1[sizeOfHearts] = {
  B00000000,B00000000,B00000000,B11000000,B11100000,B11110000,B11110000,B11100000,
  B11000000,B11100000,B11110000,B11110000,B11100000,B11000000,B00000000,B00000000,
  B00000000,B00000000,B00000000,B00000000,B00001000,B00011000,B00111000,B01111000,
  B11111000,B01111000,B00111000,B00011000,B00001000,B00000000,B00000000,B00000000};
;
byte Heart2[sizeOfHearts] = {
  B00000000,B00000000,B11000000,B11100000,B11110000,B11111000,B11111000,B11110000,
  B11100000,B11110000,B11111000,B11111000,B11110000,B11100000,B11000000,B00000000,
  B00000000,B00000000,B00000000,B00001000,B00011000,B00111000,B01111000,B11111000,
  B11111000,B11111000,B01111000,B00111000,B00011000,B00001000,B00000000,B00000000};
;

void setup() {
  Serial.begin(9600);

  pinMode(2, INPUT);
  pinMode(3, INPUT);
  attachInterrupt(0, button0ISR, RISING);
  attachInterrupt(1, button1ISR, RISING);
  interrupts();
  
  /* The MAX72XX is in power-saving mode on startup, we have to do a wakeup call */
  /* Set the brightness to a medium values */
  /* and clear the display */
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
  
  lc.shutdown(1,false);
  lc.setIntensity(1,8);
  lc.clearDisplay(1);
  
  lc.shutdown(2,false);
  lc.setIntensity(2,8);
  lc.clearDisplay(2);
  
  lc.shutdown(3,false);
  lc.setIntensity(3,8);
  lc.clearDisplay(3);

  ledState = 0;
  breakLoopFlag = false;
  Serial.print("ledState= ");
  Serial.println(ledState);
  Serial.print("breakLoopFlag= ");
  Serial.println(breakLoopFlag);
}

//****************************SUPPORT METHODS***************************************
//
/*
 This method updates the currentLED global variable to reflect the current state of the LEDs.
 It takes an array as a parameter.
 */
void updateCurrentLED(byte newLED[]){
  for(int i=0; i<sizeof(newLED); i++) {
    currentLED[i]= newLED[i];
  }
}

/*
 This method will create a delay() in seconds for whatever number is passed to it.
 */
void delaySeconds(double seconds) {
  seconds=seconds*1000;
  delay(seconds); 
}

/*
 This method writes a single image to the LEDs
 */
void writeImage(byte image[], int sizeOfArray){
  int addr = 0;
  int row = 0;
  for(int i=0; i<sizeOfArray; i++){
    if(row==8){
      row=0;
      addr++;
    }
    lc.setRow(addr,row,image[i]);
    row++;
  }
  updateCurrentLED(image);
}


//**************************************IMAGE METHODS**************************************
//
/*
This method turns all LEDs off.
*/
void clearScreen() {
  writeImage(ClearScreen, sizeOfClearScreen);
}

/*
 This method makes an upright :D face. Static image. This is also the default image for the LEDs.
 */
void smiley() {
  while(!breakLoopFlag){
    writeImage(Smiley, sizeOfSmiley);
  }
  breakLoopFlag = false;
}

/*
 This method makes a heart. Static image.
 */
void heart() {
  while(!breakLoopFlag){
    writeImage(Heart1, sizeOfHearts);
    delaySeconds(.5);
    writeImage(Heart2, sizeOfHearts);
    delaySeconds(.5);
  }
  breakLoopFlag = false;
}


//**************************************ISR METHODS****************************************
//
void button0ISR(){
  ledState=1;
  breakLoopFlag = true;
  Serial.print("ledState= ");
  Serial.println(ledState);
  Serial.print("breakLoopFlag= ");
  Serial.println(breakLoopFlag);
}

void button1ISR(){
  ledState = 2;
  breakLoopFlag = true;
  Serial.print("ledState= ");
  Serial.println(ledState);
  Serial.print("breakLoopFlag= ");
  Serial.println(breakLoopFlag);
}



void loop() {

  switch(ledState) {
  case 1: 
    smiley();
    break; 
  case 2:
    heart();
    break;
  default:
    clearScreen();
  }

}

Note: this is not my final sketch, just a test sketch for the time being. The reason why I have some of those helper methods in there is because I just copy and pasted the necessary ones from my main sketch. I had to implement some of them like that for various reasons (if you’re curious and would like to see my main sketch too just let me know).

After playing with it a little bit, it looks like interrupt1 works fine the first time I press it, if it’s the first interrupt I fire. Once I fire interrupt0, it does the weird thing were both ISRs fire no matter which interrupt I trigger. Again, there don’t appear to be any shorts.

The first button is connected to which pin? What is the other side of the first button connected to?

The second button is connected to which pin? What is the other side of the second button connected to?

void setup() {
  Serial.begin(9600);

  pinMode(2, INPUT);
  pinMode(3, INPUT);
  attachInterrupt(0, button0ISR, RISING);
  attachInterrupt(1, button1ISR, RISING);

First button is connect to pin2 and ground with a resistor on the vcc (can't remember if that makes it a pull-up or pull-down resistor), and it essentially looks like this http://www.ladyada.net/images/arduino/testswitchpullup.jpg. Pin 2 gets set to an INPUT and interrupt0 is turned on on the pin.

Same goes for second button except it is connected to pin3 instead of pin2, and interrupt1 gets turned on for it.

Also, after some more playing around, looks like I can get interrupt0 to work fine. The problem seems to be occurring whenever I fire the second of the two interrupts. Once I do that, whenever I push either button, both ISR fire.

WRONG PICTURE LINK!!

Looks like this: http://www.ladyada.net/images/arduino/testswitchpulldown.jpg

Sorry about that.

I guess I explained it wrong too haha. That second link is how it looks though.

Also, after some more playing around, looks like I can get interrupt0 to work fine. The problem seems to be occurring whenever I fire the second of the two interrupts. Once I do that, whenever I push either button, both ISR fire.

Are you determining that from what is sent through the serial port or what is displayed on the LCD?

I determined that through what is displayed through the Serial port. When I push one button it displays

"ledState= 1" "breakLoopFlag= " "ledState= 2" "breakLoopFlag= "

For some reason the breakLoopFlag isn't showing up in the Serial port. But every time I push either button (after I've pushed the second button) it shows this in the Serial port. And then the LEDs get stuck showing the heart() method. I think when I get back from work today I'm going to try that Pin Change Library, and see how that goes. Hopefully it gets rid of this problem.