Arduino library 路 Input

RotaryEncoder: a KY-040 knob with latch modes

RotaryEncoder, by Matthias Hertel (also the author of OneButton), reads a quadrature knob by polling: your sketch calls encoder.tick() and the library looks at both pins, works out whether the knob moved and updates a position. Nothing about it needs interrupt pins, so it works on any two digital or analog pins, including A2 and A3 as its examples use.

Built in on Mokxi: #include <RotaryEncoder.h> and it builds, with nothing to install. Free, and no account needed.

What RotaryEncoder does

Its distinguishing feature is the latch mode, which matches the position to the clicks you feel. Encoders differ in where their detents sit in the quadrature cycle: LatchMode::FOUR3 and FOUR0 count once per full cycle, and TWO03 counts twice, which suits many KY-040 modules. With the right mode, one click is one step.

Polling means loop() must call tick() often, or turns are lost. When loop() has slow work in it, call tick() from a pin change interrupt on both pins instead, and the position stays right.

Library Manager nameRotaryEncoder
AuthorMatthias Hertel
Include#include <RotaryEncoder.h>
Boardsevery board Mokxi compiles for
In the simulatorSimulated: it runs against the part the way it does on the bench.
Parts it drivesRotary encoder, KY-040

Install it

It builds on every board Mokxi compiles for.

In Mokxi it is built in: #include <RotaryEncoder.h> and the sketch compiles, with no download, no zip and no Library Manager.

On a real board, install "RotaryEncoder" by Matthias Hertel from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add RotaryEncoder to lib_deps in PlatformIO. Mokxi follows the calls of release 1.6.0, so a sketch written here builds there too.

ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 ATtiny85 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi

The calls you will use

In the order a sketch meets them.

RotaryEncoder encoder(A2, A3, RotaryEncoder::LatchMode::TWO03)

The knob on two pins and the latch mode that matches its clicks. The pins get their pull-ups at the first tick().

encoder.tick()

Reads both pins and updates the position. Call it on every pass of loop(), or from an interrupt.

encoder.getPosition()

The position in steps, positive one way and negative the other.

encoder.tick();
int now = encoder.getPosition();
if (now != pos) {
  pos = now;
  Serial.println(pos);
}

encoder.getDirection()

Which way the last movement went: RotaryEncoder::Direction::CLOCKWISE, COUNTERCLOCKWISE or NOROTATION.

encoder.setPosition(0)

Sets the position, for example to clamp a menu index or reset to zero.

encoder.getRPM()

An estimate of turning speed from the time between steps, useful for speeding up a value when the knob is spun fast.

Example: Count the clicks of a rotary encoder

On the Arduino Uno R3. It runs in the browser exactly as printed.

sketch.ino 路 Arduino Uno R3
#include <RotaryEncoder.h>

// DT, then CLK: turned clockwise it counts up. A KY-040 detent is a whole
// cycle of the two signals, which FOUR3 counts as one.
RotaryEncoder encoder(3, 2, RotaryEncoder::LatchMode::FOUR3);

void setup() {
  Serial.begin(9600);
  Serial.println("SimplePollRotator");
}

void loop() {
  static int pos = 0;
  encoder.tick();
  int newPos = encoder.getPosition();
  if (pos != newPos) {
    Serial.print("pos:");
    Serial.print(newPos);
    Serial.print(" dir:");
    Serial.println((int)(encoder.getDirection()));
    pos = newPos;
  }
}

Wiring

  • Arduino Uno R3 2 to Rotary encoder, KY-040 CLK
  • Arduino Uno R3 3 to Rotary encoder, KY-040 DT
  • Arduino Uno R3 5V to Rotary encoder, KY-040 VCC
  • Arduino Uno R3 GND to Rotary encoder, KY-040 GND

Open it in the editor, wired and ready to run

Common errors and how to fix them

The position changes by two for each click, or only every other click

The latch mode does not match the encoder. Try LatchMode::TWO03, FOUR0 and FOUR3 in turn until one click moves the position by exactly one.

Turns are missed while the sketch updates a display

tick() is not called while the display code runs. Attach a pin change interrupt to both encoder pins and call encoder.tick() from it, as the library鈥檚 InterruptRotator example does.

Clockwise counts down

Swap the two pin numbers in the constructor, or swap the CLK and DT wires on the module.

Try RotaryEncoder without installing anything

Open the example, change the sketch, and keep your version in a free account.