Pages: [1]   Go Down
Author Topic: How to Enable the interrupts on pins D4, D12, A0-A5 on Arduino Mega 2560 board  (Read 1468 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8821
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

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

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.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


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 fix 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
Quote
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
Quote
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,
Quote
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.
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8821
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:
// -------------------------- 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
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8821
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8821
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
#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);
 
}
Logged

Pages: [1]   Go Up
Jump to: