Using Encoder class with interrupt inside a library

Hello,
I try to use Encoder object inside a class and I have some difficulies to write it.

I understand the encoder object must be static and the doA, etc must also be static.

in the *.h of my library:

static Encoder encoder;
static void doA();
static void doB();
static void doIndex();

in the *.cpp:

constructor of my library:
// Encodor
	encoder = Encoder(ENCODER_A, ENCODER_B, 1);
	encoder.pullup = Pullup::USE_INTERN;
	encoder.quadrature = Quadrature::OFF;
	encoder.enableInterrupts(Cnc::doA, Cnc::doB, Cnc::doIndex);
	encoder.init();
}

and the functions…

void Cnc::doA(){
	encoder.handleA();
}

void Cnc::doB(){
	encoder.handleB();
}

void Cnc::doIndex(){
	encoder.handleIndex();
}

When I compile the code, i have the following error:
Cnc is my library…

libraries\CNC\Cnc.cpp.o:(.literal._ZN3Cnc3doAEv+0x0): undefined reference to `Cnc::encoder'
collect2.exe: error: ld returned 1 exit status

How can I deal with this error ?
The compiler is happy, but not the linker…

Best regards

Hi @Vorms ,

You’re trying to access the variable “encoder” from inside the static methods of class Cnc.
The linker is complaining that it can’t find this variable “encoder”.

You probably haven’t defined it. If you declare a static member in your header file, you have to define it in a cpp file, like this:

.h FIle

class Cnc {
static Encoder encoder;
...
}

.cpp file:

Encoder Cnc::encoder;

...

hello,
Many thanks for your help.
Unfortunaltly, I obtain the following error:

F:\users\Vorms\Documents\Arduino\libraries\CNC\Cnc.cpp:2:14: error: no matching function for call to 'Encoder::Encoder()'
 Encoder Cnc::encoder;
              ^
In file included from F:\users\Vorms\Documents\Arduino\libraries\Simple_FOC\src/SimpleFOC.h:101:0,
                 from F:\users\Vorms\Documents\Arduino\libraries\CNC\Cnc.h:5,
                 from F:\users\Vorms\Documents\Arduino\libraries\CNC\Cnc.cpp:1:
F:\users\Vorms\Documents\Arduino\libraries\Simple_FOC\src/sensors/Encoder.h:27:5: note: candidate: Encoder::Encoder(int, int, float, int)
     Encoder(int encA, int encB , float ppr, int index = 0);

Many thanks for your help, it’s a bit to tricky for me…

Best regards
Thierry

Ah, in this case my example was too simple! It was an example in “pseudo-code”, and so it was incomplete.

Now the compiler is complaining that there is no constructor method for the Encoder class that takes no parameters. So we have to pass in the required parameters to the constructor method of Encoder, like this:

Encoder Cnc::encoder = Encoder(ENCODER_A, ENCODER_B, 1024);

In this example the encoder uses pins ENCODER_A and ENCODER_B, and has 1024 PPR. No Index pin is used. You can look up the PPR value for your encoder in its Datasheet.

Thanks for your help.
Here is my solution:
in *.h:
static Encoder *encoder;

in *.cpp
outside of the class:
Encoder *Cnc::encoder;

in the constuctor of the class:
// Encodor
encoder = new Encoder(ENCODER_A, ENCODER_B, 1);
encoder->pullup = Pullup::USE_INTERN;
encoder->quadrature = Quadrature::OFF;
encoder->enableInterrupts(doA, doB, doIndex);
encoder->init();

this code compile but is not tested because I don’t receive the material yet.

Many thanks for your help!

1 Like

Hey, good that it is compiling, but I think there is still a problem:

encoder = new Encoder(ENCODER_A, ENCODER_B, 1);

The parameter “1” is your PPR = pulses per revolution. So with “1” as parameter, this would mean 1 pulse per revolution - I don’t know which encoder you are using, but this is almost certainly wrong. The encoders typically have 64 to 4096 PPR, depending on the model.
And if you can you should use quadrature mode to increase the resolution by x4.

Hello,
I have 500 pulses by rev but I am not using the pulses by revolution parameter…
Thanks again for your help !
I read a lot for this project and didn’t find any support for an “old scool motor.”… a simple DC motor drived by an amplifier…
So I have to deal with ramp and other part on the FOC library
best regards !