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\$ 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\$ 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\$ 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\$ 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.