Electronic – Arduino and Interrupts: Fast way to get pin values

arduinocinterrupts

I use an Arduino Uno and already set it up to work with interrupts on digital pins 2, 3, 4 and 5 according to an explanation1 I found.

void setup() contains the following code to setup the interrupts.

  //Endable Interrupts for PCIE2 Arduino Pins (D0-7)
  PCICR |= (1<<PCIE2);

  //Setup pins 2,3,4,5
  PCMSK2 |= (1<<PCINT18);
  PCMSK2 |= (1<<PCINT19);
  PCMSK2 |= (1<<PCINT20);
  PCMSK2 |= (1<<PCINT21);

  //Trigger Interrupt on rising edge
  MCUCR = (1<<ISC01) | (1<<ISC01);

And now, the ISR( PCINT2_vect ) function is triggered on every interrupt. That works like a charm. My question is, what is the best/fastest way to find out, which pin was triggered?

I found something in Re: Is better to use ISR(PCINT2_vect) or attachInterrupt on pins 2, 3?, but I do not understand the code and it does not work out of the box. But it looks impressive…

What is the solution?

[2] http://arduino.cc/forum/index.php/topic,72496.15.html#lastPost

Edit:

At the moment, I am reading the pin state from the from the input pin register:

  if (PIND & 0b00000100)
    Serial.println( "PIN 2" );
  if (PIND & 0b00001000)
    Serial.println( "PIN 3" );
  if (PIND & 0b00010000)
    Serial.println( "PIN 4" );
  if (PIND & 0b00100000)
    Serial.println( "PIN 5" );

In the end, I want to count the interrupts on the pins.
But how can I assure, that there are no counted twice?

Best Answer

I have a first solution myself, but i could not test the reliability as the hardware is not finished jet.

First I added oldPins and tickCount as global variables:

static byte oldPins = 0;
volatile unsigned int tickCount[4] = { 0, 0, 0, 0 };

And thats how I solved the ISR at the moment. Better solutions are more than welcome.

ISR( PCINT2_vect ) {
  //Read values from digital pins 2 to 7
  const byte actPins = PIND;
  //Match this values agaist the oldPins bitmask (XOR and AND for raising edge)
  const byte setPins = (oldPins ^ actPins) & actPins;

  if (setPins & 0b00000100)
    tickCount[0]++;
  if (setPins & 0b00001000)
    tickCount[1]++;
  if (setPins & 0b00010000)
    tickCount[2]++;
  if (setPins & 0b00100000)
    tickCount[3]++;

  oldPins = actPins;
}