Two-Buttons Handwheel From Industrial Encoder
by tuenhidiy in Circuits > Raspberry Pi
106 Views, 0 Favorites, 0 Comments
Two-Buttons Handwheel From Industrial Encoder



Rotary encoders are versatile input devices that can enhance your smart home setup by providing tactile control over Home Assistant or CNC applications (e.g, CNC Pendant Handwheel). Whether you want to adjust volume, brightness, thermostat control or scroll through menus, a DIY rotary encoder is an affordable and customizable solution. In this guide, we’ll walk through how to build your own a big handwheel with push buttons from 24VDC high precision industrial encoder and integrate it into the Home Assistant.
Please watch my video before getting started.
Supplies
First of all, I would like to sincerely thank Waveshare for the sponsoring and supporting me on this project. Waveshare is a leading global provider of electronic components and modules for a wide range of industries, including robotics, IoT, education, and more. With a focus on quality, reliability, and innovation, Waveshare has become a trusted partner for engineers, designers, and makers around the world.
To build a DIY big handwheel, I need the following components:
✅ 1pcs x 24VDC Industrial Incremental Encoder.
✅ 1pcs x ESP8266 or ESP32.
✅ 1pcs x Raspberry Pi 4B or Raspberry Pi 5.
✅ 1pcs x LCD Touch Screen (Optional for Raspberry Pi OS).
✅ 1pcs x ULN2803 (Option: Optocoupler (e.g., PC817) or Voltage Divider Resistors)
✅ 1pcs x Slip-ring (4 wires).
✅ 1pcs x 24VDC Power Supply for Encoder.
✅ 1pcs x Step-Down Switching Regulator LM2596 or 3.3V/5V Power Supply for ESP8266.
✅ 1pcs x Double-sided PCB 50x70mm for Converter Board.
✅ 1pcs x Double-sided PCB 70x90mm for ESP8266.
✅ 2pcs x Push Buttons.
✅ 10pcs x Resistor 1kΩ.
✅ 10pcs x Resistor 10kΩ.
✅ 20pcs x 2 Pin 2.54mm Pitch Screw Terminal Block.
✅ PVC fittings:
- 2pcs x PVC Endcap Ø114.
- 2pcs x PVC Elbow Ø21 (45 degree).
- 2pcs x PVC Tee Ø21.
- 2pcs x PVC Endcap Ø21.
- 1pcs x PVC Reducer Ø27 to Ø21.
Safety Notes
⚠️ Safety Note
Industrial encoders often run at 24V, while microcontrollers (ESP8266, ESP32, Arduino or Raspberry Pi) operate at 3.3V or 5V. Connecting a 24V signal directly will destroy your microcontroller! You must use one of these methods:
✅ Optocoupler Isolation (Best for Noise Immunity).
✅ Voltage Divider (Simple, but less robust).
✅ Level Shifter (For clean signal conversion).
Checking Malfunctioning Encoder
I have collected some big broken encoders with 80mm outer diameter, which were mounted to motor shafts in my factory and they did not function properly when the production line run at high speeds and high temperatures.
They were stored in the broken equipment shelf and will be discarded one day. When their bearings are not broken and they can be turned by hand, I always had the feeling that they could be salvaged to make some useful devices. So I decided to check them and to my delight, there were some encoders among them that could be reused. And here's how I tested the operation of an industrial encoder:
✅ I powered it with 24VDC then rotated it clockwise/counterclockwise by hand several times and measured the waveforms at channel A and B with an Oscilloscope. If everything is OK, their waveform looks like image below with encoder's channel A (yellow line) and channel B (pink line).
✅ As we can see, the signals at encoder's channel A and B are square pulse-shaped with 24VDC peak. A pink line (channel B) is shifted by 90 electrical degrees (°e) with relative to yellow line (channel A). This phase shift is used to determine the direction of rotation. For example, if my encoder rotates clockwise, channel A leads channel B and vice versa.
✅ As the above figure show, I have rotated my encoder clockwise.
Converter Schematic

Industrial rotary encoders (e.g., incremental encoders from Baumer, Omron, Sick, or IFM) are robust and precise, making them great for professional applications. However, integrating a 24VDC encoder with Home Assistant requires additional circuitry to interface safely with a microcontroller (ESP8266, ESP32, Arduino or Raspberry Pi, etc.). For most cases, the PC817 optocouplers are selected due to better noise immunity. But in my case, I used an ULN2803 Darlington array to interface my 24VDC encoder with an ESP8266, but with some important considerations. Here's how to implement it properly:
✅ Pull-up resistors adding to converter circuit, I used resistors 10kΩ.
✅ The ULN2803 is current-sinking (open-collector output), which means it inverts the signal. So we need to compensate for inversion in software. Note: The ULN2803 inverts signals (active-high 24V → active-low 3.3V).
✅ Ensure clean grounding because it is not optoisolated (unlike PC817), so ground loops could be an issue in noisy environments. We can add 0.1µF capacitors near ULN2803 power pins if signals are noisy.
Here below is my circuit schematic:
I added 2 push buttons, one is used for resetting encoder counter to zero or default value and one is used to confirm encoder counter value after rotating to expected position, for example.
In Fritzing schematic, label GPIOs with (Inverted) to remind me to set inverted: true in ESPHome later.
Voltage Thresholds:
✅ ULN2803 input handles up to 30V, perfect for 24V encoders.
✅ Output sinks up to 500mA for ULN2803, but ESP8266 only needs ~12mA.
Soldering Converter Board
I soldered all components: ULN2803, 1kΩ & 10kΩ resistors, screw terminals onto a double-sided PCB 50x70mm , following the schematic in the previous step.
✅ Top view:
✅ Bottom view:
Then I tested the encoder signals at 2 conversion voltages: 24/5VDC and 24/3.3VDC. As you can see in the figure below (24/5VDC conversion in this case), the original channel A signal (pink line - 24VDC peak) and the converted channel A signal (yellow line - 5VDC peak) are completely inverted with each other.
Handwheel Assembly
Firstly, I mounted encoder to a PVC endcap Ø114mm. My encoder has a through-bore or hollow bore design. This kind of encoder enables to measure the rotational movement of the motor shaft directly, without the need for couplings or other intermediate components. These encoders can be used with various shaft diameters by using interchangeable bore adaptors or shaft adaptors. In my case, inner bore diameter is 26mm and outer diameter is slightly bigger than 27mm.
Since the encoder's outer bore diameter is slightly bigger than 27mm, it fits tightly with the Ø27mm diameter PVC pipe fitting.
And I came up with the idea of making my own a handwheel like the picture below, it had 2 push buttons at both ends, assembled from some PVC Ø21 fittings and a reducer from Ø27 to Ø21mm. This PVC reducer on the Ø27mm side will be connected to encoder later.
Because the push buttons and their wires were located on the handwheel - a rotating part, I had to use a slip ring mechanism. Electric slip rings are used to transmit power or electrical signals from a stationary to a rotating part of a system and vice versa.
I made the PVC base for slip ring mounting. My slip ring has diameter Ø12.5mm, rated speed 200rpm and 4 wires. So I can use 3 push buttons on the rotating part.
A stationary part of slip ring was mounted to PVC bottom base.
Do wiring, connecting the wires from slip ring to push buttons.
A small PVC connector Ø21mm was installed inside encoder bore hole to keep the slip-ring wires from falling into the bore hole's grooves and causing breakage.
Mounting hand wheel to encoder bore hole. It's very tight without needing additional bolts to hold it in place.
My Home Assistant
I built my own DIN rail mounting support and preparing some necessary boards for my Home Assistant system. I connected encoder wires to the DIN terminals and converter board, then wired to ESP8266 as schematic on previous step.
I also installed Home Assistant Supervised on a Raspberry Pi 4 running Raspberry Pi OS.
Home Assistant Integration
I installed the ESPHome Device Builder in Home Assistant. The ESPHome web UI will present a wizard that guided me through creating my own configuration and installed this custom firmware to the system, named "rotary_encoder".
As mentioned, the encoder channel A and B signals were inverted in the ESPHome YAML configuration file, via the command "inverted: true"
For precise control I had to reduce the resolution in ESPHome because the encoder was too sensitive if I used its original resolution at 4096 PPR. I used ESPHome's filtering to reduce sensitivity as following:
My DIY rotary encoder finally is intergrated and shown on the Home Assistant dashboard. Now as I rotate the encoder, it changes from 0 to 100 with acceptable sensitivity, and I can scale it to any value I want.
Besides, I can reset any encoder's position value to zero or preset it to a default value when pressing the reset button, for example, sets volume to 50%, or temperature to 25°C. To preset the desired values, we can separate the reset pin from the rotary encoder and declare it as a binary sensor in Home Assistant (same as confirm button config).
Conclusion






A D.I.Y rotary encoder is a simple yet powerful way to add physical controls to Home Assistant or CNC Application. With ESPHome or Arduino, you can customize it for any smart home function or MPG (Manual Pulse Generator) CNC Pendant Handwheel. Whether for lighting, media, or climate control, this project offers a good tactile and responsive interface.
Thank you for reading my works!!!