12
\$\begingroup\$

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?

\$\endgroup\$
3
  • \$\begingroup\$ At electronics, more people have probably messed around with Arduinos and other electronic things. \$\endgroup\$
    – Earlz
    Commented Sep 28, 2011 at 15:18
  • \$\begingroup\$ If you think, the question should be over there, flag it. I solved my login problems. \$\endgroup\$
    – madc
    Commented Sep 28, 2011 at 15:24
  • 3
    \$\begingroup\$ @Earlz: This is a programming question, so it's on-topic. The fact that it's for a hobbyist platform is irrelevant; see the hundreds of other arduino questions on stackoverflow for reference. \$\endgroup\$ Commented Sep 30, 2011 at 23:13

1 Answer 1

5
\$\begingroup\$

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;
}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ If you are updating tickCount[] in an ISR, you should be declaring it with the 'volatile' type qualifier. \$\endgroup\$
    – bdutta74
    Commented Dec 22, 2011 at 6:52
  • \$\begingroup\$ I updated the code inside the answer. For more information see the arduino documentation: arduino.cc/en/Reference/Volatile \$\endgroup\$
    – madc
    Commented Dec 23, 2011 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.