How to Enable the interrupts on pins D4, D12, A0-A5 on Arduino Mega 2560 board

Hi,
I have developed a sketch working on Arduino UNO, to enable interrupts on the following pins: D4, D12, A0-A5.
That sketch uses <avr/io.h> and <avr/interrupt.h>.
Now I wish to do the same on Arduino Mega 2560 Board.
Therefore I ask to this forum if there is some sketch example to programming Arduino Mega 2560 in such way or where I could find some information about it.

Thanks in advanced
Marcello Pol

The MEGA programming should be very similar to the UNO programming. You just need to know the port and pin for each of the Arduino pins you want to manipulate. You can get that information from:

D4 is PORTG bit 5.
D12 is PORTB bit 6.
Pins A0 through A7 are on PORTF bits 0 through 7.

If you are working with Pin Change Interrupts you can find the right registers and bits in the ATmega2560 datasheet.

johnwasser: https://spreadsheets.google.com/spreadsheet/pub?key=0AtfNMvfWhA_ccnRId19SNmVWTDE0MEtTOV9HOEdQa0E&gid=0

I hate to say this, after the messy events of the past couple of days [see this thread for the gory details], http://forum.arduino.cc/index.php?topic=187422.0 but there are errors in that file for the Mega board, just as on the Mega board schematic and pinout diagrams. Basically the Arduino "experts" don't seem to see the problems - or else they might actually [u]fix[/u] them - but dumb coders like me get burned, and end up wasting an awful lot of time.

First off, on the spreadsheet where it says

pin Int 8, Pin Int 4, etc

they are referring to PCINT8, PCINT4, ie the pin change interrupts. No big deal.

However, the other lines are where the big mess is, namely

pin Arduino 328 Arduino Mega 2 PD 2 Ext Int 0 PE 4 PWM T3B, INT4 3 PD 3 PWM T2B, Ext Int 1 PE 5 PWM T3C, INT5 18 PC 4 4 I2C SDA PD 3 USART1 TX, Ext Int 3 19 PC 5 5 I2C SCL PD 2 USART1 RX, Ext Int 2 20 PD 1 I2C SDA, Ext Int 1 21 PD 0 I2C SCL, Ext Int 0

So, without going through the entire other thread again, what you need to do is look at the following web page http://arduino.cc/en/Reference/AttachInterrupt to get the "correct" info, where it says,

The table below shows the available interrupt pins on various boards.

Board int.0 int.1 int.2 int.3 int.4 int.5 Uno 2 3 Mega2560 2 3 21 20 19 18

You'll notice these pages match for the UNO board, but not for the Mega.

So, hopefully this will save Marcello some time when he tries to use these things.

oric_dan: So, hopefully this will save Marcello some time when he tries to use these things.

Since he was using Pin 4, Pin 12, and Pins A0-A5 I assumed he was using Pin Change interrupts, not the External interrupts.

johnwasser:

oric_dan: So, hopefully this will save Marcello some time when he tries to use these things.

Since he was using Pin 4, Pin 12, and Pins A0-A5 I assumed he was using Pin Change interrupts, not the External interrupts.

I did too, but just the same, this sort of thing needs to be mentioned, since he's using the Mega board, and especially as every doco I've seen so far shows it wrong - or at least doesn't indicate the existence of the discrepancies. Sometimes all you can do is shake your head, and wonder WTF.

Thanks for your replies.
I’ll study and try your indications and information.
To enable pin4, pin12 and pins A0-A5 interrupts on Arduino UNO, I have used the following method .
Is there another mothod to associate an interrupt a these pins (pin state changes).
Thanks again
Marcello

// -------------------------- Gestione Interrupts ------------------------------------>
void InitialiseIO(){
// --------- Finecorsa-------
  pinMode(Pin_FinecorsaX_0, INPUT_PULLUP); // Pin_FinecorsaX_0 is input to which a switch is connected
  digitalWrite(Pin_FinecorsaX_0, HIGH); // Configure internal pull-up resistor

  pinMode(Pin_FinecorsaY_0, INPUT_PULLUP); 
  digitalWrite(Pin_FinecorsaY_0, HIGH); 

 
//---- Joysticks -------
  
  pinMode(JoystickXP, INPUT_PULLUP); 
  digitalWrite(JoystickXP, HIGH); 

  pinMode(JoystickXM, INPUT_PULLUP); 
  digitalWrite(JoystickXM, HIGH); 

  pinMode(JoystickYP, INPUT_PULLUP); 
  digitalWrite(JoystickYP, HIGH); 

  pinMode(JoystickYM, INPUT_PULLUP); 
  digitalWrite(JoystickYM, HIGH); 
  
  pinMode(JoystickZP, INPUT_PULLUP); 
  digitalWrite(JoystickZP, HIGH); 

  pinMode(JoystickZM, INPUT_PULLUP); 
  digitalWrite(JoystickZM, HIGH); 


}
void InitialiseInterrupt(){
  cli(); // switch interrupts off while messing with their settings
 
  //----------------- Pin 12 digitale -------------------
  PCICR = (1<<PCIE0);//pin12
  PCMSK0 = (1<<PCINT4);

  //----------------- Pin 4 digitale -------------------
  PCICR |= (1<<PCIE2);
  PCMSK2 = (1<<PCINT20);

  //----------------- Pin A0  -------------------
  PCICR |= (1<<PCIE1);
  PCMSK1 = (1<<PCINT8);//A0
  
 //----------------- Pin A1  -------------------
  PCMSK1 |= (1<<PCINT9);//A1
  
 //----------------- Pin A2  -------------------
  PCMSK1 |= (1<<PCINT10);//A2
 
 //----------------- Pin A3  -------------------
  PCMSK1 |= (1<<PCINT11);//A3
  
   //----------------- Pin A4  -------------------
  PCMSK1 |= (1<<PCINT12);//A4
  
  //----------------- Pin A5  -------------------
  PCMSK1 |= (1<<PCINT13);//A5

  MCUCR = (1<<ISC00) | (1<<ISC01);//fondamentale 
  /*  MCUCR = (1<<ISC0#) | (1<<ISC0#);
  This line of code tells the chip which type of change triggers the interrupt. ISC0 is the value we are
  modifying. Inputting a 1 or a 0 at the # will determine the state. 0 0 triggers at any low level. 01 triggers
  at any change. 1 0 triggers at a falling edge. 1 1 triggers at a rising edge.
  */
  sei(); // turn interrupts back on
}

// serve interrupts per pin da 8 a 13
ISR(PCINT0_vect) {

//  cli(); // switch interrupts off while messing with their settings
int Fc_0=digitalRead(Pin_FinecorsaX_0);
  
  if ((Fc_0==LOW))
  {
    Ind_Fine_Corsa_ON_X=1;
    if (currentDirectionX==0)
    {
      Mot_Step_X=0;
      Ind_Fine_Corsa_ON_X0=1;
      Ind_Fine_Corsa_ON_XF=0;
     
    }
    else
    {
      Ind_Fine_Corsa_ON_X0=0;
      Ind_Fine_Corsa_ON_XF=1;
    }    
//    if (digitalRead(Pin_FinecorsaX_0)==LOW)   Serial.print(F("==>"));Serial.println("D12");
//    if (digitalRead(Pin_FinecorsaX_F)==LOW)   Serial.print(F("==>"));Serial.println("D4");
  }
  else
    Ind_Fine_Corsa_ON_X=0;
  //sei(); // turn interrupts back on  
  delayMicroseconds(1000); 
  
  Ind_Cambiamento=1;//29/08/2013
}

// serve interrupts per pin A0-A5
ISR(PCINT1_vect) {
  //cli(); // switch interrupts off while messing with their settings
  

  if ((digitalRead(JoystickXP)==LOW) || (digitalRead(JoystickXM)==LOW) )
  {
    if (digitalRead(JoystickXP)==LOW)     Ind_Joystick_X=-1;
    if (digitalRead(JoystickXM)==LOW)     Ind_Joystick_X=1;
//NO    POS_motorX_Simple(1, 10);
    //Serial.print(F("Ind_Joystick_X="));//Serial.print(Ind_Joystick_X);
  }  
  else
  {
     Comando=="";
     Ind_Joystick_X=0;
  }  
  if ((digitalRead(JoystickYP)==LOW) || (digitalRead(JoystickYM)==LOW) )
  {
    if (digitalRead(JoystickYP)==LOW)     Ind_Joystick_Y=-1;
    if (digitalRead(JoystickYM)==LOW)     Ind_Joystick_Y=1;
//NO    POS_motorX_Simple(1, 10);
//    Serial.print(F("Ind_Joystick_Y="));    Serial.print(Ind_Joystick_Y);
  }  
  else
  {
     Comando=="";
     Ind_Joystick_Y=0;
  }  
  
  if ((digitalRead(JoystickZP)==LOW) || (digitalRead(JoystickZM)==LOW) )
  {
    if (digitalRead(JoystickZP)==LOW)     Ind_Joystick_Z=-1;
    if (digitalRead(JoystickZM)==LOW)     Ind_Joystick_Z=1;
  }  
  else
  {
     Comando=="";
     Ind_Joystick_Z=0;
  }  

//  sei(); // turn interrupts back on
  delayMicroseconds(1000); 
  
  Ind_Cambiamento=1;//29/08/2013
}

// serve interrupts per pin da 0 a 7
ISR(PCINT2_vect) { 
//  cli(); // switch interrupts off while messing with their settings

  int Fc_0=digitalRead(Pin_FinecorsaY_0);
  if (Fc_0==LOW)
  {
    Ind_Fine_Corsa_ON_Y=1;
    if (currentDirectionY==0)
    {
      Mot_Step_Y=0;
      Ind_Fine_Corsa_ON_Y0=1;
      Ind_Fine_Corsa_ON_YF=0;
    }
    else
    {
      Ind_Fine_Corsa_ON_Y0=0;
      Ind_Fine_Corsa_ON_YF=1;
    }  
  }  
  else
    Ind_Fine_Corsa_ON_Y=0;

  //sei(); // turn interrupts back on
  delayMicroseconds(1000); 
  Ind_Cambiamento=1;//29/08/2013
}
// <-------------------------- Gestione Interrupts ------------------------------------

Thanks again

Looks like PORTG (Pin D4) and PORTF (A0-A5) don't support Pin Change interrupts. You will have to switch to other pins. Only PORTB, PORTE pin 0, PORTJ pins 0 through 6, and PORTK support Pin Change interrupts on the ATmega2560.

Hello Johnwasser, thanks for your information. Could you indicate where i'd be able to find an example or could you post an example of code to enable Pin Change interrupts on Arduino Mega 2560 (ATmega2560) on PORTJ pins 0 ? Regards Marcello

marcello_poli: Could you indicate where i'd be able to find an example or could you post an example of code to enable Pin Change interrupts on Arduino Mega 2560 (ATmega2560) on PORTJ pins 0 ?

The second page of the ATmega2560 datasheet is a pin configuration diagram for the 640/1280/2560. You can see there that pin 63 is labeled "PJ0 (RXD3/PCINT9)". Search for "PCINT9" in the datasheet and you will find the interrupt enable for that pin is in PCMSK1, bit 1. The bit that enables interrupts from the PCMSK1 register is PCIE1 in the PCICR. The interrupt goes to the PCINT1 vector (#11).

Hello Johnwasser, thanks to your indications, bit state change interrupt on pin15 of Arduino Mega2560, goes. Regards Marcello

Hello Johnwasser, bit state change interrupt on pin15 of Arduino Mega2560, now does not run.
I cannot to understand what is happened. Perhaps the Mega Board has been damaged.
I append the source code, two weeks ago it was ok.
Where can I find (on the ATmega2560 datasheet) the interrupt for “PJ0 (RXD3/PCINT9)” goes to the PCINT1 vector (#11)?
Thanks
Regards
Marcello

#define inter_Mega_14 14
#define inter_Mega_15 15//pin 63 ATmega2560 PJ0 PCINT9
#define inter_Mega_A15 A15//pin 82 ATmega2560 PK7 PCINT23, PCIE2 pag97 NON Funziona
#define inter_Mega_53 53//pin 19 ATmega2560 PB0 PCINT0 PCMSK0 pag117, pag.81 PCIE0
#define inter_Mega_52 52//pin 19 ATmega2560 PB0 PCINT0 PCMSK0 pag117, pag.81 PCIE0
// -------------------------- Gestione Interrupts ------------------------------------>
void InitialiseIO(){
// --------- Finecorsa-------

  pinMode(inter_Mega_14, INPUT_PULLUP); // 
  digitalWrite(inter_Mega_14, HIGH); // Configure internal pull-up resistor

  pinMode(inter_Mega_15, INPUT_PULLUP); // 
  digitalWrite(inter_Mega_15, HIGH); // Configure internal pull-up resistor

  pinMode(inter_Mega_A15, INPUT_PULLUP); // 
  digitalWrite(inter_Mega_A15, HIGH); // Configure internal pull-up resistor

  pinMode(inter_Mega_53, INPUT_PULLUP); // 
  digitalWrite(inter_Mega_53, HIGH); // Configure internal pull-up resistor

  pinMode(inter_Mega_52, INPUT_PULLUP); // 
  digitalWrite(inter_Mega_52, HIGH); // Configure internal pull-up resistor

}
void InitialiseInterrupt(){
  cli(); // switch interrupts off while messing with their settings

  //----------------- Pin 15 digitale -------------------
  
  PCICR = (1<<PCIE1);//pin15
//  EIMSK |= (1<<PCIE1);//pin15
//  PCMSK1 = (1<<PCINT1);//pag.116
  PCMSK1 |= (1<<PCINT9);//pag.116

  //----------------- Pin 15 digitale -------------------
  
  PCICR |= (1<<PCIE1);//pin15
  PCMSK1 |= (1<<PCINT10);//pag.116

  //----------------- Pin 53 digitale -------------------
 
  PCICR |= (1<<PCIE0);//pag. 81
  PCMSK0 = (1<<PCINT0);//PCMSK0 pag117

  //----------------- Pin 52 digitale -------------------
  PCICR |= (1<<PCIE1);//pag. 79
  PCMSK0 |= (1<<PCINT1);//PCMSK0 pag117


 //----------------- Pin 15 Analogico -------------------
  PCICR = (1<<PCIE2);//tabella pag 414 Datasheet ATmega 2560+ pag.97
  PCMSK2 |= (1<<PCINT23);//PCMSK" Tab. pag. 414 e pag.116

  MCUCR = (1<<ISC00) | (1<<ISC01);//fondamentale 
  /*  MCUCR = (1<<ISC0#) | (1<<ISC0#);
  This line of code tells the chip which type of change triggers the interrupt. ISC0 is the value we are
  modifying. Inputting a 1 or a 0 at the # will determine the state. 0 0 triggers at any low level. 01 triggers
  at any change. 1 0 triggers at a falling edge. 1 1 triggers at a rising edge.
  */
  sei(); // turn interrupts back on
}




ISR(PCINT1_vect) {
  //cli(); // switch interrupts off while messing with their settings
  

  if ((digitalRead(inter_Mega_15)==LOW)  )
  {
   
    Serial.print(F("Pin 15="));Serial.println("0");
  }  
  else
  {
    Serial.print(F("Pin 15="));Serial.println("1");

  }  


  if ((digitalRead(inter_Mega_14)==LOW)  )
  {
   
    Serial.print(F("Pin 14="));Serial.println("0");
  }  
  else
  {
    Serial.print(F("Pin 14="));Serial.println("1");

  }  

  if ((digitalRead(inter_Mega_52)==LOW)  )
  {
   
    Serial.print(F("Pin 52="));Serial.println("0");
  }  
  else
  {
    Serial.print(F("Pin 52="));Serial.println("1");
  }  

//  sei(); // turn interrupts back on
  delayMicroseconds(1000); 
 
}


ISR(PCINT0_vect) {
  //cli(); // switch interrupts off while messing with their settings
  

  if ((digitalRead(inter_Mega_53)==LOW)  )
  {
   
    Serial.print(F("Pin 53="));Serial.println("0");
  }  
  else
  {
    Serial.print(F("Pin 53="));Serial.println("1");
  }  

//  sei(); // turn interrupts back on
  delayMicroseconds(1000); 
 
}


ISR(PCINT2_vect) {
  //cli(); // switch interrupts off while messing with their settings
  

  if ((digitalRead(inter_Mega_A15)==LOW)  )
  {
   
    Serial.print(F("Pin A15="));Serial.println("0");
  }  
  else
  {
    Serial.print(F("Pin A15="));Serial.println("1");
  }  

//  sei(); // turn interrupts back on
  delayMicroseconds(1000); 
 
}