Hi,
I want to create a class "Odometer" which outputs distance measured by a rotary encoder.
I'm re-using one of the sketches code from here : Arduino Playground - RotaryEncoders.
And I've embedded the interrupts and ISRs into the class constructor.
Now, the code "attachInterrup(0, encodePinA, CHANGE)" works just fine when it's in the void setup(),
but when I put it in the class constructor, it's not compiling !
Details
the compile error is :
* *In constructor 'Odometer::Odometer(int, int)': .../libraries/Odometer/Odometer.cpp:20:40: error: cannot convert 'Odometer::encodePinA' from type 'void (Odometer::)()' to type 'void (*)()'* *
I've tried changing ISR call to "this.encodePinA" or "this.encodePinA()" or "this->encodePinA" or "this->*encodePinA" and am out of ideas.
Find below, the sketch, the class librabary .h and .cpp
SKETCH
#include <Odometer.h>
Odometer MyOdometer(2, 3);
long prev_distance = 0;
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
if (prev_distance != MyOdometer.distance()) {
Serial.println(MyOdometer.distance());
prev_distance = MyOdometer.distance();
}
}
HEADER
#ifndef Odometer_h
#define Odometer_h
#include "Arduino.h"
class Odometer
{
public:
Odometer(int pinA, int pinB);
long distance();
void debug(boolean debug);
private:
void encodePinA();
void encodePinB();
int _pinA;
int _pinB;
boolean _A_set = false;
boolean _B_set = false;
boolean _debug;
long _distance;
};
#endif
CONSTRUCTOR
#include "Arduino.h"
#include "Odometer.h"
Odometer::Odometer(int pinA, int pinB)
{
pinMode(pinA, INPUT);
digitalWrite(pinA, HIGH); // turn on pullup resistor
_pinA = pinA;
pinMode(pinB, INPUT);
digitalWrite(pinB, HIGH); // turn on pullup resistor
_pinB = pinB;
attachInterrupt(0, encodePinA, CHANGE);
attachInterrupt(1, encodePinB, CHANGE);
_distance = 0;
_debug = false;
}
// Return Distance
long Odometer::distance(){
return _distance;
}
// Interrupt on A changing state
void Odometer::encodePinA(){
// Test transition
_A_set = digitalRead(_pinA) == HIGH;
// and adjust counter + if A leads B
_distance += (_A_set != _B_set) ? +1 : -1;
if (_debug) {Serial.println(_distance);}
}
// Interrupt on B changing state
void Odometer::encodePinB(){
// Test transition
_B_set = digitalRead(_pinB) == HIGH;
// and adjust counter + if B follows A
_distance += (_A_set == _B_set) ? +1 : -1;
if (_debug) {Serial.println(_distance);}
}
Am I tackling a pure syntax problem or is this more core to using attachInterrupt in classes ?
Thanks for your help !
Baptiste