Motion
Interfacing KY 040 Motion with Arduino Uno
What is the KY 040?
KY 040 practical reference
A rotary encoder with a push-button, widely used for volume knobs, menu navigation, and precise incremental control input.
Key specifications
- Type: Incremental mechanical rotary encoder with integrated momentary push-button
- Resolution: 20 detents (clicks) per full revolution, 20 pulses/rev quadrature output
- Output type: 2-bit quadrature (Gray code) on CLK/DT, direction derived from their phase relationship
- Operating voltage: 3.3V–5V DC
- Mechanical life: ~30,000 rotation cycles typical for this class of encoder
- Interface: Digital — 2 GPIO for rotation (CLK, DT) + 1 GPIO for the push-button (SW), no bus protocol
- Debounce requirement: Mechanical contacts bounce for a few ms on both rotation and button press — needs software or hardware debouncing
Pinout and connection notes
Decode direction from CLK+DT phase, not CLK alone — reading CLK by itself only tells you that the knob moved, not which way. Standard quadrature decoding compares the current and previous state of both CLK and DT to determine clockwise vs counter-clockwise.
Use an interrupt on CLK, not polling — polling in loop() is unreliable at typical rotation speeds and will miss steps. Attach a hardware interrupt (attachInterrupt) on the CLK pin and read DT's state inside the handler to catch every transition.
Debounce in software — mechanical contacts bounce for a few milliseconds; a naive interrupt handler will often register 2-4 counts per physical click. A simple time-based debounce (ignore transitions faster than ~1-5ms apart) or a state-machine decoder fixes this — don't rely on the raw interrupt count.
Direction feels backwards? Swap CLK/DT in code, not wiring — if clockwise rotation decreases your counter, it's almost always just a CLK/DT swap; flipping the two variable names in your decode logic is easier than re-wiring the module.
SW is a separate mechanical switch, not electrically related to the encoder — it needs its own pull-up (INPUT_PULLUP is fine) and its own debounce handling, independent of the rotation logic.
- GND: Ground
- +: Power, 3.3–5V DC
- SW: Push-button output — LOW when pressed (active LOW, needs pull-up if board doesn't include one)
- DT: Quadrature channel B — read alongside CLK to determine rotation direction
- CLK: Quadrature channel A — the primary channel to trigger an interrupt on for reliable counting
Integration checklist
- Confirm the exact part number and breakout-board revision.
- Verify supply voltage, current demand, logic levels, and signal direction against the datasheet.
- Check controller pin assignments and bus address or interface mode against the example code.
- Power up with external loads disconnected, then test signals before full integration.
- If readings or communication fail, check power and ground first, then pin mapping, interface settings, and library initialization.
Troubleshooting and reproducibility
Record the board used, wiring, library/version, supply arrangement, and measured behavior. Use the selected board-specific wiring example as the source of truth. Never assume visually similar modules share identical voltage tolerance or pin order.
Setting Up KY 040 with Arduino Uno
Library
Encoder by Paul Stoffregen (PJRC)
Arduino IDE → Tools → Manage Libraries → search "Encoder" by Paul Stoffregen → Install
Wiring
| Component pin | Arduino Uno pin | Note |
|---|---|---|
| + | 5V | |
| GND | GND | |
| CLK | D2 | Use an interrupt-capable pin for smooth reads. |
| DT | D3 | Use an interrupt-capable pin for smooth reads. |
| SW | D4 | Built-in pushbutton, active LOW — use INPUT_PULLUP. |
Swipe sideways to see every column →
- The Encoder library divides raw quadrature pulses by 4 in the sketch because the KY-040 detents produce 4 pulses per "click" — without that division every knob click reports as 4 separate steps.
- CLK and DT both benefit from being on interrupt pins (2 and 3 on the Uno) for reliable counting at speed; polling on non-interrupt pins can miss fast turns.
- Some KY-040 boards lack pull-up resistors on CLK/DT — if readings are erratic, add external 10kΩ pull-ups to 5V on both lines.
Related Components
Related Guides & Projects
Arduino Uno R4 Minima Pinout: Every GPIO, ADC, DAC, and Op-Amp Pin Explained
A complete Arduino Uno R4 Minima pinout reference — digital I/O, ADC, DAC, op-amp, CAN, dual UART, and exactly what it leaves out compared to the WiFi variant.
Mastering PWM on Arduino: Dimming LEDs and Controlling Motors
Understand what PWM actually is on Arduino, dim an LED smoothly, and safely control a DC motor's speed with a driver chip -- plus the mistakes (like wiring a motor straight to a pin) that damage boards.
4-Digit 7-Segment Counter with TM1637 & Arduino
Drive a TM1637-based 4-digit 7-segment display with Arduino Uno to show a real-time up/down counter, elapsed timer, and scrolling text. Covers library setup, brightness control, and custom segment mapping.
Arduino Uno R4 Minima vs WiFi: Which One Should You Choose?
Same processor, same memory, different price. Here's what the WiFi variant's extra hardware actually gets you, and when the Minima is the smarter buy.