3.3 KiB
Rotary Dial
ESP32 firmware that reads a pulse-generating telephone rotary dial and publishes the dialled number to Home Assistant over MQTT.
Built on the ESP32 Device Framework.
How it works
A classic rotary telephone dial generates a burst of pulses as it returns to rest after each digit — one pulse for 1, two for 2, …, nine for 9, ten for 0. The firmware counts those pulses on a single GPIO pin and assembles digits into a string. When the user stops dialling (2.5 s silence), the complete number is published to MQTT.
Leading zeros are preserved: dialling 07 sends "07", not "7".
Hardware
| Item | Details |
|---|---|
| MCU | ESP32 (any variant) |
| Dial | Pulse-generating rotary telephone dial |
| Pulse pin | GPIO 4 (DIAL_PIN in main.cpp) |
| Wiring | Pulse contact between GPIO 4 and GND. Pin uses INPUT_PULLUP. |
The pulse contact is normally open. As the dial returns it briefly shorts GPIO 4 to GND on each pulse — the rising edge (release) is what the interrupt counts.
If your dial's contact is normally closed instead, change the interrupt trigger in setup() from RISING to FALLING.
Building and flashing
# Build (S3 DevKit)
pio run -e esp32-s3-devkitc-1
# Flash
pio run -e esp32-s3-devkitc-1 --target upload
# Serial monitor (115200 baud)
pio device monitor
First-time Wi-Fi setup
On first boot the device opens an access point named Rotary-Dial. Connect with any phone or laptop; a captive portal will appear.
- Enter your Wi-Fi credentials.
- Optionally set the Device hostname (default:
rotary-dial). - Save. The device joins your network and restarts.
Reachable at http://rotary-dial.local or the IP shown in the serial monitor.
Factory reset
Power-cycle or press EN 5 times in quick succession (before boot completes). All settings are cleared and the device restarts into the Wi-Fi portal.
Web UI
Browse to the device address to configure hostname, authentication, and MQTT.
MQTT
Topics
| Direction | Topic | Description |
|---|---|---|
| Published | <prefix>/dialed |
Complete dialled number as a string (not retained) |
| Published | <prefix>/status |
online on connect, offline as LWT (retained) |
Default prefix: dial
Home Assistant
On MQTT connect the device publishes a discovery payload so HA automatically creates a sensor entity (sensor.<hostname>_dialed_number) that shows the last dialled number.
Example automation:
automation:
- alias: Act on dialled number
trigger:
platform: mqtt
topic: dial/dialed
action:
- choose:
- conditions:
- condition: template
value_template: "{{ trigger.payload == '112' }}"
sequence:
- service: notify.mobile_app
data:
message: "Emergency number dialled!"
Timing constants
Adjust in main.cpp if your dial runs faster or slower than standard:
| Constant | Default | Description |
|---|---|---|
PULSE_DEBOUNCE_MS |
15 ms | Minimum time between counted edges |
INTER_PULSE_MS |
350 ms | Silence after last pulse = digit complete |
INTER_DIGIT_MS |
2500 ms | Silence after last digit = number complete |