Hello i have a class and i would like to attach an interrupt inside the class and attach it to a function of the class.
class counter{
public:
counter(int pin){
Ipin=pin;
}
void startCounting(){
attachInterrupt(digitalPinToInterrupt(Ipin),this.addCount,CHANGE);
}
void stopCounting(){
detachInterrupt(digitalPinToInterrupt(Ipin));
}
void addCount(){
count++;
}
private:
int Ipin;
unsigned long count= 0;
};
Some what of the code above. There can be multiple intialization of this class. hopefully depending on the user uses a different pin.
There is a way arround this where the attaching of pin is done in the loop or setup and just calling a public function of the class. But to me that kinda doesn't fit the spirit of classes like a properly made library is done.
Im not very good at programming if you could teach me how it would be greatly appreciated.
-
I's not supported by attachInterrupt. You need some function that calls that desired method.KIIV– KIIV2020年03月18日 21:54:52 +00:00Commented Mar 18, 2020 at 21:54
-
@KIIV so how do libraries with interrupts do it?Jack– Jack2020年03月18日 22:05:26 +00:00Commented Mar 18, 2020 at 22:05
-
By using some function that calls method on specific object. You can't use more callbacks for the same interrupt source anyway.KIIV– KIIV2020年03月18日 22:08:56 +00:00Commented Mar 18, 2020 at 22:08
-
So if we go by what you have said and to lets say i were to create a library. I would have 2 fuunctions that does not belong to any class in the .h or .cpp that first function attaches the interrupt to the second function, and that second function calls a method of the class?? Is it possible to call a global function inside of a class?Jack– Jack2020年03月18日 22:24:31 +00:00Commented Mar 18, 2020 at 22:24
1 Answer 1
I have a post about this problem.
Basically you cannot attach a class function with attachInterrupt because of the hidden "this" pointer which needs to be supplied to a (non-static) class function, where "this" is the particular instance of the class. You can work around it like this:
class myClass
{
static volatile bool switchChanged; // declare
public:
void begin ()
{
pinMode (2, INPUT_PULLUP);
attachInterrupt (0, switchPressed, CHANGE);
} // end of myClass::begin
static void switchPressed ()
{
switchChanged = true;
} // end of myClass::switchPressed
}; // end of class myClass
volatile bool myClass::switchChanged; // define
myClass foo; // make an instance of myClass
void setup ()
{
foo.begin ();
} // end of setup
void loop ()
{
// whatever
} // end of loop
But that isn't great because, as you observed, you are really downgrading the class to use a static boolean.
Another way of doing it is to write "glue" routines, like this:
class myClass
{
volatile bool switchChanged;
static myClass * instances [2];
static void switchPressedExt0 ()
{
if (myClass::instances [0] != NULL)
myClass::instances [0]->switchPressed ();
} // end of myClass::switchPressedExt0
static void switchPressedExt1 ()
{
if (myClass::instances [1] != NULL)
myClass::instances [1]->switchPressed ();
} // end of myClass::switchPressedExt1
public:
void begin (const byte whichPin)
{
pinMode (whichPin, INPUT_PULLUP);
switch (whichPin)
{
case 2:
attachInterrupt (0, switchPressedExt0, CHANGE);
instances [0] = this;
break;
case 3:
attachInterrupt (1, switchPressedExt1, CHANGE);
instances [1] = this;
break;
} // end of switch
} // end of myClass::begin
void switchPressed ()
{
switchChanged = true;
}
}; // end of class myClass
myClass * myClass::instances [2] = { NULL, NULL };
// instances of our class
myClass foo;
myClass bar;
void setup ()
{
foo.begin (2); // pin D2
bar.begin (3); // pin D3
} // end of setup
void loop ()
{
// whatever
} // end of loop
That's still not a great solution, but it might give you some ideas.
Your fundamental problem is that classes, by their nature, can be instantiated many times, however you only have a small, fixed, number of interrupts on the microprocessor.
-
Thank you for the great reference, the "glue" solution would work for me because i am using a custom built board and there is a fix number of pins to interrupt. I just want to take the trouble off the user when using the library, when begin is called on my main class all the interrupts should be ready to go. Atleast i wont have to make a function on all interrupt pins (60+ pins = 60+ functions on due). Thank you again for the answer.Jack– Jack2020年03月19日 10:39:43 +00:00Commented Mar 19, 2020 at 10:39
-
I can understand it would cause trouble where the number of instantiation would exceed the number of interrupts the processor. Although that can be fixed by adding protection macros that throws an error if the number of instantiation exceed the number of interrupts,but that would be a lot of macros for each board you want your class to work.Jack– Jack2020年03月19日 10:50:06 +00:00Commented Mar 19, 2020 at 10:50