Go Down

Topic: Incremental Rotary Encoder and Arduino... (Read 2 times) previous topic - next topic


So I have bought this 12v Motor that has an Incremental 64 CPR Encoder installed on it.
The classic gray code A/B sensors.

I wrote the arduino code, similar to examples found on the net.
Tried polling the sensors both: on Loop and using Interrupts.

Problem is, the motor turns fast. Not lightning fast, but fast and some codes are being skipped.
When I turn the motor by my hand 'click' by 'click' all codes are in proper order both directions turned.

But, if I try to turn it, even by hand a little bit faster, then some codes will be skipped.
Is that normal with a 64 CPR encoder for arduino? Is it "high" precision for the Speed Arduino can actually poll the data?

Please note: the code is optimized, does not have bugs or does expensive operations that delay the execution.
(for instance, yes. the sensor pins are polled once per loop and saved into two variables, then used as those variables)

I am starting to wonder, do I have to place an Absolute Encoder to make this work?
Or an even smaller precision like 4 CPR to be sure arduino can process every pulse correctly?



Interrupts sound like the way to go. Post your code though.


Tried already with attachInterrupts.
Still skips codes...  =(

Please note. Skipping of codes does not happen if I rotate very slowly.


Tried already with attachInterrupts.
Still skips codes...  =(

Please note. Skipping of codes does not happen if I rotate very slowly.

Again, I'm not familiar with the encoder or pulses you are receiving or, how you set up the interrupts. Did you set the interrupt as a positive flank detection instead of pin change? That's quite an important part.

Are you running the serial port? I don't have the serial port library with me but, my guess is that when you send data through it, you disable interrupts while you're sending data and then enable them when the transmission if finished. At higher speeds, this causes a problem in your software.

Do this, delete all the Serial.print*() functions from the software. Create a condition that you'll only send data if a request from the serial port is received. Say, every time you send a "T" over the serial protocol, the program sends the count to you. Run the encoder fast for a set number of times, stop, and check the count on the encoder input.
This will tell you if the problem is on the serial port or not.

However, the best way to do this task is to free the system from processing just to count.

Check how to set up Timer 1 as a counter, and then place the encoder signal in that input. It won't detect direction, but it will count. probably fast enough for you to catch it.

I'm at work now, but if you can't find it by then, I'll post an example for you to see what I'm talking about.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).


hmm, very interesting and you are right on spot with your guesses.

-When I tried the interrupts I added on Pin Change.
-To test if it was working properly I also Serial.Printed the Sensors Output

So both have problems it seems.
I will make the changes you recommended retest and see if it worked.

Thanks, I will post the results once I can.

Go Up