Go Down

Topic: PinChangeInt library- To attach interrupts to multiple Arduino (Uno/Mega) pins (Read 24577 times) previous topic - next topic

GreyGnome

After some time, I have updated the library. There is a significant fix submitted by jrhelbert which makes the two Port J pins work properly with the Mega. See http://code.google.com/p/arduino-pinchangeint/.

Downloads available at https://bintray.com/greygnome/generic/PinChangeInt/view

Bleeding edge source available at https://github.com/GreyGnome/PinChangeInt

GreyGnome

Note: I don't have a Mega, so I didn't test ports J and K. If you use it, please let me know if it works. Thanks.

Petertje

Maybe somebody can help me?
I have this code, it is used to read a rotary encoder with an Arduino Uno. I want to make this work on an Arduino Mega.


Code: [Select]
  PORTC |= _BV(PORTC0) | _BV(PORTC1) | _BV(PORTC2) | _BV(PORTC3);   // enable pullup for pins
  PCMSK1 = _BV(PCINT8) | _BV(PCINT9) | _BV(PCINT10) | _BV(PCINT11); // enable button pin change interrupt A0 A1 A2 A3
  PCICR = _BV(PCIE1);
     

I can not find any help about converting this to a working Mega sketch. Can you help me?

GreyGnome

First you have to study the Mega pinout and figure out which pins and ports are available to you. Have you done this?

It looks like you have two rotary encoders (4 pins total). Is that correct?

I tried to use this lib, but sadly doesn't work as expected, so moved to http://www.geertlangereis.nl/Electronics/Pin_Change_Interrupts/PinChange_en.html . It works fine and I got all Analog pins on my Mega 2560 working as interrupt. but there I got other problem.... I lost Serial1, Serial2, Serial3.
None other than Serial0 Serial3 works with PCINT1 to PCINT23, with the ATMEL datasheet for 2560 it has stated that Serial3 (ATMEL's RXD3/TXD3) are on  PCINT9 and PCINT10 , so there are chances that Serial3 wont work with manipulated PCICR setting. Yet we have 2 other Serial Ports (Serial1 and Serial2) which haven't specified on any PCINT pins.
Please guide me about this.
This is where I Initialise Interrupts
Code: [Select]
[code]void InitialiseInterrupt(){
 cli(); // switch interrupts off while messing with their settings  

 PCICR =0x06;          // Enable PCIE2 and PCIE1
 PCMSK1 = 0b11111111; // Enabling A0 to A7 pins on Mega 2560 (PCINT23:16)
 PCMSK2 = 0b11111111; // Enabling A8 to A15 pins on Mega 2560(PCINT15:8)
 sei(); // turn interrupts back on
}


also as per the ATMEL's pdf you dont have any PCINT on ADC0...ADC7 pins. yet those are working


the full code is
Code: [Select]
#include <TimerOne.h>
#include <Encoder.h>
#include <SPI.h>

Encoder xenc(18,19);
int iPin[] = {54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69}; //{"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","A10","A11","A12","A13","A14","A15"};
int iLast[16];
void setup()
{
 SPI.begin();
 Serial.begin(9600);
 Serial.println("Boe");
 Serial2.begin(9600);
 InitialiseIO();
 InitialiseInterrupt();
Timer1.initialize(100000);
Timer1.attachInterrupt(Timer1_tick);
}
void Timer1_tick(){
 float z = xenc.read();
digitalWrite(13,!digitalRead(13));
SPI.transfer(z);
}
void serialEvent(){
Serial2.print("A");
}
void loop() {
 /* Nothing to do: the program jumps automatically to Interrupt Service Routine "blink"
  in case of a hardware interrupt  */
}  

void InitialiseIO(){
 pinMode(13,OUTPUT);
 digitalWrite(13,LOW);
 pinMode(A0, INPUT);   // Pin A0 is input to which a switch is connected
 digitalWrite(A0, HIGH);   // Configure internal pull-up resistor
 pinMode(A1, INPUT);   // Pin A1 is input to which a switch is connected
 digitalWrite(A1, HIGH);   // Configure internal pull-up resistor
 pinMode(A2, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A2, HIGH);   // Configure internal pull-up resistor
  pinMode(A3, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A3, HIGH);   // Configure internal pull-up resistor
  pinMode(A4, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A4, HIGH);   // Configure internal pull-up resistor
  pinMode(A5, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A5, HIGH);   // Configure internal pull-up resistor
  pinMode(A6, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A6, HIGH);   // Configure internal pull-up resistor
  pinMode(A7, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A7, HIGH);   // Configure internal pull-up resistor
 pinMode(A8, INPUT);   // Pin A0 is input to which a switch is connected
 digitalWrite(A8, HIGH);   // Configure internal pull-up resistor
 pinMode(A9, INPUT);   // Pin A1 is input to which a switch is connected
 digitalWrite(A9, HIGH);   // Configure internal pull-up resistor
 pinMode(A10, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A10, HIGH);   // Configure internal pull-up resistor
  pinMode(A11, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A11, HIGH);   // Configure internal pull-up resistor
  pinMode(A12, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A12, HIGH);   // Configure internal pull-up resistor
  pinMode(A13, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A13, HIGH);   // Configure internal pull-up resistor
  pinMode(A14, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A14, HIGH);   // Configure internal pull-up resistor
  pinMode(A15, INPUT);   // Pin A2 is input to which a switch is connected
 digitalWrite(A15, HIGH);   // Configure internal pull-up resistor
 
}

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

 PCICR =0x06;          // Enable PCINT1 interrupt
 PCMSK1 = 0b11111111;
 PCMSK2 = 0b11111111;
 sei(); // turn interrupts back on
}
/*
ISR(PCINT1_vect) {    // Interrupt service routine. Every single PCINT8..14 (=ADC0..5) change
           // will generate an interrupt: but this will always be the same interrupt routine
 if (digitalRead(A0)==0)  Serial.println("A0");
 if (digitalRead(A1)==0)  Serial.println("A1");
 if (digitalRead(A2)==0)  Serial.println("A2");
  if (digitalRead(A3)==0)  Serial.println("A3");
 if (digitalRead(A4)==0)  Serial.println("A4");
 if (digitalRead(A5)==0)  Serial.println("A5");
  if (digitalRead(A6)==0)  Serial.println("A6");
 if (digitalRead(A7)==0)  Serial.println("A7");

}
ISR(PCINT2_vect) {    // Interrupt service routine. Every single PCINT8..14 (=ADC0..5) change
           // will generate an interrupt: but this will always be the same interrupt routine
 if (digitalRead(A8)==0)  Serial.println("A8");
 if (digitalRead(A9)==0)  Serial.println("A9");
 if (digitalRead(A10)==0)  Serial.println("A10");
  if (digitalRead(A11)==0)  Serial.println("A11");
 if (digitalRead(A12)==0)  Serial.println("A12");
 if (digitalRead(A13)==0)  Serial.println("A13");
  if (digitalRead(A14)==0)  Serial.println("A14");
 if (digitalRead(A15)==0)  Serial.println("A15");

}*/
ISR(PCINT1_vect) {
 for (int q = 0; q <= 7; q++) {
   int u = digitalRead(iPin[q]);
   String OP = "IP";

   if (iLast[q] != u) {
     OP += q;
     OP += u;
     OP += "!";
     Serial.print(OP);
   }
   iLast[q] = u;
 }

}
ISR(PCINT2_vect) {
 for (int q = 8; q <= 15; q++) {
   int u = digitalRead(iPin[q]);
   String OP = "IP";

   if (iLast[q] != u) {
     OP += q;
     OP += u;
     OP += "!";
     Serial.print(OP);
   }
   iLast[q] = u;
 }

}

[/code]

GreyGnome

Don't do a Serial.print() inside an ISR. If it does work, consider yourself lucky and stop doing it as soon as possible because things are (were?) problematic when printing from an ISR (but supposedly fixed in IDE 1.5; see https://github.com/matthijskooijman/Arduino/commit/eb86af7b67407e198bac24ecd16a8c1669e3efaa ).

Regarding the rest of your question, you stated that you tried the PinChangeInt library and it didn't work for you. This thread is about the PinChangeInt library. The code you speak of was written by someone else so I don't think this is the appropriate place for this question, but perhaps someone will lend you the time and help you out.

GreyGnome

Announcing the release of version 2.40-rc2 for the Arduino PinChangeInt library.

See http://code.google.com/p/arduino-pinchangeint/.
Downloads available at https://bintray.com/greygnome/generic/PinChangeInt/view
Bleeding edge source available at https://github.com/GreyGnome/PinChangeInt

See the RELEASE_NOTES for detailed information. In short, some of the changes in recent history include:

The library is now licensed under the Apache 2.0 License. I wanted to free the code up for any use, and Chris J. Kiick and Lex Talionis graciously agreed.

Cleaned up some code, and added the following #define's for ease-of-use:

#define        detachPinChangeInterrupt(pin)
#define        attachPinChangeInterrupt(pin,userFunc,mode)
#define        getInterruptedPin()



Cleaned up the README for better display on GitHub.

Version 2.40-rc1 Fri Nov  7 07:26:36 CST 2014
I'm going to the "-rcX" numbering format like the Linux kernel. That is, 2.40-rc1 is the first "release
candidate" on the way to a stable 2.40 release.

Beginning with this release, only Arduino >= 1.00 is supported. The older Arduinos are left to the
dustbin of history...

I have BIG news: Jan Baeyens ("jantje") has graciously DONATED an Arduino Mega ADK to the PinChangeInt project!!! Wow, thanks Jan! This makes the 2560-based Arduino Mega a first class supported platform- I will be able to test it and verify that it works. I have done so in this release.

To that end, The PinChangeIntExample has been modified to work properly with the Arduino Mega. Thanks, Jan!

Many thanks to JRHelbert for fixing the PJ0 and PJ1 interrupt PCMSK1 issue on the Arduino Mega! This was a great coup, in my humble opinion.  Mega interrupt users are indebted to you, jrhelbert.

tomega3

Great Library,
Any chance to add support in it for the Atmel 1284p micro controller?

I have a board with a 1284p (moteino mega) that I can test it with.

Thanks

GreyGnome

Great Library,
Any chance to add support in it for the Atmel 1284p micro controller?

I have a board with a 1284p (moteino mega) that I can test it with.

Thanks
It would probably be pretty easy, since the library already has Sanguino support. Could you take the following code and add/modify the 1284 to the #define and see if it works just like that?

#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)

just change it to

#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284__) || (defined __AVR_ATmega1284P__)

(that final "P" may need to be a "p". Could you check both?)

Thanks.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy