Is EC11 Rotary Encoder with Push Button Compatible with Home Assistant (ESPHome)?
Electrical Specifications
Always confirm pin assignments against the manufacturer datasheet before wiring.
Compatibility Overview
Quadrature rotary knob encoder for manual media volume adjustment light dimming control or menu navigation interfaces.
Wiring EC11 Rotary Encoder with Push Button to ESP32
| Module pin | ESP32 | Note |
|---|---|---|
| A | GPIO32 | A bare EC11 has no pull-up resistors, so the config switches on the ESP32's internal pull-up for this pin. |
| B | GPIO33 | Pulled up the same way as A. Swap the two pins in the YAML if the count runs the wrong way. |
| C (common) | GND | A and B are two contacts that close to this pin, so a pulled-up input reads low while its contact is closed. |
| Switch, first pin | GPIO25 | The config enables the internal pull-up and inverts the pin, so a press reads as on. |
| Switch, second pin | GND | |
| + (breakout boards only) | 3V3 | A bare encoder has no supply pin. On a module the + pin feeds its pull-up resistors, and those lines go straight into the ESP32, so use 3V3 and never 5V. |
Host pins are the ones the configuration on this page uses. Move a pin here and change it in the YAML — they are documented together so they cannot disagree.
Technical Specification Matrix
| Feature / Attribute | Specification / Status |
|---|---|
| Hardware Protocol | Quadrature GPIO / 3.3V |
| Bridge Required | NO |
| Border Router Needed | None |
| Hardware Capabilities & Peripherals | Encoder Position Encoder Button Note: these entities come from the ESPHome configuration you flash — each one needs its matching component in that YAML before it appears. |
| Pairing Complexity | Plug-and-Play |
| Factory Reset Instruction | Hold BOOT button for 3s. |
Wire, Flash, Adopt, Check
Wire it up
Follow the wiring table above. The ESP32 pins there are the ones the configuration uses, so if you move one, change it in both places.
Flash the configuration
Create a new device in the ESPHome dashboard (the Home Assistant add-on) and paste the configuration below into it, or save it as emb_esp32_ec11_esphome.yaml and run esphome run emb_esp32_ec11_esphome.yaml. The first flash goes over USB. If it is not detected, hold BOOT button for 3s to put it in download mode. Every update after that is over the air.
Adopt it in Home Assistant
Settings → Devices & Services. A node on the same network shows up as a discovered ESPHome device within a minute of joining Wi-Fi; choose Configure and enter the API encryption key from your secrets.yaml. If discovery does not find it, add the ESPHome integration by hand with the node's IP address.
Check it works
The log shows a new Encoder Position value at each step, rising one way and falling the other, and pressing the shaft turns Encoder Button on and off again. A count that drifts or jumps while nobody touches the knob means A and B are floating — usually a pin moved to one without an internal pull-up. A count that moves only every second click is resolution: 1 on a 30-detent part, and a count that runs backwards means A and B are swapped. A button that never turns on is wired to 3V3 instead of GND.
ESPHome Configuration
Starting configuration for EC11 Rotary Encoder with Push Button on ESP32. Untested on hardware — verify wiring and pins against your own board.
# ESPHome configuration for EC11 Rotary Encoder with Push Button
# Host: ESP32. Pin numbers below are host-side defaults — any free
# GPIO will do, and you should change them to match your own wiring.
esphome:
name: emb_esp32_ec11_esphome
friendly_name: "EC11 Rotary Encoder with Push Button"
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# A bare EC11 is two contacts to ground with no resistors, and
# rotary_encoder enables no pull-ups of its own: without these, A and B
# float whenever a contact opens and the count wanders.
sensor:
- platform: rotary_encoder
name: "Encoder Position"
pin_a:
number: GPIO32
mode:
input: true
pullup: true
pin_b:
number: GPIO33
mode:
input: true
pullup: true
binary_sensor:
- platform: gpio
name: "Encoder Button"
pin:
number: GPIO25
mode:
input: true
pullup: true
inverted: true
Before you flash:
the !secret values come from your
secrets.yaml, and the GPIO numbers are host-side
defaults rather than properties of this part — change them to match how you actually wired it.
What Appears in Home Assistant
A running count in steps: up one way, down the other, with no limit in either direction until you set min_value and max_value. It is kept across reboots, because restore_mode defaults to RESTORE_DEFAULT_ZERO.
On while the shaft is pressed in. On the node, on_multi_click can separate single, double and long presses.
Not in the config. The position is only a number; to turn a light up or down, call homeassistant.action from on_clockwise and on_anticlockwise. Tick "Allow the device to perform Home Assistant actions" in the ESPHome integration options first, or Home Assistant will not run the calls.
Known Problems and Fixes
Pull-ups on A and B
rotary_encoder does not switch pull-ups on by itself, which is why the config asks for them on GPIO32 and GPIO33. Without them a bare EC11's lines float whenever a contact is open, and the count creeps or jumps with nobody touching the knob. The internal pull-ups are weak, so on a long cable out to a panel add 10kΩ resistors to 3V3 as well. GPIO34 to GPIO39 are a poor choice for an encoder, because they have no internal pull-ups at all.
Clicks are not pulses
Alps sells the EC11E with 15 pulses and 30 detents, for example, which is one full quadrature cycle for every two clicks. At the default resolution: 1, ESPHome counts once per cycle, so the position changes on every second click. resolution: 2 gives one count per click on those parts; on an encoder with as many pulses as detents, leave it at 1.
Contacts bounce
These are mechanical wipers, and Alps allows a few milliseconds of chatter and suggests an RC filter on each output. The quadrature decoding cancels most bounce out, because a chattering contact counts forward and straight back. The push switch has no such protection; a delayed_on filter of a few tens of milliseconds on Encoder Button stops one press arriving as two.
Give a dial its limits
Without min_value and max_value the count carries on past 100 and below zero, which is no use as a volume or brightness level. Set both. on_clockwise and on_anticlockwise still fire at the limits, which is what relative dimming needs.
Every step is a state
Each step publishes a new value, so a quick spin sends a burst of states to Home Assistant and into its history. Handle a knob that drives something on the node itself locally; for one that only reports, a throttle or delta filter on the sensor keeps the history readable.
Only the ESP32's own pins
The encoder is decoded in an interrupt handler, so pin_a and pin_b must be native GPIOs. A pin on an MCP23017 or PCF8574 expander is rejected. The push switch is an ordinary binary_sensor and has no such restriction.
Report a Pinout Error or Submit Tested Code Snippets
Found a pin mapping quirk or built a custom ESPHome YAML driver for EC11 Rotary Encoder with Push Button? Submit a pull request or report corrections to our index.
Hardware Correction Reporter (emb-esp32-ec11-esphome)
Frequently Asked Questions
Does EC11 Rotary Encoder with Push Button work without an internet connection?
How is EC11 Rotary Encoder with Push Button powered and wired to the host board?
How does the host board reach Home Assistant (ESPHome)?
Alternatives
KY-040 Rotary Encoder Module
A detented encoder on a small board with 10kΩ pull-ups already fitted on CLK and DT, so the floating-line problem does not arise.
AS5600 12-bit Magnetic Rotary Encoder
A magnetic angle sensor: no contacts to wear or bounce, and it knows the shaft angle within a turn after a power cut. No clicks, so it feels like a smooth knob.
Moes Wireless Zigbee Smart Scene Knob
A finished battery-powered Zigbee knob, if what you want is a dimmer on the wall rather than a panel you build.
TTP223 Capacitive Touch Button Module
A capacitive touch pad that works behind glass or plastic, when a button is needed and a knob is not.