'crash' when using pin change interrupts
Your onPinChange() function is called with interrupts disabled.

For you what it means is this function should:


last as short as possible (because NO interrupts are handled during its execution, that includes timers that are used by several Arduino core libraries)
not use Serial functions as these functions are slow and sometimes wait on interrupts (that could thus mean wait forever)


You can read further advice about these so-called Interrupt Service Routines (ISR) here and there.

If you want to trace all calls to onPinChange() then you will have to use some kind of circular buffer as a global volatile variable, which will be written into by onPinChange() and read from by loop().

Accessing that buffer from loop() should be protected against concurrent write by ISR.

Here is sample code I have just written (disclaimer, I have not checked that it compiles but I think it should work correctly) that uses such a circular buffer as described above, and ensures all shared variables accesses are protected against concurrent write by ISR:

#include &lt;PciManager.h&gt;
#include &lt;PciListenerImp.h&gt;

// Structures and function to manage circular buffer of changes
struct Change {
    int i;
    byte kind;
};

// We allow max SIZE changes in the buffer; if onPinChange() is called more often
// than loop(), then at one time the buffer will be overwritten.
const int SIZE = 100;
volatile Change changes[SIZE];
volatile int start = 0;
volatile int end = 0;

// Get the next change recorded by onPinChange()
Change* nextChange() {
    static Change change;
    Change* result = 0;
    // Disable interrupts as we are accessing variables modified by onPinChange
    cli();
    if (start != end) {
        change = changes[start];
        start = (start + 1) % SIZE;
        result = &amp;change;
    }
    // Re-enable interrupts before leaving the function
    sei();
    return result;
}

#define INPUT_PIN 3

PciListenerImp listener(INPUT_PIN, onPinChange);

// No change necessary in setup()
void setup() {
    Serial.begin(9600);
    PciManager.registerListener(INPUT_PIN, &amp;listener);
    Serial.println(Ready.);
}

void loop() {
    // Get the next change recorded by onPinChange (if any)
    Change* change = nextChange();
    if (change != 0) {
        // One change occurred since last time, trace it to Serial
        Serial.print("pci : ");
        Serial.print(change-&gt;i);
        Serial.print(" : ");
        Serial.println(change-&gt;kind);
    }
}

void onPinChange(byte changeKind) {
    // i does not have to be visible outside this function
    static int i = 0;
    i++;
    // Write information to the end of the circular buffer
    Change&amp; change = changes[end];
    change.i = i;
    change.kind = changeKind;
    // Prepare for the next call (write to the next item of the buffer)
    end = (end + 1) % SIZE;
}