digitalPinToInterrupt() for pins_arduino.h

3,453 views
Skip to first unread message

Paul Stoffregen

unread,
Sep 26, 2013, 7:09:26 AM9/26/13
to Arduino Developers
I'd like to propose another macro in pins_arduino.h, to allow libraries
to translate digital pins to the interrupt numbers needed for
attachInterrupt(), and detect if a user-specified pin doesn't support
attachInterrupt().

It might look something like this?

// Arduino Uno
#define digitalPinToInterrupt(p) ( (p) == 2 ? 0 : ((p) == 3 ? 1 : -1) )

// Arduino Mega
#define digitalPinToInterrupt(p) ( (p) == 2 ? 0 : ((p) == 3 ? 1 :
((p) >= 18 && (p) <= 21 ? 23 - (p) : -1)) )

// Arduino Leonardo & Yun
#define digitalPinToInterrupt(p) ( (p) == 0 ? 2 : ((p) == 1 ? 3 :
((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : -1)))) )

// Arduino Due
#define digitalPinToInterrupt(p) ( (p) < NUM_DIGITAL_PINS ? (p) : -1 )

At least 4 libraries currently have long #ifdef chains for this purpose:
Encoder, PS2Keyboard, Adafruit_VS1053 and Adafruit_CC3000. The GSM3
library also has some hard-coded pin to interrupt stuff. I do not
believe any of these libraries fully supports all official Arduino boards.

Peter Feerick

unread,
Sep 26, 2013, 7:37:58 AM9/26/13
to Arduino Developers
As a recent user of an ARM based Arduino clone (DigiX), I like this idea, as I had issues with how the attachInterrupts function changed behaviour from AVR to ARM (ie. interrupt on AVR and pin on ARM). I ended up putting conditional compilation statements for some example code to work for both arch.

Pete
> --
> You received this message because you are subscribed to the Google Groups "Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

Rob Tillaart

unread,
Sep 26, 2013, 9:21:17 AM9/26/13
to Peter Feerick, Arduino Developers
reverse engineering the requirement from the implementation

We should implement:   connectInterrupt( pinnr, func() );

This function would handle all the mapping (as Paul suggested) internally. The advantage is that the user does not need to know /use the macro's directly. the code would be 

connectInterrupt(2, func, mode);

iso

uint8_t IRQ = digitalPinToInterrupt(2);
attachInterrupt(IRQ, func, mode);

It would be nice if connectInterrupt()  would return the previous connected function pointer or NULL if none. 
That would allow some neat tricks changing the IRQ function and back very fast.

Implementation something like

voidFuncPtr connectInterrupt(uint8_t pin, void (*userFunc)(void), int mode)
{
  uint8_t IRQ = digitalPinToInterrupt(pin);  // Paul's Macro
  if (IRQ >= 0)
  {
    voidFuncPtr prevFunc = intFunc[IRQ];
    attachInterrupt(IRQ, userFunc, mode);
    return prevFunc;  // NULL or func ptr?
  }
  else return IRQ;  // typically -1;
}

A simpler version: 

bool connectInterrupt(uint8_t pin, void (*userFunc)(void), int mode)
{
  uint8_t IRQ = digitalPinToInterrupt(pin);  // Paul's Macro
  if (IRQ >= 0)
  {
    voidFuncPtr prevFunc = intFunc[IRQ];
    attachInterrupt(IRQ, userFunc, mode);
    return true;
  }
  return false;
}

my 2 cents;
Rob

Matthijs Kooijman

unread,
Sep 26, 2013, 9:34:03 AM9/26/13
to Rob Tillaart, Peter Feerick, Arduino Developers
> reverse engineering the requirement from the implementation
>
> We should implement: connectInterrupt( pinnr, func() );
Sounds like a plan, I always wondered about the interface for
attachInterrupt.

However, you've chosen a name that's pretty much interchangeable with
the existing attachInterrupt, which would lead to confusion I expect...
How about using attachInterruptToPin or something like that?

> It would be nice if connectInterrupt() would return the previous connected
> function pointer or NULL if none.
It seems that returning a pointer or NULL is not compatible with
returning -1 on error as your example implementation shows.

I do think returning an error is important here, since there's usually
only a few pins that actually work. This is of course the downside of a
function like this: People will see the function, assume they can just
change the pin number and won't check the return value or read the
documentation...

While we're adding an interface like this, might it make sense to also
include support for using pin change interrupts (which work for all
pins) instead of just the actual pin interrupts? With some extra support
code, the pin change interrupts should be able to support CHANGE, RISING
and FALLING (but not LOW, though that could be emulated by polling in
the loop or something ugly like that...).

While we're here, perhaps registering multiple handlers for a single IRQ
and some way to disable / enable specific pin interrupts might also make
sense?


However, apart from all of the above, a good first step is to implement
Paul's suggestion, which we will be needing anyway (and shouldn't be
delayed by other crazy ideas)...

Gr.

Matthijs
signature.asc

Rob Tillaart

unread,
Sep 26, 2013, 9:46:37 AM9/26/13
to Peter Feerick, Arduino Developers
simpler version tested - works like a charm!
- patched Arduino.h (prototype function)
- patched Winterrupts.c (implementation connectInterrupt + macro for UNO )  (changed type to boolean)

test-sketch return true and false as expected.

volatile uint8_t counter=0, prevCounter=0;

void setup()
{
  Serial.begin(115200);

  bool b = connectInterrupt(2, f, CHANGE);
  Serial.println(b);

  b = connectInterrupt(4, f, CHANGE);  // does not exist on UNO
  Serial.println(b);

  delay(10000);
}

void loop()
{
  if (counter != prevCounter)
  {
    Serial.println(counter);
    prevCounter = counter;
  }
}

void f()
{
  counter++;
}

Rob Tillaart

unread,
Sep 26, 2013, 9:49:57 AM9/26/13
to Peter Feerick, Arduino Developers
attachInterruptToPin  - is indeed a better name. 

There allready exist a nice library for pinINterrupts, have no time to look it up but I recall helping optimizing its performance (quite) a bit.

Good idea to get the macro''s in for version 1.0.6

Rob

Victor Aprea

unread,
Sep 26, 2013, 10:58:04 AM9/26/13
to Rob Tillaart, Arduino Developers, Peter Feerick

Rob,

Small thing, IRQ should be int8_t rather than uint8_t for the error handling to work as intended. I also support Paul's macro as a very worthwhile addition to the core (developers) API.

Cheers,

Vic

David Mellis

unread,
Sep 26, 2013, 11:40:06 AM9/26/13
to Paul Stoffregen, Arduino Developers
Sounds like a good idea to me. Cristian?

Whether attachInterrupt() should have used pin numbers instead of interrupt numbers -- or whether we should provide a replacement or alternative that does -- seems like a trickier question. I don't like the idea of having two almost identical functions, except that one takes interrupt numbers and one takes pin numbers. If we did do something like that, I agree that we should name it accordingly (e.g. "attachInterruptToPin()") instead of simply giving it a different but similar name (like "connectInterrupt()").


--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.

Paul Stoffregen

unread,
Sep 26, 2013, 4:55:18 PM9/26/13
to David Mellis, Arduino Developers
A macro in pins_arduino.h would be best for 3rd parties using Arduino's AVR core library with only a "variant" header.  I personally don't use the variant feature, so it's not a big deal for me, but this might help others who use Arduino's core library for their boards.  It also ought to make future official Arduino boards easier, assuming they reuse the existing core libraries.

If attachInterruptToPin() is added to the API, perhaps it should use the macro from pins_arduino.h, so it'll work automatically on variants?
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.


Cristian Maglie

unread,
Sep 26, 2013, 7:17:55 PM9/26/13
to devel...@arduino.cc



> > Sounds like a good idea to me. Cristian?

I like it too, is someone going to do it?

> If attachInterruptToPin() is added to the API, perhaps it should use the
> macro from pins_arduino.h, so it'll work automatically on variants?

Yes I think.

I'm wondering also that once attachInterruptToPin() becomes part of the API,
then attachInterrupt() will have no more reason to exist except compatibility
for old sketches.

C
Cristian

Paul Stoffregen

unread,
Sep 26, 2013, 9:34:42 PM9/26/13
to devel...@arduino.cc
On 09/26/2013 04:17 PM, Cristian Maglie wrote:
> I like it too, is someone going to do it?

Like this?

Rob Tillaart

unread,
Sep 27, 2013, 4:35:38 AM9/27/13
to Cristian Maglie, Arduino Developers
I'm wondering also that once attachInterruptToPin() becomes part of the API, then attachInterrupt() will have no more reason to exist except compatibility for old sketches.

1) Compatibility; important
2) Easy implementation of attachInterruptToPin(); see proto below
3) Codesize: as attachInterruptToPin() makes sketch ~30 bytes larger  [quick 1 call test on UNO]


boolean attachInterruptToPin(uint8_t pin, void (*userFunc)(void), int mode)
{
  int IRQ = digitalPinToInterrupt(pin);
  if ( IRQ >= 0)
  {
    attachInterrupt(IRQ, userFunc, mode);
    return true;
  }
  return false;
}

boolean detachInterruptFromPin(uint8_t pin) 
{
  int IRQ = digitalPinToInterrupt(pin);
  if ( IRQ >= 0)
  {
    detachInterrupt(IRQ);
    return true;
  }
  return false;
}

the test >= 0 is needed as attachInterrupt expects an uint8_t, "throwing" in -1 results in a unwanted cast.

The functions could be made of the type void although bool adds value.







Matthijs Kooijman

unread,
Sep 27, 2013, 4:46:10 AM9/27/13
to Rob Tillaart, Cristian Maglie, Arduino Developers
Hi Rob,

> 2) Easy implementation of attachInterruptToPin(); see proto below
This alone is probably a reason to keep it, even if only internally.

> 3) Codesize: as attachInterruptToPin() makes sketch ~30 bytes larger
> [quick 1 call test on UNO]
I suspect this is partly because the "valid interrupt / pin" check
happens twice now. I expect that the extra size gets reduced if you make
attachInterrupt return a boolean too and in attachInterruptToPin just
call attachInterrupt without any checks and forward the return value.
Same for detach, of course.

> the test >= 0 is needed as attachInterrupt expects an uint8_t, "throwing"
> in -1 results in a unwanted cast.
This would need to be solved as well, but I guess that simply using 0xff
as "invalid interrupt / pin" instead of -1 would work just as fine?
That'll remove the need for using ints instead of uint8_t, which also
saves a byte (and the related code for handling 2 bytes).

> The functions could be made of the type void although bool adds value.
Agreed.

Gr.

Matthijs
signature.asc

Rob Tillaart

unread,
Sep 27, 2013, 5:12:41 AM9/27/13
to Rob Tillaart, Cristian Maglie, Arduino Developers
On Fri, Sep 27, 2013 at 10:46 AM, Matthijs Kooijman <matt...@stdin.nl> wrote:
Hi Rob,

> 2) Easy implementation of attachInterruptToPin(); see proto below
This alone is probably a reason to keep it, even if only internally.

> 3) Codesize: as attachInterruptToPin() makes sketch ~30 bytes larger
>  [quick 1 call test on UNO]
I suspect this is partly because the "valid interrupt / pin" check
happens twice now. I expect that the extra size gets reduced if you make
attachInterrupt return a boolean too and in attachInterruptToPin just
call attachInterrupt without any checks and forward the return value.
Same for detach, of course.
As long as you still allow calls to attachInterrupt(compatibility) the test should be done there too. 
A short test shows 6 bytes improvement (still 24 more) .

> the test >= 0 is needed as attachInterrupt expects an uint8_t, "throwing"
> in -1 results in a unwanted cast.
This would need to be solved as well, but I guess that simply using 0xff
as "invalid interrupt / pin" instead of -1 would work just as fine?
That'll remove the need for using ints instead of uint8_t, which also
saves a byte (and the related code for handling 2 bytes).
That will work as no board has 256 pins yet. Note the Due has interrupt on all pins,.
However keeping an error value distinct from possible valid values is a good design principle.



Matthijs Kooijman

unread,
Sep 27, 2013, 5:15:43 AM9/27/13
to Rob Tillaart, Cristian Maglie, Arduino Developers
Hey Rob,

> > I suspect this is partly because the "valid interrupt / pin" check
> > happens twice now. I expect that the extra size gets reduced if you make
> > attachInterrupt return a boolean too and in attachInterruptToPin just
> > call attachInterrupt without any checks and forward the return value.
> > Same for detach, of course.
>
> As long as you still allow calls to attachInterrupt(compatibility) the test
> should be done there too.
> A short test shows 6 bytes improvement (still 24 more) .
My suggestion was to only check in attachInterrupt and remove the check
in attachInterruptToPin, not the other way around?

Gr.

Matthijs
signature.asc

Rob Tillaart

unread,
Sep 27, 2013, 5:35:33 AM9/27/13
to Rob Tillaart, Cristian Maglie, Arduino Developers
did just that, but note that attachInterrupt() grows by returning bool.

boolean attachInterruptToPin(uint8_t pin, void (*userFunc)(void), int mode)
{
  return attachInterrupt(digitalPinToInterrupt(pin), userFunc, mode);
}

keeping attachInterrupt void gives me the smallest code. (and by keeping it void it will be BWcompatible)

Matthijs Kooijman

unread,
Sep 27, 2013, 5:53:41 AM9/27/13
to Rob Tillaart, Cristian Maglie, Arduino Developers
Hi Rob,

> keeping attachInterrupt void gives me the smallest code. (and by keeping it
> void it will be BWcompatible)
Making it bool is also backwards compatible. Source compatible of
course, but I don't think binary compatible is important for Arduino,
right?

You're saying that attachInterrupt as a void with the duplicate check in
the ToPin versions is smaller than a bool attachInterrupt and the
minimal ToPin version you showed? That would surprise me, really... Or
just that attachInterrupt is smallest when void (which makes sense).

Gr.

Matthijs
signature.asc

Rob Tillaart

unread,
Sep 27, 2013, 8:24:41 AM9/27/13
to Rob Tillaart, Cristian Maglie, Arduino Developers
(testsketch 1 call)
void attachInterrupt: 2946 bytes 
boolean attachInterrupt: 2954 bytes

Think AITP() was already quite optimized by the compiler.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAlJFVaUACgkQz0nQ5oovr7xLhQCgmqjpfALALnNSR/1MpSFa7+q5
Sx4An1uA3f9kM+DU9iOjpwFXurx0D1zE
=8PN6
-----END PGP SIGNATURE-----


Paul Stoffregen

unread,
Sep 27, 2013, 9:14:29 AM9/27/13
to devel...@arduino.cc
On 09/27/2013 05:24 AM, Rob Tillaart wrote:
(testsketch 1 call)
void attachInterrupt: 2946 bytes 
boolean attachInterrupt: 2954 bytes

Think AITP() was already quite optimized by the compiler.

If attachInterruptToPin() is implemented as a static inline function, will the compiler completely eliminate all overhead when the input is a constant?

Inside a library where the input comes from a function call, it probably can't optimize away the extra code.  But the libraries already have a bunch of code and lots of #ifdefs to map pin numbers to interrupts.  Hopefully this new function makes all that board-specific code unnecessary.





On Fri, Sep 27, 2013 at 11:53 AM, Matthijs Kooijman <matt...@stdin.nl> wrote:
Hi Rob,

> keeping attachInterrupt void gives me the smallest code. (and by keeping it
> void it will be BWcompatible)
Making it bool is also backwards compatible. Source compatible of
course, but I don't think binary compatible is important for Arduino,
right?

You're saying that attachInterrupt as a void with the duplicate check in
the ToPin versions is smaller than a bool attachInterrupt and the
minimal ToPin version you showed? That would surprise me, really... Or
just that attachInterrupt is smallest when void (which makes sense).

Gr.

Matthijs

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAlJFVaUACgkQz0nQ5oovr7xLhQCgmqjpfALALnNSR/1MpSFa7+q5
Sx4An1uA3f9kM+DU9iOjpwFXurx0D1zE
=8PN6
-----END PGP SIGNATURE-----


Tom Igoe

unread,
Sep 26, 2013, 11:49:32 AM9/26/13
to David Mellis, Paul Stoffregen, Arduino Developers
I'd combine them into one. I've found people generally confused about usongvan interrupt number as opposed to a pin number. You can't physically see the interrupts, but you can see the pins.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

David Mellis

unread,
Sep 27, 2013, 1:23:02 PM9/27/13
to Tom Igoe, Paul Stoffregen, Arduino Developers
Combine them how? If we just change the behavior of attachInterrupt(), we'll break people's existing code.

Cristian Maglie

unread,
Sep 28, 2013, 3:35:58 PM9/28/13
to devel...@arduino.cc

In data venerdì 27 settembre 2013 03:34:42, Paul Stoffregen ha scritto:
> Like this?

Yeah :)

put it here for a short review (barely tested):

https://github.com/arduino/Arduino/pull/1595

C

Paul Stoffregen

unread,
Sep 28, 2013, 3:48:24 PM9/28/13
to devel...@arduino.cc
On 09/28/2013 12:35 PM, Cristian Maglie wrote:
Should the Leonardo one also go into
hardware/arduino/avr/variants/robot_control ?



>
> C
>

Cristian Maglie

unread,
Sep 28, 2013, 3:56:06 PM9/28/13
to devel...@arduino.cc
In data sabato 28 settembre 2013 21:48:24, Paul Stoffregen ha scritto:
> Should the Leonardo one also go into
> hardware/arduino/avr/variants/robot_control ?

robot variants needs a more deep update... but yes, it should, I've updated
the pull request.

C

Matthijs Kooijman

unread,
Sep 28, 2013, 4:39:24 PM9/28/13
to Cristian Maglie, devel...@arduino.cc
Hey folks,

> put it here for a short review (barely tested):
>
> https://github.com/arduino/Arduino/pull/1595
Looks good. I checked the code against the schematics (Leonardo, Uno and
Mega 2560, didn't check the Due) and the attachInterrupt code and it
looks correct to me.

I was unpleasantly surprised by the complexity of the attachInterrupt
function, especially the fact that the interrupts numbers for the mega
are shuffled (e.g, you have to pass 2 to get INT0) seems confusing, but
I guess that's because there is some hardware that has INT4 and INT5 but
not INT0 and INT1 or something?


Anyway, regarding the code: In previous discussion it seemed useful to
use 0xff instead of -1 for the "invalid interrupt" case. In practice,
this is of course the same if saved in a uint8_t, but might be better to
make this explicit?

Gr.

Matthijs
signature.asc

Rob Tillaart

unread,
Sep 29, 2013, 10:32:22 AM9/29/13
to Cristian Maglie, Arduino Developers
Think -1 is better as when a board with >256 pins will arrive (someday)  the -1 will be mapped upon 0xFFFF 


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAlJHPnsACgkQz0nQ5oovr7xBogCgsnSbF0/p9myZ+KEAAtqn/6Pb
3dYAoONP0CB0Su2zOrilSVEA24XynYwn
=Hl/S
-----END PGP SIGNATURE-----


Brian Cook

unread,
Sep 29, 2013, 12:52:32 PM9/29/13
to Rob Tillaart, Cristian Maglie, Arduino Developers

Think -1 is better as when a board with >256 pins will arrive (someday)  the -1 will be mapped upon 0xFFFF

An even better choice would be a named typed constant.

- Brian

--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

Dennis German

unread,
Sep 29, 2013, 12:53:49 PM9/29/13
to devel...@arduino.cc
As an aside, can the

static const uint8_t LED_BUILTIN = ?????

be added while these updates are going on?

On 9/28/13 3:56 PM, Cristian Maglie wrote:
hardware/arduino/avr/variants/robot_control ?

Rob Tillaart

unread,
Sep 29, 2013, 1:13:58 PM9/29/13
to DGe...@real-world-systems.com, Arduino Developers
I prefer a 
#define  LED_BUILTIN 13 // or whatever
as it would not take memory.

did you post an issue for this @github yet?


--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.

Rob Tillaart

unread,
Sep 29, 2013, 1:19:49 PM9/29/13
to Brian Cook, Cristian Maglie, Arduino Developers
indeed that is a better idea,  could be 

#define  NOT_A_INTERRUPT    -1

Tom Igoe

unread,
Sep 29, 2013, 2:05:08 PM9/29/13
to Rob Tillaart, Brian Cook, Cristian Maglie, Arduino Developers
Perhaps NOT_AN_INTERRUPT would be better.

t.

Brian Cook

unread,
Sep 29, 2013, 11:14:36 PM9/29/13
to Rob Tillaart, DGe...@real-world-systems.com, Arduino Developers

I prefer a 
#define  LED_BUILTIN 13 // or whatever
as it would not take memory.

Which also works a better for boards that do not have a built-in LED.

- Brian



did you post an issue for this @github yet?
On Sun, Sep 29, 2013 at 6:53 PM, Dennis German <DGe...@real-world-systems.com> wrote:
As an aside, can the

static const uint8_t LED_BUILTIN = ?????

be added while these updates are going on?

On 9/28/13 3:56 PM, Cristian Maglie wrote:
 hardware/arduino/avr/variants/robot_control ?


--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

Cristian Maglie

unread,
Oct 1, 2013, 7:24:01 PM10/1/13
to devel...@arduino.cc
In data venerdì 27 settembre 2013 15:14:29, Paul Stoffregen ha scritto:
> On 09/27/2013 05:24 AM, Rob Tillaart wrote:
> > (testsketch 1 call)
> > void attachInterrupt: 2946 bytes
> > boolean attachInterrupt: 2954 bytes
> >
> > Think AITP() was already quite optimized by the compiler.
>
> If attachInterruptToPin() is implemented as a static inline function,
> will the compiler completely eliminate all overhead when the input is a
> constant?

It works, the compiler is able to fully optimize the function, but the body
should be placed inside Arduino.h (and after the inclusion of pins_arduino.h
because it uses pinToInterrupt macro internally).

On the Due is not possible to do the same for the different structure of core's
headers, but I think losing 40 bytes of flash there is not a concern.

Since I messed up the original pull request I've created another one here:

https://github.com/arduino/Arduino/pull/1604

if there are no concerns I'll merge it in a day or two.

C

David Mellis

unread,
Oct 2, 2013, 2:01:46 AM10/2/13
to Cristian Maglie, Arduino Developer's List
Personally, I don't like the duplication of attachInterrupt() and attachInterruptToPin(). Regardless of whether we use interrupt numbers or pin numbers, people still need to know (apart from the Due) which pins support interrupts. If they're already referring to a reference of some sort to find that out, it doesn't seem like much of an extra step to also find out the number of the interrupt that's attached to the pin.

If we were doing it over, I'd probably prefer pin numbers to interrupt numbers but I'm not convinced it's worth the duplication of providing both.



C

Matthijs Kooijman

unread,
Oct 2, 2013, 4:17:19 AM10/2/13
to David Mellis, Cristian Maglie, Arduino Developer's List
> Personally, I don't like the duplication of attachInterrupt() and
> attachInterruptToPin(). Regardless of whether we use interrupt numbers or
> pin numbers, people still need to know (apart from the Due) which pins
> support interrupts. If they're already referring to a reference of some
> sort to find that out, it doesn't seem like much of an extra step to also
> find out the number of the interrupt that's attached to the pin.
That is true for a lot of users, but I can still see two proper usecases
here:
- Libraries that accept arbitrary pin numbers can now more easily
attach interrupts to them.
- A program that #defines a pin number at the top now doesn't also need
to #define the corresponding interrupt number.

Of course, the end user that actuall decides which pins to use should
still know which pins are valid and which are not, but if the examples
are updated to actually check the result of attachInterruptToPin() and
print an error, I guess this should work out.

Also, both of the above usecases can also be done by manually calling
pinToInterrupt, but having a convenience wrapper makes more sense.

Finally, I think that the API of attachInterruptToPin makese more sense,
so this would only keep the old attachInterrupt around in the API by
means of backwards compatibility.




On another note: I'm not really sure if the name "attachInterruptToPin"
is the best one. Even though I proposed it, it seems to me now that it
could mean that you attach a particular interrupt to a particular pin,
which really isn't what's happening. The function attaches a handler to
the interrupt for a particular pin, so perhaps something like
attachInterruptForPin?

Gr.

Matthijs
signature.asc

Cristian Maglie

unread,
Oct 2, 2013, 5:42:54 AM10/2/13
to Arduino Developer's List
In data mercoledì 2 ottobre 2013 10:17:19, Matthijs Kooijman ha scritto:
> > Personally, I don't like the duplication of attachInterrupt() and
> > attachInterruptToPin(). Regardless of whether we use interrupt numbers or
> > pin numbers, people still need to know (apart from the Due) which pins
> > support interrupts. If they're already referring to a reference of some
> > sort to find that out, it doesn't seem like much of an extra step to also
> > find out the number of the interrupt that's attached to the pin.

True, but how we can move forward from that? I really like the method
attachInterruptToPin() because is much much more arduino-style than
attachInterrupt(), and I would love to find a way to evolve the API without
being stuck on the old method/design.

In this case why we don't simply deprecate attachInterrupt() method in favor
of attachInterruptToPin? This means that:
- we continue to provide attachInterrupt() for backward compatibility
- we document only attachInterruptToPin as "official" API (and maybe keep the
old attachInterrupt doc just for reference)

C

Paul Stoffregen

unread,
Oct 2, 2013, 11:02:15 AM10/2/13
to devel...@arduino.cc
On 10/02/2013 02:42 AM, Cristian Maglie wrote:
>
> True, but how we can move forward from that? I really like the method
> attachInterruptToPin() because is much much more arduino-style than
> attachInterrupt(), and I would love to find a way to evolve the API without
> being stuck on the old method/design.

+1 : Long term, evolve the API but maintain backwards compatibility.

Short term, after an IDE release with the digitalPinToInterrupt() macro,
I'll update the 2 libraries I maintain and submit pull requests to
Adafruit's libraries. It will be a very long time until libraries use
any new API that doesn't exist on older versions, but an #ifdef check on
the macro is a really nice solution as soon as any officially released
IDE supports it.

David Mellis

unread,
Oct 6, 2013, 2:12:22 PM10/6/13
to Cristian Maglie, Arduino Developer's List
I think we'd get stuck documenting and supporting both attachInterrupt() and attachInterruptToPin() for a long time. This might be worth it if there was a big benefit but, again, in this case I think it's not that bad (although not ideal) to ask someone to look up the interrupt number for the pin. Library writers and others that need a more general solution can use the digitalPinToInterrupt() macro.



C

Cristian Maglie

unread,
Oct 24, 2013, 4:11:01 AM10/24/13
to devel...@arduino.cc
In data domenica 6 ottobre 2013 20:12:22, David Mellis ha scritto:
> I think we'd get stuck documenting and supporting both attachInterrupt()
> and attachInterruptToPin() for a long time.

IMHO we should stop documenting attachInterrupt() and keep updating only
attachInterruptToPin().
Moreover attachInterruptToPin() is a wrapper function that will never change.

C

David Mellis

unread,
Oct 24, 2013, 9:32:04 AM10/24/13
to Cristian Maglie, Arduino Developer's List
But the idea is to continue to have attachInterrupt() around for compatibility right?  In which case, either you have an undocumented function (which is confusing) or you have to keep documenting both it and attachInterruptToPin(), which creates duplication and makes it harder for people to know which one to use. 



C

Victor Aprea

unread,
Oct 24, 2013, 9:34:50 AM10/24/13
to David Mellis, Arduino Developers, Cristian Maglie

Just mark one add deprecated in big red letters in the docs...right?

Vic

Tom Igoe

unread,
Oct 24, 2013, 9:37:43 AM10/24/13
to David Mellis, Cristian Maglie, Arduino Developer's List
I believe the plan was to keep everything in the 1.0 spec, at least until there’s a full 2.0, right?  Which would argue for not deprecating attachInterrupt() just yet.

t.

Tom Igoe

unread,
Oct 24, 2013, 9:38:23 AM10/24/13
to Victor Aprea, David Mellis, Arduino Developers, Cristian Maglie
Because every beginner is familiar with what that means? 

t.

Paul Stoffregen

unread,
Oct 24, 2013, 2:59:21 PM10/24/13
to devel...@arduino.cc
On 10/24/2013 06:32 AM, David Mellis wrote:
But the idea is to continue to have attachInterrupt() around for compatibility right?  In which case, either you have an undocumented function (which is confusing) or you have to keep documenting both it and attachInterruptToPin(), which creates duplication and makes it harder for people to know which one to use.

Over the long term, Arduino needs _some_ way to improve APIs.

Sure, there are trade-offs between various approaches, like most technical decisions.  There is no perfect, absolutely ideal way.  But avoiding beneficial changes due to documentation challenges would mean keeping Arduino forever frozen and unable to improve.

There certainly are cases where difficulty of documentation is an indication some feature is too complex.  I really don't think that applies in this particular case.

Tom Igoe

unread,
Oct 24, 2013, 3:07:33 PM10/24/13
to Paul Stoffregen, Arduino Developers
I agree, but I think the right times to make changes like that are on major version changes, not minor. Add on the minor, deprecate on the major. So I’m suggesting that perhaps deprecating attachInterrupt could hold off until we do a 2.0, and perhaps we could and should define what a 2.0 spec looks like.

t.

Cristian Maglie

unread,
Oct 31, 2013, 8:02:46 AM10/31/13
to devel...@arduino.cc

For the record: I've pushed the first part of the pull request about the macro
digitalPinToInterrupt(), since there are no concerns about that. Sorry for not
doing it early.

In data giovedì 24 ottobre 2013 21:07:33, Tom Igoe ha scritto:
> I agree, but I think the right times to make changes like that are on major
> version changes, not minor. Add on the minor, deprecate on the major. So
> I’m suggesting that perhaps deprecating attachInterrupt could hold off
> until we do a 2.0, and perhaps we could and should define what a 2.0 spec
> looks like.

deprecating means that we discourage the use of attachInterrupt() in favor of
attachInterruptToPin() that will be the long term supported function that
offers the same functionality but in an easier way.
We are no removing the old function, so we are not breaking 1.0 API in any
way: we are adding as you said.

I don't see any reason to delay this until 2.0 API (that may take many months
to actually happen) except the documentation effort.

C

David Mellis

unread,
Oct 31, 2013, 10:36:37 AM10/31/13
to Cristian Maglie, Arduino Developer's List
Again, I don't think it's that much overhead for someone to use the interrupt number instead of the pin number. Anyway, they need to look up in the documentation which pins support interrupts (apart from the Due); it doesn't seem that much of a burden to also note the interrupt number associated with that pin. The digitalPinToInterrupt() macro seems like it should handle the case in which you need a more generic method of using a pin number instead of an interrupt number.

If this change seemed more pressing, I think it would be okay to switch over to a new function and deprecate the old one. In this case, though, it doesn't seem worth the confusion of having two different but similar functions.



C

Tyler F

unread,
Mar 2, 2015, 8:11:59 PM3/2/15
to devel...@arduino.cc
Digging up this old thread: I like the idea for digitalPinToInterrupt(), but what about analog pins on the Due? Is it even possible to assign an interrupt to an analog pin to detect a falling/rising edge? When I tried it, my Arduino just hung, probably because the sensor data was noisy and was constantly calling the interrupt, not allowing anything else to run. Is there a way to do it with a certain threshold or something?

Thanks!

Tyler

On Thursday, September 26, 2013 at 4:09:26 AM UTC-7, paul wrote:
I'd like to propose another macro in pins_arduino.h, to allow libraries
to translate digital pins to the interrupt numbers needed for
attachInterrupt(), and detect if a user-specified pin doesn't support
attachInterrupt().

It might look something like this?

   // Arduino Uno
   #define digitalPinToInterrupt(p)  ( (p) == 2 ? 0 : ((p) == 3 ? 1 : -1) )

   // Arduino Mega
   #define digitalPinToInterrupt(p)  ( (p) == 2 ? 0 : ((p) == 3 ? 1 :
((p) >= 18 && (p) <= 21 ? 23 - (p) : -1)) )

   // Arduino Leonardo & Yun
   #define digitalPinToInterrupt(p)  ( (p) == 0 ? 2 : ((p) == 1 ? 3 :
((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : -1)))) )

   // Arduino Due
   #define digitalPinToInterrupt(p)  ( (p) < NUM_DIGITAL_PINS ? (p) : -1 )

At least 4 libraries currently have long #ifdef chains for this purpose:
Encoder, PS2Keyboard, Adafruit_VS1053 and Adafruit_CC3000. The GSM3
library also has some hard-coded pin to interrupt stuff.  I do not
believe any of these libraries fully supports all official Arduino boards.

Reply all
Reply to author
Forward
0 new messages