digitalPinToInterrupt(20) and (21) wont work on MEGA

the following code works fine if I have the line

const int INTERRUPT_PIN_[] = {0, 18, 19, 2, 3};

but when I change that line to

const int INTERRUPT_PIN_[] = {0, 18, 19, 20, 21};

then the 2 buttons that correspond to pins 20 and 21 achieve nothing ant ISR code for those buttons doesn’t fire.
I have eliminated everything I can think of including swapping out all the hardware including the ARDUINO

const int LED_PIN_[] = {0, 43, 45, 47, 49};
const int DEBOUNCE_DELAY = 150;   // the debounce time; increase if the output flickers
const int INTERRUPT_PIN_[] = {0, 18, 19, 20, 21};
const int BUTTON_PIN_OUT_[] = {0, 31,33,35,37, 39};

//int lastSteadyState[] =      {LOW, LOW, LOW, LOW, LOW};
//int lastFlickerableState[] = {LOW, LOW, LOW, LOW, LOW};
//int currentState[5];
volatile byte ledState_[] = {LOW, LOW, LOW, LOW,LOW};
unsigned long lastDebounceTime[] = {0, 0, 0, 0, 0};


int ii[5];
int ij[5];
void setup() {
  for (int button = 1 ; button  < 5 ; button++)
  {
    pinMode(LED_PIN_[button], OUTPUT);
    pinMode(BUTTON_PIN_OUT_[button], OUTPUT);
    pinMode(INTERRUPT_PIN_[button], INPUT_PULLUP);
    digitalWrite(BUTTON_PIN_OUT_[button], LOW);
  }
    
  Serial.begin(9600); Serial.println("Start up");
//
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_[1]), BtnBounce_1, RISING);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_[2]), BtnBounce_2, RISING);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_[3]), BtnBounce_3, RISING);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_[4]), BtnBounce_4, RISING);
}

void loop() {

}


void BtnBounce_1() {
  int button = 1;
  ii[button] += 1;
 // Serial.print("button_1 Hit");Serial.print(lastDebounceTime[button]); Serial.print("--"); Serial.print( millis());Serial.print("--");Serial.println( millis() - lastDebounceTime[button]);
  if ((millis() - lastDebounceTime[button]) > DEBOUNCE_DELAY) {
    ij[button] += 1;
//    Serial.print("in Here"); Serial.print(ii[button]); Serial.print("--"); Serial.println(ij[button]);
    lastDebounceTime[button] = millis();
  ledState_[button] = !ledState_[button];
  digitalWrite(LED_PIN_[button], ledState_[button]);
  }
}

void BtnBounce_2() {
  int button = 2;
  ii[button] += 1;
//  Serial.print("button_2 Hit");Serial.print(lastDebounceTime[button]); Serial.print("--"); Serial.print( millis());Serial.print("--");Serial.println( millis() - lastDebounceTime[button]);
  if ((millis() - lastDebounceTime[button]) > DEBOUNCE_DELAY) {
    ij[button] += 1;
//    Serial.print("in Here"); Serial.print(ii[button]); Serial.print("--"); Serial.println(ij[button]);
    lastDebounceTime[button] = millis();
  ledState_[button] = !ledState_[button];
  digitalWrite(LED_PIN_[button], ledState_[button]);
  }
}

void BtnBounce_3() {
  int button = 3;
  ii[button] += 1;
//  Serial.print("button_3 Hit");Serial.print(lastDebounceTime[button]); Serial.print("--"); Serial.print( millis());Serial.print("--");Serial.println( millis() - lastDebounceTime[button]);
  if ((millis() - lastDebounceTime[button]) > DEBOUNCE_DELAY) {
    ij[button] += 1;
//    Serial.print("in Here"); Serial.print(ii[button]); Serial.print("--"); Serial.println(ij[button]);
    lastDebounceTime[button] = millis();
  ledState_[button] = !ledState_[button];
  digitalWrite(LED_PIN_[button], ledState_[button]);
  }
}
void BtnBounce_4() {
  int button = 4;
  ii[button] += 1;
//  Serial.print("button_4 Hit");Serial.print(lastDebounceTime[button]); Serial.print("--"); Serial.print( millis());Serial.print("--");Serial.println( millis() - lastDebounceTime[button]);
  if ((millis() - lastDebounceTime[button]) > DEBOUNCE_DELAY) {
    ij[button] += 1;
//    Serial.print("in Here"); Serial.print(ii[button]); Serial.print("--"); Serial.println(ij[button]);
    lastDebounceTime[button] = millis();
  ledState_[button] = !ledState_[button];
  digitalWrite(LED_PIN_[button], ledState_[button]);
  }
}

Guessing I might have missed something that turns pins 20 & 21 to interrupt pins, but I cant see what it is, any help appreciated

for (int button = 1 ; button < 5Oops.

Is that why you’ve zeroed elements in your arrays?

the for loop in the setup is just easier than setting pion modes etc individually didn't really need to use arrays as it's just that I have 4 user input buttons I need to respond to I zero them out as I am naturally a quite defensive programmer and this code is part of a larger suite of stuff

It’s just that array indices start at zero, and you’re using the same for loop for arrays with different numbers of elements - I don’t know what you mean by “defensive” in this context, unless that’s a synonym for “wrong”.

all that does is grabs the last 4 values in the array. I don't like using zero based arrays in names, that is why INTERRUPT_PIN_[0] = 0 so that I can just step over it,
I cant see that that may have a bearing on the code BtnBounce_3 and BtnBounce_4 not firing???

Just to verify, you do not have any additional hardware connected to the Mega, in particular anything that uses the I2C bus or is connected to SCL and SCA?

I don’t like using zero based arrays

Bite the bullet and use them. They are nothing to be afraid of and using arrays the same way that the majority of the World does make sense, don’t you think ?

As it is the < 5 test, although it may work is not very intuitive,is it, because you don’t have 5 useable elements in your array so it adds confusion

Better to use zero based arrays and then you can use < 4 as your test, or better still

int anArray[] = {123, 456, 1234, 4567};
const byte NUMBER_OF_ELEMENTS = sizeof(anArray) / sizeof(anArray[0]);

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  for (int x = 0; x < NUMBER_OF_ELEMENTS; x++)
  {
    Serial.println(anArray[x]);
  }
  Serial.println();
}

void loop()
{
}

This works for any data type and size of array and gives you a descriptive constant variable to use in for loops, with a guarantee of never reading past the end of the array, or if you test the value of the array index being used, never writing past the end of an array, which is possibly even more important

The Mega Rev 3 has 10K pullup resistors on the SDA (20) and SCL (21) pins, so you may never be getting a LOW on the input.

See the upper right corner of the first page of the MEGA2560 Rev3e schematic

@david_2018 there is no other hardware attached, this is a barebones test to just get it running, does this SCL/SDA functionality prevent pins 20 & 21 from being used with a simple button? I had hoped/guessed that that is what INPUT_PULLUP would do

If you run this code and momentarily ground pin 20 and then 21, do you see the on-board LED light for 1-sec and 2-sec respectively?

/*
 * Sketch: 
 * Target:
 *
 */

const uint8_t pin20 = 20;
const uint8_t pin21 = 21;

const uint8_t pinLED = LED_BUILTIN;

volatile uint8_t flag = 0;

void setup() 
{
    pinMode( pin20, INPUT_PULLUP );
    pinMode( pin21, INPUT_PULLUP );

    pinMode( pinLED, OUTPUT );

    attachInterrupt( digitalPinToInterrupt(pin20), isr_pin20, RISING );
    attachInterrupt( digitalPinToInterrupt(pin21), isr_pin21, RISING );

}//setup

void loop() 
{
    if( flag )
    {
        digitalWrite( pinLED, HIGH );
        delay( flag == 1 ? 1000:2000 );
        digitalWrite( pinLED, LOW );
        flag = 0;
    }

}//loop

void isr_pin20( void )
{
    flag = 1;    
}//isr_pin20

void isr_pin21( void )
{
    flag = 2;
        
}//isr_pin21

If the button is pulling the input LOW, then it should be working. How are the buttons wired?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.