Rotary encoder registers 4 times as much

Hello,

I'm using one those cheap rotary encoders off ebay:

and tried it along with those libraries:

RotaryEncoder.h

https://www.pjrc.com/teensy/td_libs_Encoder.html

and when I upload the sketch to my MCU(Arduinio nano) it all works CW and CCW but registers 4 times at a tick (in both libraries) instead of a single time as expected.

How would I fix it?

Thanks for helping.

Divide by 4.

aarg:
Divide by 4.

Well that won't do sins I don't want to put /4 all over the code that's why I use a library to keep it neat.

MikeLemon:
Well that won't do sins I don't want to put /4 all over the code that's why I use a library to keep it neat.

I'm glad that it's so virtuous. You shouldn't have to put /4 everywhere for anything in a properly constructed C++ program. That's what functions are for.

aarg:
I'm glad that it's so virtuous. You shouldn't have to put /4 everywhere for anything in a properly constructed C++ program. That's what functions are for.

But why not solve the problem from the roots? it will just bee an exponential issue like that.

MikeLemon:
But why not solve the problem from the roots? it will just bee an exponential issue like that.

Unfortunately, most hardware is kind of dumb and requires a "wrapper" of some kind to manage the complexity and hide the details that are not important in the user application. In my view, a well constructed interface is a root solution.

Dividing by 4 would be a kind of kludge, I admit. I would be surprised if the library doesn't have some feature to handle this problem.

But it is not hard to encapsulate it, like:

long getEncPosition()
{
  return myEnc.read()/4;
}

Then you just call getEncPosition() any place you would have called myEnc.read(). You can even use find and replace if you already have the sketch written.

Delta_G:
I'd skip the library. All you need is one interrupt routine for one of the pins if you only want one tick per click. I mean libraries are nice, but if it doesn't work like you want then why spend a day trying to change the library when you can spend 30 seconds writing the one function you actually need?

Education!

Delta_G:
I'd skip the library. All you need is one interrupt routine for one of the pins if you only want one tick per click. I mean libraries are nice, but if it doesn't work like you want then why spend a day trying to change the library when you can spend 30 seconds writing the one function you actually need?

Great, so the work is finished by the time I post this! Excellent! :slight_smile:

aarg:
Great, so the work is finished by the time I post this! Excellent! :slight_smile:

Woho wait this library also supports velocity control that's another reason I need to modify it.

Which library?

aarg:
Which library?

https://code.google.com/archive/p/arduino-rotary-encoder-with-velocity/downloads

You sure you want to proceed with this:

To do this effectively, you really need to "debouce" the switch. I've never been able to effectively do this in software. I use 10000pF capacitors between the A pin and GND and B pin GND. This makes the circuit very well protected from bad reads. Furthermore, you need to check the value more frequently than it can change otherwise the quadrature signal will become out of sync and you will not know what direction you are turning.

?

aarg:
You sure you want to proceed with this:?

Nope...

What do you suggest I do?

MikeLemon:
Nope...

What do you suggest I do?

What have you tried?

What do you suggest I do?

How are you using this encoder? How do you plan to use the velocity?

aarg:
What have you tried?

having the function encoder.readEncoder only return a number od change it when both reads are high acted wierdly

and now the less elegant solution of making a float variable divide it by 4 and and put it on another int for major read.

MikeLemon:
...and now the less elegant solution of making a float variable divide it by 4 and and put it on another int for major read.

...as opposed to the brutally simple function I showed you?

MikeLemon:
What do you suggest I do?

You might consider upgrading to a photoelectric encoder. These usually employ an optical disk with phototransistors and several choices of solid state outputs. No debouncing, standard A, B, Z output channels, various PPR rates.

A caveat: They're not Ebay cheap but if you balance encoder cost against your programming time it may work for you.

So I am using this encoder for similar projects. The code is quite simple to achieve what you need

#define ClockPin 2 // Must be pin 2 
#define DataPin 3 // can be any pin

volatile long count = 0;
long lastCtr;

void Encoder() {
  (digitalRead(DataPin)== HIGH)  ? count++ : count--;
}

void setup() {
  Serial.begin(115200); //115200
  pinMode(ClockPin, INPUT);
  pinMode(DataPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(ClockPin),Encoder, RISING);
}

void loop() {
  long Counter;
  noInterrupts ();
  Counter = count;
  interrupts ();
  if (lastCtr != Counter) {
    Serial.println(Counter);
  }
  lastCtr = Counter;
}

This is as simple as I can make it.

also This shows how I debounced the encoder which is required for this device!!!!
Encoder.jpg

Z

Encoder.jpg

Why @MikeLemon is focused on using a library, and not a very flexible or powerful one, inspite of all the simple demonstration code previously offered (and now yours) along with advice to not use a library is a mystery.

Quote from: aarg on Today at 07:32 am
Which library?
Google Code Archive - Long-term storage for Google Code Project Hosting.