DTMF decoder library

I have modified the Goertzel algorithm implementation here:

so that it can be used to detect DTMF tones. The new version, like the original, is not interrupt driven.
It is provided AS IS for you to play with.
There are two sample audio files in the zip which, when the windows audio is turned up full, the sample code detects with no errors.
There is also a circuit diagram of how I connected the audio from the computer's headphone output to the Arduino's analog Pin 0. Use at your own risk.
Unzip the attached file into your libraries directory.

UPDATED 2016/12/19. I've attached the most recent version of the library to this message. Later messages (#6, #29) had a link to the zip file but those links will die soon - my ISP is withdrawing the webspace service.
Also, see message #42 for a link to another DTMF library. I haven't tried it but it is probably better than this one.

Pete

DTMF.zip (43.3 KB)

1 Like

So, I took a look and it works beautifully. Their are 2 things I have questions about though. The tone length is very strict. If the tone is too short it wont work and if it plays too long it will put print the number multiple times. Is their any chance you could make it modifiable? Also, the goertzel algorithm is supposed to compensate for magnitude on its own. Is there anyway to account for that?

Again, great job and thanks for your help!

Moose

SexualMoose:
So, I took a look and it works beautifully. Their are 2 things I have questions about though. The tone length is very strict. If the tone is too short it wont work and if it plays too long it will put print the number multiple times. Is their any chance you could make it modifiable? Also, the goertzel algorithm is supposed to compensate for magnitude on its own. Is there anyway to account for that?

Again, great job and thanks for your help!

Moose

I believe the official (original ATT specs?) DTMF specs for minimum recognition time (shortest tone period) for a valid digit is around 40 msec if I recall correctly. Decoding multiple repeated digits for a single tone of any length sounds like just a 'feature' of the library. :wink:

The tone length is very strict. If the tone is too short it wont work

How short a tone are you trying? The dialabc example uses 50ms tones. The example code uses a sample length of 128 which means that a sample block is 14 milliseconds long. It should have 3 good blocks in one 50ms tone and might detect tones down to around 30ms - I haven't tried that. You could try making the sample length shorter (try 64) so that the algorithm samples the tone more times. If you do that, you'll have to reduce the threshold amplitude as well.

and if it plays too long it will put print the number multiple times.

When the code detects a tone it won't return it again until it sees something that is not a tone. If for any reason the amplitude drops a bit to just below the threshold it can think it has seen the end of the tone when there's actually still more to come. Try lowering the threshold amplitude just a bit.

Is their any chance you could make it modifiable?

Make what modifiable?

Also, the goertzel algorithm is supposed to compensate for magnitude on its own.

I saw one implementation which divided the resulting magnitude by the number of samples. I don't know if that's actually part of the Goertzel algorithm itself.
I'll play with it in the next day or so.

Again, great job and thanks for your help!

You're welcome :wink:

Pete

Also, the goertzel algorithm is supposed to compensate for magnitude on its own.

This can be done without changing the library.
The dtmf_test sketch originally had this code:

  dtmf.detect(d_mags,512);

  thischar = dtmf.button(d_mags,1800);

Change it to this:

  dtmf.detect(d_mags,512);
  
  for(int i = 0;i < 8;i++) {
    d_mags[i] /= n;
  }
  
  thischar = dtmf.button(d_mags,20.);

The "for" loop normalizes the magnitudes. I determined the threshold value of 20 empirically but it works for values of n from 55 up to 160 when using either of the sample audio files.
I prefer to leave this outside the library but if you want to build it in, in the method DTMF::detect change this statement:

    dtmf_mag[i] = sqrt(Q1[i]*Q1[i] + Q2[i]*Q2[i] - coeff[i]*Q1[i]*Q2[i]);

to this:

    dtmf_mag[i] = sqrt(Q1[i]*Q1[i] + Q2[i]*Q2[i] - coeff[i]*Q1[i]*Q2[i])/N;

Pete

is there a way to make the link alive again?

The most recent version of the library is attached to the first message in this thread.

Pete

Hi Pete

thanks for the new link, but i fail to understand how the code work .
i dont have any expriance in arduino but i want to give it a shot....

as described i built the neccesery cirucit and connected it to my audio output of my pc.
when i upload the code to my (MEGA2560) i dont see any feedback from the circuit exept from when i opening the serial monitor and the led on pin 13 go ON. i tried to open the serial monitor
put it on 115200 baud and wait and see the detction working but its seems to do nothing.

how can i adavnce and make it work (sorry for my bad english)
my audio output in full volume and my divider is on 512 please help.

hi i have an update its working.
is there a way that can i decode 6 inputs in parallel?

The code could be modified to handle six inputs but it would slow down the sampling rate quite substantially which would change the characteristics of the detection.
A better way to handle the audio sampling is to use a timer interrupt and do the detection on-the-fly but in either case you would probably need a faster processor to handle six channels.

Pete

I have an issue with the detection of the DTMF tones. When I try with audio archives through my computer, I have no problem, but when I connect my phone, nothing is detected. I don´t know why.

What I have in mind is to connect one phone to my arduino board, with voicemail active, then if there is an incoming call, the voice mail pick up the call and because of this is allowed to dial the tones. For example 001 wich turns on the heating.

But without detection through my mobile I am blocked, what can I do?

Thanks for your help in advanced

bowline77:
I have an issue with the detection of the DTMF tones. When I try with audio archives through my computer, I have no problem, but when I connect my phone, nothing is detected. I don´t know why.

What I have in mind is to connect one phone to my arduino board, with voicemail active, then if there is an incoming call, the voice mail pick up the call and because of this is allowed to dial the tones. For example 001 wich turns on the heating.

But without detection through my mobile I am blocked, what can I do?

Thanks for your help in advanced

You would probably have to show us how you are attempting to connect to your telephone line. Actually most countries/telephone companies have laws and rules about how equipment can be wired to the local subscribers loop, as it's a balance line and you are not free to ground either the tip or ring wire. Normally equipment manufactures use approved chips/modules/components to do such electrical interfacing to the line called DAA modules. These usually involve a 600 ohm 1:1 transformer as well as ring detection/protection components. Keep in mind that the ring voltage when your phone rings is a 90 VAC 20Hz signal that can easily blow up components wired directly to the phone pair.

So I would suggest you do a little goggling for telephone interfacing circuits to see what you should be using.

Lefty

I have used El_supremo offered drawing and I connected a mobile phone with the audio jack so I don´t have the issue of a landline connetion (this is another point that I want to check out)

Thaks for your help

audio_1.gif

corolla9:
hi i have an update its working.
is there a way that can i decode 6 inputs in parallel?

el_supremo:
The code could be modified to handle six inputs but it would slow down the sampling rate quite substantially which would change the characteristics of the detection.
A better way to handle the audio sampling is to use a timer interrupt and do the detection on-the-fly but in either case you would probably need a faster processor to handle six channels.

Pete

Parallax Propeller could decode to 7 parallel channels with little external circuitry & leaving one of the COG's for serial back to an arduino.. A propeller chip (P8X32A) has 32 I/O, fully digital, analog input can be accomplished via sigma-delta conversion. There are actually 8 separate MCU's called cog's inside of one chip, this is how the propeller can do real-time parallel processing

There is an IC part# MT8870. It is a DTMF decoder that will provide a Data Valid signal and 4 bit binary output. all it requires is about 100 MV of clean audio, 5 V and a 3.58 MHz color burst crystal.
Here is a link from "Futurlec"that " appears to do a great deal.. and cheaper too @$12.98..

MT8870 DTMF Receiver Mini Board.

Bob

i did buy 6 of these chips $6 ea. haven't tried them yet but im sure they will work fine.

Hi,
I'm trying to use el_supremo's DTMF library. No matter what I do, I can't get a reading/signal from it.
I am wiring up the handset output of my telephone with this schematic:

Taken from: https://coolarduino.files.wordpress.com/2011/02/dc_bias11.png
I know this circuit is working because other libraries that do different things correctly analyze the audio.

Is there something I need to change? I would prefer not to by a DTMF Decoder.

Which other libraries, what do they do?

Pete

This is a basic speech recognition software: GitHub - arjo129/uSpeech: Speech recognition toolkit for the arduino. It worked great.
This gave a response, but because it can only detect one tone at once, it didn't work: GitHub - jacobrosenthal/Goertzel: Arduino Library implementation of the Goertzel algorithm

Hello,

Works very well for me to display the code on the computer.

For cons, I can not seem to use a DTMF to turn an LED on output.

How to make the LED lights up when you press the button 5.

thank you