tutorialspinouttools
Sensors · ESP32-C3

KY-040 on OLED: Rotary Encoder Counter

Free ESP32 & Arduino tutorial · wiring, code & parts · gokul.builds

Overview & Wiring

What it is: The KY-040 is a rotary encoder — a knob you can turn endlessly in either direction, plus a built-in push button. It's the input device for menus, volume controls and setting values. How it works: Turning the knob produces two square waves (CLK and DT) 90° out of phase. By checking DT at the moment CLK changes, you know the direction. The shaft also presses down as a button (SW). All digital. Wiring: KY-040 CLK -> GPIO10 KY-040 DT -> GPIO6 KY-040 SW -> GPIO7 (push button) KY-040 + -> 3V3 KY-040 GND -> GND OLED VCC=3V3, GND=GND, SDA=GPIO4, SCL=GPIO5 Libraries: only "Adafruit SSD1306" and "Adafruit GFX Library". On screen / Serial: a counter that goes up when you turn one way and down the other. Press the knob to reset to 0. Gotchas: Cheap encoders bounce; this sketch reads on the CLK falling edge to reduce it, but for heavy use add small capacitors or use an interrupt-based library. The internal button needs a pull-up (enabled in code).

Circuit Diagram

KY-040 on OLED: Rotary Encoder Counter wiring diagram for ESP32-C3

Parts You Need

ESP32-C3 SuperMiniBuy →
0.96" SSD1306 OLEDBuy →

Source Code (Arduino / ESP32)

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(128, 64, &Wire, -1);

#define CLK 10
#define DT  6
#define SW  7
long counter = 0;
int lastClk;

void setup() {
  Serial.begin(115200);
  Wire.begin(4, 5);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  pinMode(CLK, INPUT);
  pinMode(DT, INPUT);
  pinMode(SW, INPUT_PULLUP);                   // button active-LOW
  lastClk = digitalRead(CLK);
}

void loop() {
  int clk = digitalRead(CLK);
  if (clk != lastClk && clk == LOW) {          // falling edge of CLK
    if (digitalRead(DT) != clk) counter++;      // DT leads -> clockwise
    else counter--;
    Serial.printf("Count: %ld\n", counter);
  }
  lastClk = clk;

  if (digitalRead(SW) == LOW) { counter = 0; }  // press resets

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println("KY-040 Encoder");
  display.setTextSize(3);
  display.setCursor(0, 26);
  display.printf("%ld", counter);
  display.display();
}
Browse all tutorials ESP32-C3 pinout Calculators