TK06DIGITALbeginner

Rotary Encoder

An EC11-type rotary encoder with a push switch in its shaft, its pull-ups, filter capacitors and pull-down already fitted. Two contacts a quarter of a cycle apart give the direction; the program keeps the count. Pushed in, BTN reads HIGH.

Comes in this kit — not sold separately

Specifications

TypeIncremental quadrature rotary encoder with a push switch, no end stops
EncoderEC11-type, horizontal, Ø6 mm shaft on an M7 bushing, blue knob. Most EC11 parts give 20 clicks a turn; count yours
Pull-ups10 kΩ from CLOCK and from DATA to VCC, with 100 nF from each to GND: a 1 ms filter. Both rest HIGH and go LOW while their contact is closed
Push switchJoins BTN to VCC, with a 10 kΩ pull-down to GND. Released reads LOW, pushed reads HIGH
Supply3.3 V or 5 V on VCC. CLOCK, DATA and BTN all reach VCC, so use 3V3 beside an ESP32, ESP32-S3 or Pico and 5V beside an Uno
Pins to wire5 of the 6: GND, VCC, BTN, CLOCK and DATA. NC is connected to nothing on the board
Header6-pin right-angle male, 2.54 mm pitch: GND, VCC, NC, BTN, CLOCK, DATA, with GND on the square pad
Board22.4 × 30.4 mm, two 4.8 mm mounting holes 16 mm apart; 15.43 mm to the top of the knob
In the box1 × TK06 block. It also ships inside the TinkerBlock kits

What it is

A knob with no end stops. Inside it, two contacts close and open a quarter of a cycle apart as the shaft turns; each pulls its line, CLOCK or DATA, LOW while it is closed, and a 10 kΩ pull-up holds it HIGH while it is open. The direction is in which of the two falls first, and the distance is how many times they do. Push the knob in and a third switch pulls BTN HIGH.

The TK06 at an angle: a black board with a gold-plated border, a metal and teal encoder body near the top with its threaded bushing and a large blue knob pointing out past the top edge, two big mounting holes, lonely binary along the left edge, and a right-angle header whose six pins point out past the bottom edge.
The TK06. The shaft points out past the top edge, the header past the bottom.

Unlike a potentiometer, it reports change, not position, so it suits a menu, a volume that should not jump when the program starts, or any value with more range than one turn. The catch is in the reading. A sketch that polls the pins from a loop() with a delay() in it counts perfectly when turned gently and loses count, or counts backwards, when someone flicks it. The handbook below shows why and fixes it with an interrupt.

Each rotation line also has a 100 nF capacitor to GND, which with the pull-up makes a 1 ms filter against contact bounce. It helps; it does not make bounce impossible.

VCC is the level of all three signals

Your boardVCC toCLOCK and DATA at restBTN pushed
Arduino Uno5V5 V5 V
ESP32, ESP32-S3, Pico3V33.3 V3.3 V

Never 5V beside a 3.3 V board. With VCC unconnected, CLOCK and DATA float and the count wanders on its own.

Which pin is which

Knob side up, header at the bottom, reading left to right:

GNDto your board's GNDthe square pad: count from here
VCCto 3V3 or 5Vyour board's logic voltage
NCnothingnot connected on the board
BTNto a digital inputHIGH while the knob is pushed in
CLOCKto a digital inputrests HIGH, LOW while its contact is closed
DATAto a digital inputthe same, a quarter of a cycle away

The back prints TK06 ROTARY ENCODER and ROTATES TO PICK SETTINGS instead of pin names. Turned over, the square pad is on the right, and it is still GND.

Wiring, in five lines

  1. GND to your board's GND.
  2. VCC to 5V on an Uno, 3V3 on an ESP32, ESP32-S3 or Pico.
  3. CLOCK to D2 on an Uno, GPIO 25 on an ESP32, GPIO 4 on an ESP32-S3, GP13 on a Pico.
  4. DATA to D3 on an Uno, GPIO 26 on an ESP32, GPIO 5 on an ESP32-S3, GP14 on a Pico.
  5. BTN to D4 on an Uno, GPIO 27 on an ESP32, GPIO 6 on an ESP32-S3, GP15 on a Pico.

Leave NC unconnected. Set all three pins to INPUT: the pull-ups and the pull-down are already on the board.

Example

// CLOCK, DATA and BTN, as GPIO numbers.
// Uno: 2, 3, 4. ESP32: 25, 26, 27. ESP32-S3: 4, 5, 6. Pico: 13, 14, 15.
const int CLOCK_PIN = 4;
const int DATA_PIN = 5;

long count = 0;
int lastClock = HIGH;

void setup() {
  Serial.begin(115200);
  pinMode(CLOCK_PIN, INPUT);    // the block has its own pull-ups
  pinMode(DATA_PIN, INPUT);
}

void loop() {
  int clockLevel = digitalRead(CLOCK_PIN);
  if (clockLevel != lastClock) {
    if (clockLevel == LOW) {    // CLOCK has just fallen
      if (digitalRead(DATA_PIN) == HIGH) count++;   // CLOCK first
      else count--;                                 // DATA first
      Serial.println(count);
    }
    lastClock = clockLevel;
  }
}

If it counts down when you turn clockwise, swap count++ and count--.

The rotary encoder on an Arduino Uno

Where to start

The handbook below is ten short articles, each with a working figure. The first count is the whole build in five wires and a few lines.

If the count goes wrong when you turn the knob quickly, read why polling misses steps and then counting with an interrupt.

And before plugging it into an ESP32, VCC sets all three levels is the one page that protects the board.

When it doesn’t work

Does BTN read HIGH or LOW when pushed?
HIGH. The switch in the shaft joins BTN to VCC, and a 10 kΩ pull-down holds it at 0 V the rest of the time. Released reads LOW, pushed reads HIGH. Sketches written for encoder boards whose switch is pulled up test for LOW and get this block backwards.
INPUT or INPUT_PULLUP?
INPUT on all three pins. CLOCK and DATA already have 10 kΩ pull-ups on the board, and BTN has a pull-down that the chip's pull-up would fight. In MicroPython, Pin(pin, Pin.IN) with no pull argument.
Should VCC go to 3V3 or 5V?
To your board's logic voltage: 3V3 on an ESP32, ESP32-S3 or Pico, 5V on an Uno. CLOCK and DATA rest at VCC through their pull-ups, so 5V beside a 3.3 V board holds its pins past their rating the whole time, not only when you turn.
The count jumps around or goes backwards when I turn it fast.
The sketch is reading the pins too late: a delay() or a slow print in loop(). Count in an interrupt on CLOCK, or on both pins with a state table. On an Uno, CLOCK and DATA need to be on D2 and D3, its two external-interrupt pins.
It counts the wrong way.
Not a fault. Which contact leads when turned clockwise depends on the part. Swap the + and - in the sketch, or swap the CLOCK and DATA pin numbers.
One click gives two or four counts.
The sketch counts more edges than the part has clicks. Counting one fall of CLOCK per cycle gives one count a click on many EC11 parts; a state table counts four steps a cycle and divides by four. Turn one full turn and compare the count with the clicks you felt.
Do I need to add capacitors to the phases?
No. 100 nF from CLOCK and from DATA to GND is already fitted. With the 10 kΩ pull-ups that is a 1 ms filter that swallows the shortest bounces. It helps; a state table in the sketch deals with what gets past it.

The rotary encoder handbook

10 articles · about 50 minutes

This page is the reference: what the part is, what it is made of, and the questions people arrive already asking. The handbook is the walk — the same part in the order somebody actually meets it.

What is on the board

2 articles

Six pins of which five are wired, an EC11 encoder with a switch in its shaft, and the rule to learn before plugging it in: VCC sets the level of all three signals.

How a turn becomes two signals

2 articles

Two contacts that close a quarter of a cycle apart, the direction hidden in which one goes first, and the pull-ups and capacitors that turn them into clean levels.

Reading it

3 articles

Five wires and a sketch that counts clicks by watching CLOCK fall, the switch in the shaft that reads HIGH when pushed, and why the first sketch loses count when the loop gets slow.

Counting every click

3 articles

An interrupt that counts while loop() is busy, a state table that shrugs off bounce, and the short list of reasons a count goes wrong.

Lessons using TK06

Each one is a working build, not a snippet.

Edit this page — content/modules/rotary-encoder.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

Rotary Encoder

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum