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 name | RotaryEncoder |
|---|---|
| Author | Matthias Hertel |
| Include | #include <RotaryEncoder.h> |
| Boards | every board Mokxi compiles for |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | Rotary 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.
#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
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.
Keep going
Try RotaryEncoder without installing anything
Open the example, change the sketch, and keep your version in a free account.