100 lines
3.3 KiB
Markdown
100 lines
3.3 KiB
Markdown
# 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](../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
|
|
|
|
```bash
|
|
# 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.
|
|
|
|
1. Enter your Wi-Fi credentials.
|
|
2. Optionally set the **Device hostname** (default: `rotary-dial`).
|
|
3. 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:
|
|
|
|
```yaml
|
|
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 |
|