Pages: [1]   Go Down
Author Topic: Changing Interrupt Pins  (Read 1931 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey everyone, after hours of searching I am still very confused as to how to attach interrupts to pins. I am trying to make an interrupt on DP8; this is the part of my code I am having trouble with:
Code:
#include <avr/interrupt.h>
#include <avr/io.h>

int recpin = 8;
int ledPin3 = 11;

void setup() {
  pinMode(ledPin3, OUTPUT);
  pinMode(recpin, INPUT);
  PCICR |= (1 << PCIE0);
  PCMSK0 |= (1 << PCINT0);
  attachInterrupt(8, ISR(PCINT0_vect), CHANGE);
  interrupts();
}

void loop(){
some other functions
}

ISR(PCINT0_vect){
    digitalWrite(ledPin3, HIGH);
  }
I'm not getting the led to turn on when the button on DP8 changes states.
Could anyone point me in the proper direction? I would be most appreciative.
« Last Edit: November 20, 2010, 06:33:25 pm by vex » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I realize that, so I'm trying to add additional pins using Atmega commands, in the same way that the Arduino Mega gains additional interrupts. As I understand it, all IO pins on Atmega are covered by Pin Change Interrupts.
« Last Edit: November 20, 2010, 06:36:31 pm by vex » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.arduino.cc/playground/Main/PcInt
http://www.arduino.cc/playground/Main/PinChangeInt
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1259918394/15
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 988
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I believe the problem is this: there are two types of pin related interrupts, and attachInterrupt() only handles one kind.  The wrong one, for your application.

The kind that attachInterrupt() handles is the External Interrupt Request, which is bound to the INT0 and INT1 pins.

The kind you seem to be requiring is a Pin Change interrupt, a different beast.  Any pin can be configured to generate this kind of interrupt; you set PCICR, PCIFR, and the appropriate PCMSKn.

Searching on pin-change interrupt here in the forum may be helpful as will be a look at the data sheet for the '328 at Section 12.2/page 71 from this url:

      http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf

Best,

-br
http://bitlash.net
http://entropymouse.com

edit: great links vex!

« Last Edit: November 20, 2010, 06:52:13 pm by billroy » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, that makes sence. The closest replacement I can find for attachInterrupt() is in the third link I posted, where this code is claimed to work for pin 5:
Code:
ISR(PCINT2_vect)
{
  if (PIND & B00100000) // evaluates to TRUE when PortD bit #5 (Arduino digital pin #5) is HIGH
  {
    counter1++;
  }
}

Unfortunately, I have no idea what the binary part means as it seems to correspond to pin #4.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Your example is NOT an "interrupt". It is simply an example of "polling". i.e. just going out at some specified time and saying "does this equal that?" Very much different than an interrupt.  They could just as easily have said: if digitalRead(5) Then counter1++
In the context of the persons code, it is. "ISD()" is apparently an AVR interrupt command, run on  "PCINT2_vect", the Atmega equivalent of pin 5, in the attached libraries.
Quote
Your other examples show extentions to the Arduino base functionality.  Apparently there are features in the Atmel chip which the Arduino basic language doesn't implement. So they have extentions that you can use to get to those other features. But you must use the special code and syntax. You can't simply use attachInterrupt() as it only supports the pins defined by the definition page.
All of them do. Interrupt pins aren't "hard-wired", like you said, into the Atmega; that's how the Arduino Mega can use the same chip and have more native interrupts. And yes, I understand that I can't use attachInterrupt(), I have to use some variation of ISR(). That's what I'm asking about.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But your example clearly shows "attachInterrupt(8, ISR(PCINT0_vect), CHANGE);"  and the documentation clearly doesn't support that.
Sorry, I meant that I "understand that" after reading billroy's post.
Logged

Las Vegas, NV
Offline Offline
God Member
*****
Karma: 0
Posts: 507
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you want some sample code that uses pin change interrupts on arbitrary, specifiable pins, take a look at the OrangutanPulseIn code from the Pololu AVR Library.  Once you download the library, you can find the source code in the directory:

libpololu-avr/src/OrangutanPulseIn

The library code is documented in the command reference; this might help you better understand what it's doing.

I hope you find this more helpful than confusing!

- Ben
Logged


Las Vegas, NV
Offline Offline
God Member
*****
Karma: 0
Posts: 507
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Unfortunately, I have no idea what the binary part means as it seems to correspond to pin #4.
I don't understand you're confusion here.  The statement is checking to see if the fifth bit of the digital input register for port D (PIND) is set:

PIND & B00100000

Why are you interpreting this as pin 4?

One key thing to note about pin change interrupts is that there is only one ISR per port, so if you have configured multiple pins from the same port to generate pin change interrupts, you need to do some extra computation in the ISR to figure out which pin actually changed.  External interrupts are nicer because you automatically know which pin caused the interrupt and what edge was detected.

- Ben
Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey, that Pololu thing really helps, thanks!

And lol, I thought that since 00100000 in binary equaled 20 it must refer to Atmel 20 -> DP4.

Thanks a bunch!
Logged

Las Vegas, NV
Offline Offline
God Member
*****
Karma: 0
Posts: 507
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hah, that is a pretty convoluted way to get to pin 4!  Also, 00100000 is 20 in hex (it's actually 32 in decimal) smiley

- Ben
Logged


Pages: [1]   Go Up
Jump to: