Pages: [1]   Go Down
Author Topic: Using PinChangeInt in multiple libraries  (Read 899 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have been using http://code.google.com/p/arduino-pinchangeint/ 1.72 successfully in a simple sketch.

Now I want to use the functions in one or more libraries of my own creation. Alll the code of PinChangeInt is in a single PinChangeInt.h header file. If the latter is included in multiple places, I unsurprisingly get warnings about duplicated functions.

I could modify PinChangeInt to separate interface and implementation into separate .h and .cpp files. Before I embark on this task, I thought I would ask if anyone else has encountered this issue, and if there is a simpler workaround!

Thanks in advance for any suggestions.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The problem with pin change interrupts is that, on the Atmega328 at least, you get three interrupts (three ISRs).

Some information here:

http://www.gammon.com.au/interrupts

Now you just can't, for example, have four libraries that each try to implement those ISRs. In fact any library that uses pin change interrupts may "take over" all of them, or at least one of them. In other words, the same ISR can't be implemented more than once.

Maybe a better solution would present itself if you didn't try to describe the low level problem (trying to manage lots of pin change interrupts) but the higher level problem (what you are actually trying to achieve).

Logged


Dallas, Texas
Offline Offline
Sr. Member
****
Karma: 3
Posts: 267
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow Nick. What a great page. Its an excellent Arduino/AVR INT resource.

Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is indeed a great page! Thanks.

Back to the original thread - I don't want to implement lots of interrupts, and I understand the limitations of AVR, but....

I would like to be able to encapsulate low-level stuff within a library, and hide the nuts and bolts from the user. To this end, I would like to be able to attach and detach interrupts within library functions. But as I have to include PinChangeInt.h, which includes the implementation, it seems I can only do this for one library. If I want to attach another pin change interrupt within another library, I can't.

The alternative seems to be to only include PinChangeInt.h in the top sketch, and make all calls to attachInterrupt() and detachInterrupt() in the top sketch. Which seems messy.

Also, in my library code, it seems I have to include desired header files by relative path:

Code:
#include "..\Timer1\TimerOne.h"
#include "..\PinChangeInt\PinChangeInt.h"

instead of the usual

Code:
#include <TimerOne.h>
at the top level sketch.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

For a start, attachInterrupt/detachInterrupt only refer to the external interrupts, not the pin change ones. They did that by making a level of indirection where the "real" interrupt calls a function stored in an array (by attachInterrupt).

There is a cost ... the attachInterrupt handlers are slower than "pure" interrupt handlers.

If you try to add your own indirection you will be adding this extra cost. Bearing in mind interrupt handlers are supposed to be as fast as possible.

Also I don't like the idea of:

Quote
I would like to be able to attach and detach interrupts within library functions ...

I hope you don't mean continuously, because interrupts by their nature are unpredictable. The best you could probably do is chain them, and even that might not be optimal - both for speed reasons, and the question of "which handler gets to be serviced first?".

I'm inclined to ask "what problem are you trying to solve?". The idea of nice libraries is all well and good, but this is a $5 chip with some limitations. At times we have to work within those rather than trying to be too general.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, laziness on my part. I meant PCintPort::attachInterrupt() and PCintPort::detachInterrupt()

Not intending to be attaching and detaching continually. Just wanted to hide the low level configuration from the end user of a library, so that the attaching is not done in the top sketch. I suppose I could define a preprocessor macro in the library header file, which then gets put in the top sketch, and expanded when the PCintPort methods are in the compiler scope.

Point taken about the $5 chip though...

Thanks for your input.
Logged

0
Offline Offline
Jr. Member
**
Karma: 4
Posts: 93
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, laziness on my part. I meant PCintPort::attachInterrupt() and PCintPort::detachInterrupt()

Not intending to be attaching and detaching continually. Just wanted to hide the low level configuration from the end user of a library, so that the attaching is not done in the top sketch. I suppose I could define a preprocessor macro in the library header file, which then gets put in the top sketch, and expanded when the PCintPort methods are in the compiler scope.

Point taken about the $5 chip though...

Thanks for your input.

In the header of the PinChangeInt.h file, I write:


The library has been modified so it can be used in other libraries, such as my AdaEncoder library
   (http://code.google.com/p/adaencoder/).  When #include'd by another library you should #define
   the LIBCALL_PINCHANGEINT macro.  For example:
   #ifndef PinChangeInt_h
   #define LIBCALL_PINCHANGEINT
   #include "../PinChangeInt/PinChangeInt.h"
   #endif
   This is necessary because the IDE compiles both your sketch and the .cpp file of your library, and
   the .h file is included in both places.  But since the .h file actually contains the code, any variable
   or function definitions would occur twice and cause compilation errors- unless #ifdef'ed out.

Hopefully that helps.  See http://code.google.com/p/arduino-pinchangeint/wiki/Usage#Use_from_Another_Library
« Last Edit: June 23, 2012, 07:25:20 pm by GreyGnome » Logged

Pages: [1]   Go Up
Jump to: