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

migrated from stackoverflow.com Oct 1 '11 at 6:48

This question came from our site for professional and enthusiast programmers.

  • \$\begingroup\$ At electronics, more people have probably messed around with Arduinos and other electronic things. \$\endgroup\$ – Earlz Sep 28 '11 at 15:18
  • \$\begingroup\$ If you think, the question should be over there, flag it. I solved my login problems. \$\endgroup\$ – madc Sep 28 '11 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\$ – BlueRaja - Danny Pflughoeft Sep 30 '11 at 23:13
4
\$\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\$
  • 1
    \$\begingroup\$ If you are updating tickCount[] in an ISR, you should be declaring it with the 'volatile' type qualifier. \$\endgroup\$ – icarus74 Dec 22 '11 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 Dec 23 '11 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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