Need a S-I-M-P-L-E example of using PinChangeInt or ooPinChangeInt

I need two interrupts on a Nano (interrupts on pins 2 and 3) to measure the duration of pulses from two wheels to get speed feedbacks for PID loops. I'm already using pin 3 for PWM to a motor drive and I am changing the PWM frequency on timers 1 and 2 (pins 3,9,10,11). So I need two software interrupts. I have been trying to understand PinChangeInt and ooPinChangeInt (what's the difference?) and I find it tough going. I don't know a class from a hole in the ground, let alone sub classes. Do I have to use different ports (D,B,C) for the two interrupt pins or can I use pins 4 and 5?

I have tried to understand the examples downloaded with the libraries and the Wiki but I am dumbfounded. Anyone know of a simple example with two software interrupts? I learn by copying and trying. Thanks for any help!

So what confuses you about the example here:

That is simple, but how would I add another interrupt pin? And what is pin 15? I don’t have a input 15. Can I use pins 4 and 5? Is this OK:

Copyright 2011 Lex.V.Talionis at gmail
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
    #include <PinChangeInt.h>
    #include <PinChangeIntConfig.h>
    #define PIN 4  // the pin we are interested in
    #define PIN2 5  // the pin we are interested in
    volatile byte burp=0;    // a counter to see how many times the pin has changed
    volatile byte burp2=0;    // a counter to see how many times the pin has changed
    byte cmd=0;     // a place to put our serial data
    void setup() {
      Serial.print("PinChangeInt test on pin ");
      Serial.print("PinChangeInt test on pin ");
      pinMode(PIN, INPUT);     //set the pin to input
      digitalWrite(PIN, HIGH); //use the internal pullup resistor
      pinMode(PIN2, INPUT);     //set the pin to input
      digitalWrite(PIN2, HIGH); //use the internal pullup resistor
      PCintPort::attachInterrupt(PIN, burpcount,RISING); // attach a PinChange Interrupt to our pin on the rising edge
      PCintPort::attachInterrupt(PIN2, burpcount2,RISING); // attach a PinChange Interrupt to our pin on the rising edge
    // (RISING, FALLING and CHANGE all work with this library)
    // and execute the function burpcount when that pin changes
    void loop() {;  
      if (cmd=='p')
        Serial.println(burp, DEC);
        Serial.println(burp2, DEC);
    void burpcount()
    void burpcount2()

pin 15 on the Uno is the same as A1.

The example shows attachInterrupt being called for two pins, check with the library sources but I suspect you just call it for any and all pins you want, and the library handles dispatching to your handlers - that would be the obvious way to do it.

The original example was for only one pin - 15. I modified it above for two pins - 4 and 5. Is that OK? Or do the pins have to be on different vectors (whatever they are) or ports?

What Arduino are you using, not all of them support pin change int on every pin.

See here for an example using multiple pin change ints and the last link for a guide to which pins can be used on which Arduinos -

Background - because of the way the class is written, you dont need to know that its a class, just use a slightly different way of calling the functions -

Example usage

Usable pins

Duane B

Like others I#ve some problems understanding and using PinChangeInt. On my Mega2560 I need three interrupt pins. In the past I tested with two external Pins and had success.But now externals can't be used, because of usage by shields.

I want to use PintChangedInt with the analogue pins A1,A2 and A3 for interrupts with light barriers, which change when reflecting from HIGH to LOW. Is the follwoing code snippet correct for this?

#define Pin1 15
#define Pin2 16
#define Pin3 17
pinMode(Pin1, INPUT);     //set the pin to input
digitalWrite(Pin1, HIGH); //use the internal pullup resistor
pinMode(Pin2, INPUT);    
digitalWrite(Pin2, HIGH); 
pinMode(Pin3, INPUT);    
digitalWrite(Pin3, HIGH);
PCintPort::attachInterrupt(Pin1, ISR_for_Pin1,FALLING); // attach 
PCintPort::attachInterrupt(Pin2, ISR_for_Pin2,FALLING); // attach 
PCintPort::attachInterrupt(Pin3, ISR_for_Pin3,FALLING); // attach

Dear friends , this is my first contribute to the community.
I got to say this , Pin change is very simple that you dont even need to use a library for.
I learned form Qeewiki , all pin on atmega328 can be interrupt.
What is Pin Chang Int different from pin 2 and 3 interrupt?

  1. It is grouped , meaning that when ever one pin of a group has change state , you must check which pin has change.
  2. It is Pin Change , unlike pin 2 and 3 which ony interrupt on RISE, fall … so you need to check the state of that pin to know if it was a rise or a fall
    How to use?
  3. Set your interrupt pin to be INPUT or INPUT_PULLUP
  4. There are 3 group , check the pinout , let say i want to interrupt on pin 4, 5 and A3.
    So I check the register map, 4 is PCINT20 belong to PCMSK2 , 5 is PCINT21 (PCMSK2) and A3 is PCINT11 (PCMSK1);
  5. so I use PCMSK1 and PCMSK2 right ? then I tell the UNO that I use this two by setting the PCICR
PCICR |=  ( (1 << PCIE1) | (1 << PCIE2);

this mean , hey , enable interrupt on group 1 and 2.
4. Now , i define each group , which pin will trigger group interrupt
I use PCINT20 and PCINT21 (pin 4 and 5 ) which belong to PCMSK2 so

PCMSK2 |=( (1 << PCINT20) | (1 << PCINT21) ;

The same for pin A3

PCMSK1 |= (1 << PCINT11) ;
  1. So i use PCINT1 and PCINT2 right , then I will set the ISR,
ISR (PCINT1_vect)
{//THIS WILL BE CALL WHEN A3 change state
//if you read the pin right now and it is HIGH then it was a RISE, else , It was a FALL
ISR (PCINT2_vect)
{//THIS WILL BE CALL WHEN EITHER PIN 4 or 5 change state
   //THIS IS TRICKIER BECAUSE YOU MUST KNOW Which pin change state, so you need a history to compare
uint8_t changedbits;

    changedbits = PINB ^ portbhistory; // PINB if PCINT2, PIND if PCINT0, PINC for PCINT1
    portbhistory = PINB;// CHANGE HERE ALSO

    //DONT USE DIGITAL READ HERE , INSTEAD use port manipulation
//If you dont know why this is PINB0, check picture below
    if(changedbits & (1 << PINB0))
        /* PCINT0 changed */
    if(changedbits & (1 << PINB1))
        /* PCINT1 changed */

    if(changedbits & (1 << PINB2))
        /* PCINT2 changed */

All thanks to the Q guys , you are rock.

let say PINB0 , it is PB0 , which is pin 8
somehow if the picture dont show up , go to the source.

Thanks for stepping into the deep end. |500x204

|500x202 .