Dual-Tone Multi-Frequency (DTMF) is a telephone signaling scheme in which each keypad symbol is represented by the simultaneous transmission of two sinusoidal tones, one chosen from a low-frequency group (697, 770, 852, 941 Hz) and one from a high-frequency group (1209, 1336, 1477, 1633 Hz). The combination of the two tones uniquely identifies one of 16 symbols (digits 0-9, *, #, and the rarely used A-D column) in standard implementations.
In practice
In embedded systems, DTMF generation is straightforward: two sinusoids at the appropriate frequencies are summed and fed to a DAC or a PWM output driving an audio path. On resource-constrained MCUs, the tones are often produced using pre-computed sine tables with a phase accumulator per tone. On parts with a hardware DAC and DMA (such as STM32 or Kinetis series), the CPU is largely free during transmission.
DTMF detection is more demanding than generation. The standard approach is the Goertzel algorithm, which efficiently computes a single DFT term recursively without performing a full FFT, making it practical for evaluating energy at specific frequencies. Running eight Goertzel filters in parallel (one per DTMF frequency) over a block of 102 to 205 samples at 8 kHz is typical and fits comfortably on a Cortex-M4 or even a Cortex-M0+. The post "DFT Bin Value Formulas for Pure Real Tones" is useful background for understanding how tone amplitude relates to Goertzel output magnitude.
A common pitfall is choosing a block size that does not land a DTMF frequency close to a Goertzel bin center. Because the Goertzel algorithm evaluates the DFT at a fixed coefficient computed from the target frequency, the analysis is still valid for any block size, but leakage from off-bin energy grows as the ratio of tone frequency to bin spacing worsens. Designers typically choose block sizes (N) such that N * f_tone / f_sample is close to an integer. At 8 kHz sampling, N = 205 is a widely used compromise that yields acceptable leakage and latency, though not all tones land especially close to exact DFT-bin centers at that rate.
Robustness requirements in practice include handling talk-off (voice audio falsely decoded as a digit), level variation across the two tones (the TIA-968 standard allows up to 4 dB twist), and rejecting harmonics. Production decoders often add a second-harmonic energy check: if harmonic bin energy exceeds a threshold relative to the fundamental (the exact criterion varies by implementation), the detection is suppressed. Timing constraints also matter; TIA-968 specifies minimum tone duration of 40 ms and inter-digit gaps of 40 ms as a broadly cited baseline, though specific timing requirements can vary by signaling context and acceptance criteria, so the detection window and holdoff logic must be designed accordingly.
Discussed on DSPRelated
Frequently asked
Why is the Goertzel algorithm preferred over an FFT for DTMF detection?
DTMF detection requires only 8 specific frequency bins out of hundreds. Computing a full
FFT to obtain 8 values wastes cycles and memory. The
Goertzel algorithm computes the
DFT magnitude at a single frequency using a second-order
IIR filter with O(N) multiplications, making it 5 to 10 times cheaper than a comparably sized FFT when only a handful of bins are needed.
What sample rate and block size should I use for DTMF detection?
8 kHz is the conventional
sample rate, matching voice telephony. A block size of N = 205 samples (about 25.6 ms) is widely cited as a practical compromise between latency and spectral leakage at that rate; the bin spacing is roughly 39 Hz, and the actual tone-to-bin mismatch varies by tone but is generally kept to an acceptable level for reliable detection. Smaller blocks (e.g., N = 102) reduce latency but increase leakage and reduce frequency resolution.
How do I generate DTMF tones on a microcontroller without a floating-point unit?
The most common approach is a
phase-accumulator per tone combined with a fixed-point sine lookup table. Each sample, the phase accumulator is incremented by a step size proportional to the tone frequency, the table is indexed to retrieve the sine value, and the two tone values are summed and scaled before output. This requires only integer adds and a table lookup per sample, making it practical on 8-bit and 16-bit MCUs as well as Cortex-M0 parts.
What is 'twist' in DTMF, and why does it matter?
Twist is the amplitude difference in dB between the high-frequency and low-frequency tone of a DTMF pair. TIA-968 allows up to 4 dB of normal twist (high tone louder) and 8 dB of reverse twist (low tone louder). A detector that assumes equal amplitudes will miss valid signals from phones that apply pre-emphasis or from audio paths with frequency-dependent loss. Detection thresholds should be designed to accept signals within the specified twist range.
Can DTMF be decoded in real time on a small MCU like a Cortex-M0+?
Yes, for a single audio channel. Eight Goertzel filters over a 205-sample block at 8 kHz require roughly 8 * 205 = 1640 multiply-accumulate operations per block, or about 64,000 MACs per second. A Cortex-M0+ at 48 MHz has ample headroom for this workload, leaving the processor mostly available for other tasks. Fixed-point implementation is advisable since M0+ cores lack an FPU.
Differentiators vs similar concepts
DTMF is sometimes confused with FSK (Frequency-Shift Keying), which is also used in telephony (e.g., for caller ID transmission between rings in the Bell 202 format). FSK encodes data by switching between two frequencies at different times; only one frequency is present at any moment. DTMF always transmits two frequencies simultaneously and is designed for in-band human-dialed signaling rather than continuous data transfer. DTMF is also distinct from MF (Multi-Frequency) signaling used in older inter-office trunk signaling (R1/R2 systems), which uses a different set of tone pairs and is not intended for end-user equipment.