Detecting DTMF tones from scratch

If you’ve ever wondered about the best way to detect dial and DTMF tones from a phone line, [Debraj] is your man.

[Debraj] built a DTMF detector using the Goertzel algorithm. Normally, when we think about detecting tones, we pull FFT out of our bag of tricks. The Goertzel algorithm isn’t as computationally complex as FFT and can be implemented on even the smallest microcontrollers.

For the build, the first thing to solder is a nice audio transformer and some protection diodes. The ring tone from a phone line goes from +35 V to -35 V – a bit more than a microcontroller could handle. A PIC18F4520 dev board was used as the brain of the system with all the code is available on [Debraj]’s site.

Although implementations of the Goertzel algorithm are a little uncommon, [Debraj] has seen a few interesting projects using this technique. [Debraj]’s build could easily be modified into a guitar tuner with a few changes in the code, for example.

This project was built as the command and control for a home automation system and from the video after the break, we can’t wait for [Debraj] to get annoyed at the phrase, “To turn on the kitchen lights, please press 1…”

9 thoughts on “Detecting DTMF tones from scratch

  1. The Goertzel algorithm isn’t as computationally complex as FFT

    Well, not exactly. If you need all the frequency bins, the FFT is the most efficient implementation. However, if you only need a small number of frequency bins (as in the case of DTMF detection), then the Goertzel algorithm can be computationally less intensive since you’re not computing the entire spectrum.

  2. The second harmonic detection logic can be reserved for those times when a single row and a single column frequency have already been detected. It need not run all the time.

    As noted in the article, the 2nd harmonic check is used for rejecting voice signals. I like to turn that around and check that the DTMF frequency is not a second harmonic of a voice signal. In other words, rather than looking for 697 && !1394, I look for 697 & !348.5Hz. It seems a little more robust.

    Another check that is frequently done is the “twist” test. If a row freq and a column freq are both present, their magnitudes need to be “close” to one another. If the twist test fails, there is no need to check the harmonic (or fundamental, as the case may be).

    Another trick to reduce average processing bandwidth is to run the three (or four, if desired) column frequency tests first, and then only run the row frequencies if only one of the columns was detected. If more than one were detected, you needn’t do anymore work to reject the tone.

    Also… it might not be necessary to divide the result by 256 at the end, because you’re not really interested in absolute magnitudes – only relative magnitudes. If both frequencies are scaled by the same number (256) then the relationship is unaltered.

    Yeah… I’ve done a bit of DTMF detection with Mr Goertzel’s algorithm in the past.

  3. wouldn’t a simpler solution just involve an FM tuner, some ttl and a demux? DTMF is just 7 (or really 8) harmonic formants, right? so tune at all four row frequencies, and return the column/row that matches with one of the 16 (12) known tones. what am i missing?

  4. Now you know why you saved that box full of old crappy $5 winmodems; for the 600 ohm xformers.

    Oh, that was just me? Never mind.

    1. I searched and could never get the older modems here in India. So I had to settle by purchasing the new ones from online stores..

  5. On the microcontroller board there are white blocks holding wires. Where can I buy those at?

    I’ve got a rs232 to usb which has pins but I need some way to attach wires to that without soldering them. In addition, attach wires to the jumper block of a 2.5 inch laptop hard drive.


  6. I myself would stick with a simple 75T202/203 and interface to a processor freeing the processor to do other things.

    But its kinda neat to see what can be done if there were not cheap decoders already on the market.

  7. hey Debraj,

    anychance you could implement this into arduino code. I took a look at your code, but it is certainly way over my head. At least in terms of porting it to an arduino. I would very much appreciate it if you could take a whack at it. Impressive work, btw.

  8. I’m doing my project for DTMF but I’m using 7 segment to display when I push the button and also I’m using Arduino board could I use the same code you used

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s