Rotary Encoder

When using a rotary encoder with the CLK and DT pins connected to INT pins 0 & 1, I would expect to see the binary pattern between the CLK and the DT pins as a mixture of HIGH's and LOW's as the shaft is rotated. However I see the two signals are permanently high with brief excursions LOW when the shaft is rotated but both return to the high state. I would expect them to see a binary 2 bit pattern going from 00, 01, 10, 11 and then reverse. depending on shaft rotation direction.
Anybody else experience this? Is there a fix?
Thanks in advance.

I would expect them to see a binary 2 bit pattern going from 00, 01, 10, 11

What exact encoder are you using? How exactly is it wired? Schematic and code, please.

Read the how to use this forum-please read sticky to see how to properly post code and some advice on how to ask an effective question. Remove useless white space and format the code with the IDE autoformat tool (crtl-t or Tools, Auto Format) before posting code.

Posting images
How to post an image.
Another page on posting images.

Apologies for not following protocol.

I have attached a circuit diagram. Ignore the OLED, that functions fine. I haven’t included the code in the post as I haven’t began to code it until I know the hardware problem.
The rotary encoder includes 2 x 10K pull up resistors not shown on the diagram.
Thanks for your patience.

A rotary encoder switch has two outputs, called A and B, and a common ground.

You've drawn ground and Vcc both going to the encoder and only one data line, so its clearly wrong,
probably a potentiometer circuit instead.

Please post an accurate circuit diagram, with resistors. Don't bother with Fritzing wiring diagrams,
draw a circuit diagram.

CLK and DT imply clock and data, which is not appropriate to an incremental encoder like this.

Standard imcremental encoder outputs are A and B, and sometimes Z as well, being a once-per-rotation
index pulse.

Many thanks for your timely response MarkT
I have attached a schematic of the wiring and a image of the encoder provided by ELEGOO showing Gnd, Vcc, DT and CLK pins.
Im sure its a rotary encoder not a potentiometer!

As the rotary encoder is rotated I can see on an oscilloscope the CLK and DT pins transition to a low state but only briefly and then both return to high.


The Encoder library make using those units pretty simple. The linked page has links to pages that explain how the encoders and library works. The library is available via the IDE library manager. There also examples with the library.

In my (limited) experience, controls like this have detents, and at the rest positions, both A and B outputs are open circuit. A and B close momentarily between detents, one before the other, depending on direction of turn. You can think of A and B as CLK and DAT but it's a little arbitrary which is which.

That diagram shows 2 diodes and 1 switch inside the encoder. That's wrong!

You don't need to use 2 interrupt pins. Just use 1 interrupt pin for CLK and any other digital input for DAT. Read DAT in the interrupt routine, on either the rising or falling edge of CLK, and increment of decrement a volatile global int variable. Experiment to find out which works best.

Thanks Paul. That makes sense why the two signals only take a momentary excursion to a logical low state. I can code it to increase or decrease a count but its a little twitch and sometimes jumps tow to 3 counts (even when using various toolkit examples). Ill play with the timing of monitoring the states following an interrupt to see if that helps.
Yes I am wasting a INT pin so will move across to a I/O pin.
One other question, why use a volatile int?

Many thanks again.

Inside the encoder are mechanical switches. Mechanical switches bounce. Some encoder libraries include debounce. I often do not use libraries so I do hardware debounce on the encoders. Set the inputs to pinMode INPUT_PULLUP.

One other question, why use a volatile int?

This and much else on the reference page.

“volatile” is important when a variable is changed by an interrupt function. The C++ compiler is clever and will try to figure out when a variable can or cannot have changed, and make the code faster by assuming it has not changed. But interrupts can break that assumption. By making the variable “volatile”, you are instructing the compiler not to make assumptions which may not be true.

Encoder libraries never need debounce as their is no ambiguity with bounce, it just toggles the
output position +/- one count, which is something that can happen anyway if there's mechanical vibration.

The output position from an encoder like this can be given hysteresis of 1 count before interpreting it,
something like this:

volatile int position ;

ISR ....
  position = ...

int get_position()
  static int smoothed_position;
  if (abs (position - smoothed_position) > 1) // moved more than 1 since last time
    smothed_position = position ;
  return smoothed_position ;

The result of get_position() will hide any bouncing or dithering between readings when
perched on the edge.