This build turns a rotary encoder into a dimmer switch for an LED on an ESP32. Instead of hardcoding brightness in your sketch, you turn a knob and watch analogWrite() respond in real time, a nice way to get a feel for how encoders report direction through two digital pins.

The full tutorial, with every detail and the line-by-line code explanation, is on our site: ESP32 - Rotary Encoder LED

What you need

Wiring

ESP32 - Rotary Encoder LED wiring diagram

The rotary encoder has three signal pins: CLK goes to GPIO25, DT goes to GPIO26, and SW (the built-in push button) goes to GPIO27, though this sketch doesn't use the button. The LED connects through a 220Ω resistor to GPIO22, which limits current so the LED doesn't burn out. If you'd rather skip the resistor and wiring fuss, an LED module with a built-in resistor works as a drop-in replacement.

How it works

A rotary encoder has two internal switches, CLK and DT, that toggle as you turn the knob. The order in which they change tells you the direction of rotation: if DT is already HIGH when CLK goes HIGH, you're turning counter-clockwise, otherwise it's clockwise. The code watches for that CLK transition and uses it as a trigger to check DT and decide which way the knob moved. Each detected step nudges a brightness value up or down by 10, clamped between 0 and 255, and that value is written straight to the LED.

Code

The sketch stores the previous state of CLK and compares it each loop to the current reading, acting only on the rising edge so a single detent doesn't get counted twice. Based on the direction, it adjusts a brightness variable, clamps it to the valid analogWrite() range, and sends it to the LED pin. It also logs the counter and brightness to the serial monitor, so you can watch the values change as you turn the knob.

esp32-rotary-encoder-led.ino

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-rotary-encoder-led */ #include <ESP32Servo.h>  #define CLK_PIN 25 // ESP32 pin GPIO25 connected to the rotary encoder's CLK pin #define DT_PIN 26 // ESP32 pin GPIO26 connected to the rotary encoder's DT pin #define SW_PIN 27 // ESP32 pin GPIO27 connected to the rotary encoder's SW pin #define LED_PIN 22 // ESP32 pin GPIO22 connected to the LED  #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction  int counter = 0; int direction = DIRECTION_CW; int CLK_state; int prev_CLK_state; int brightness = 125; // middle value void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); // read the initial state of the rotary encoder's CLK pin prev_CLK_state = digitalRead(CLK_PIN); pinMode(LED_PIN, OUTPUT); } void loop() { // read the current state of the rotary encoder's CLK pin CLK_state = digitalRead(CLK_PIN); // If the state of CLK is changed, then pulse occurred // React to only the rising edge (from LOW to HIGH) to avoid double count if (CLK_state != prev_CLK_state && CLK_state == HIGH) { // if the DT state is HIGH // the encoder is rotating in counter-clockwise direction => decrease the counter if (digitalRead(DT_PIN) == HIGH) { direction = DIRECTION_CCW; counter--; brightness -= 10; // you can change this value } else { // the encoder is rotating in clockwise direction => increase the counter direction = DIRECTION_CW; counter++; brightness += 10; // you can change this value } if (brightness < 0) brightness = 0; else if (brightness > 255) brightness = 255; // sets the brightness of LED according to the counter analogWrite(LED_PIN, brightness); Serial.print("COUNTER: "); Serial.print(counter); Serial.print(" | BRIGHTNESS: "); Serial.println(brightness); } // save last CLK state prev_CLK_state = CLK_state; } 

Things that go wrong

If turning the knob does nothing, double-check that CLK and DT are on GPIO25 and GPIO26 and not swapped, since swapping them just reverses the direction logic rather than breaking it outright. If the counter jumps by two instead of one per click, you're likely seeing both edges of the signal rather than just the rising edge. If the LED never lights up at all, check the 220Ω resistor and the polarity of the LED itself.

Full tutorial

The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: https://esp32io.com/tutorials/esp32-rotary-encoder-led