I am making my own optical encoders. Each of them follows the exact same structure, so I figured I'd lump all the encoder processing in a class, StepCounter
. However, when I directly attach an interrupt to a member function, I get
cannot convert 'StepCounter::step' from type 'void (StepCounter::)()' to type 'void (*)()'
Fair enough, a member method is different than a global method (however, maybe I can somehow cast it to a void(*)()
by providing this
?). So, I made the following solution (note: 18, 19 and 22, 23 are pin numbers, so assume that the naming convention makes any sense there):
class StepCounter {
public:
StepCounter(int pinInterrupt, int pinSecond, void (*wrapperFcn)(void)) :
pinInterrupt(pinInterrupt),
pinSecond(pinSecond) {
pinMode(pinInterrupt, INPUT);
pinMode(pinSecond, INPUT);
stateSecond = digitalRead(pinSecond);
attachInterrupt(digitalPinToInterrupt(pinInterrupt), wrapperFcn, CHANGE);
};
volatile int distance = 0;
void step() {
int newSecond = digitalRead(pinSecond);
int stateXOR = digitalRead(pinInterrupt);
// Direction is stateXOR * (stateSecond==newSecond)
// if we take (-1,1) rather than (0,1) for (true,false)
int multiplier = (stateXOR == HIGH) ? -1 : 1;
if (stateSecond == newSecond) {
distance -= multiplier;
} else {
distance += multiplier;
}
stateSecond = newSecond;
}
private:
const int pinInterrupt;
const int pinSecond;
volatile int stateSecond;
};
void interrupt1822(); // Forward declaration
void interrupt1923();
StepCounter stepCounter1822(18,22,interrupt1822),
stepCounter1923(19,23,interrupt1923);
void interrupt1822() {
stepCounter1822.step();
};
void interrupt1923() {
stepCounter1923.step();
};
But, in all honesty, this looks rather clumsy with a bunch of forward declarations. And, although there is only so many interrupt pins on an Arduino, I still feel that copy-pasting so many things is something that should usually be avoided in programming.
Furthermore, I'm wondering whether there is any faster way of doing my step()
function; since it's an interrupt service routine that I expect to be called a lot, I'd like it to be as fast as possible.