Arduino interrupt button calls multiple ISRs

Viewed 202

For a project I'm using an Arduino Mega2560 to control a couple of stepper motors with the AccelStepper library. It's the first time I'm using Arduino and I'm writing everything in Arduino IDE 2.0 (I also tried it with IDE 1.8 but no change). It's coming along quite nicely and it's a lot of fun! Everything seems to work as intended. Except for 1 thing.

I'm using 4 buttons to trigger certain events in my code, using the interrupt function. I'm doing this because the accelStepper library asks a lot of proccesing from the arduino and I need as many steps/sec as I can get. When 1 of the interrupts is activated it somehow calls another with it. I've removed everything from the code except the interrupt part to see if just the interrupts would work, but I still have the same issue. With this code I would expect to see a print in the serial of the button I pressed. However, when I press button one it sometimes prints both button 1 and button 2. When I press button 2 it always calls button 1 as well. Sometimes button 1 is printed first, sometimes button 2 is printed first. When I press button 3, button 2 is always called and when I press button 4, button 3 is always called.

As you can see in the code, I'm using port 18 through 21 as interrupt ports and their grounds are all connected to the same GND port on the Arduino. I tried disconnecting all the grounds and only connected button 1 with the Arduino GND. But somehow it still triggers button 2 as long as the cable of the button is still plugged into pin 19. Even though the ground of button 2 is not connected.

What am I doing wrong? Did I misunderstand how the interrupts with input_pullup works? Or am I doing something wrong in my code?

I'm running out of ideas so any help is appreciated!

// Define pins numbers
const int button1 = 18;
const int button2 = 19;
const int button3 = 20;
const int button4 = 21;

// Define variables
volatile bool button1Pressed = false;
volatile bool button2Pressed = false;
volatile bool button3Pressed = false;
volatile bool button4Pressed = false;
float timeTrigger1 = 0;
float timeTrigger2 = 0;
float timeTrigger3 = 0;
float timeTrigger4 = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Startup begins");

  pinMode(button1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button1), interrupt1, FALLING);

  pinMode(button2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button2), interrupt2, FALLING);

  pinMode(button3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button3), interrupt3, FALLING);

  pinMode(button4, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button4), interrupt4, FALLING);

  Serial.println("Startup finished");
}

void loop() {
  if (button1Pressed) {
    Serial.println("button 1 was pressed");
    button1Pressed = false;
  }
  if (button2Pressed) {
    Serial.println("button 2 was pressed");
    button2Pressed = false;
  }
  if (button3Pressed) {
    Serial.println("button 3 was pressed");
    button3Pressed = false;
  }
  if (button4Pressed) {
    Serial.println("button 4 was pressed");
    button4Pressed = false;
  }
}


void interrupt1() {
  if (millis() - timeTrigger1 >= 500) {
    timeTrigger1 = millis();
    button1Pressed = true;
  }
}

void interrupt2() {
  if (millis() - timeTrigger2 >= 500) {
    timeTrigger2 = millis();
    button2Pressed = true;
  }
}

void interrupt3() {
  if (millis() - timeTrigger3 >= 500) {
    timeTrigger3 = millis();
    button3Pressed = true;
  }
}

void interrupt4() {
  if (millis() - timeTrigger4 >= 500) {
    timeTrigger4 = millis();
    button4Pressed = true;
  }
}

EDIT: checking the button state once the ISR is called did the trick. Like the code below.

void interrupt1() {
  if (millis() - timeTrigger1 >= 500 && digitalRead(button1)==LOW) {
    timeTrigger1 = millis();
    button1Pressed = true;
  }
}
0 Answers
Related