DTMF decoder library

DTMF.cpp gets compile errors for me. I use the current version of the 'arduino' package from the Fedora 'updates' repository on Fedora 20. Perhaps something has changed in the avr-gcc compiler. I get error message:
unable to find a register to spill in class 'POINTER_REGS'
The line causing the error is:
dtmf_mag = sqrt(Q1Q1 + Q2Q2 - coeffQ1_Q2);
I fixed the problem by splitting up this expression into 3 lines:
float tmp;

tmp = Q1*Q1 + Q2Q2;
tmp = tmp - coeff*Q1Q2;

dtmf_mag = sqrt(tmp);
Griff_

Pete, it is possible that your library can decode CTCSS tone? this guy make something that : Private Site
but this radio can't read DTMF tone or i made a mistake ?

The library is specifically designed to decode the 8 DTMF tones. Decoding CTCSS tones is much more difficult because in some cases they are less than 3Hz apart whereas the DTMF tones are at least 70Hz apart.
If you were aiming to decode only a few of the tones and could choose a few that were much further apart, it can be done, but trying to decode all of them is probably impossible on an Arduino without external hardware.

Pete

When I try to compile the example dtmf_test I get the following and some more error-messages:

C:\Users\Peter\Documents\Arduino\libraries\DTMF\DTMF.cpp: In member function 'void DTMF::detect(float*, int)':

C:\Users\Peter\Documents\Arduino\libraries\DTMF\DTMF.cpp:179:1: error: unable to find a register to spill in class 'POINTER_REGS'

Arduino: 1.6.1 (Windows 7), Platine: "Arduino Uno"

Has anyone an idea how to fix this?

The code compiles with Arduino version 1.0.6 but it appears that there is a bug of some sort in the compiler in versions 1.6.0 and 1.6.1 - probably related to the -Os flag.
I have a workaround. Replace the entire DTMF:detect function in the DTMF.cpp library file with this:

// return the magnitudes of the 8 DTMF frequencies
void DTMF::detect(float dtmf_mag[],int adc_centre)
{
  int index;
  float d_tmp;

  /* Process the samples. */
  for (index = 0; index < N; index++)
  {
    ProcessSample(testData[index],adc_centre);
  }
  // Calculate the magnitude of each tone.
  for(int i=0;i < 8;i++) {
// El_Supremo 150318 the compilers in Arduino verisons 1.6.0 and 1.6.1
// generated "unable to find a register to spill" error in the original statement
// here. Breaking it into pieces worked around the problem.
//     dtmf_mag[i] = sqrt(Q1[i]*Q1[i] + Q2[i]*Q2[i] - coeff[i]*Q1[i]*Q2[i]);

  	// This is the equivalent of sqrt(real*real + imag*imag)
  	d_tmp = Q1[i]*Q1[i];
  	d_tmp += Q2[i]*Q2[i];
  	d_tmp -= coeff[i]*Q1[i]*Q2[i];

    dtmf_mag[i] = sqrt(d_tmp);
  }
  ResetDTMF();
}

I didn't notice/remember the report of the same problem in message #24 by griff2a until after I'd found a fix. My first attempt at splitting up the statement was similar to his but it didn't help so I had to split it even further.

Let me know if this works for you. I will update the link to the library.

Pete

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

Pete

Everything works fine now. Thank You !!!

el_supremo:
I've uploaded the updated version to http://members.shaw.ca/el.supremo/DTMF.zip.

Pete

Hey Pete,

The above link seems to be pointing to the previous version... still the same detect function.

rob

Hi Rob,
Thanks for the heads up. I've uploaded the correct version this time.

Pete

I realized the wrong link by myself. Thanks to everybody. My application, the detection of given 4 alarmtones between 580 and 820 Hz, works very fine!

Hey everybody,

I'm so glad this DTMF library exists. To add to the posted code in this thread. Any ideas on how to select 2 or 4 dtmf tones sequentially to flip the LED on?

I'm looking for:

if(thischar == '55') {
digitalWrite(led, HIGH);
}

Or:

if(thischar == '55AB') {
digitalWrite(led, HIGH);
}

I'm thinking of having a counter that counts until 2 or 4. Once the count gets up to 2 or 4, 'thischar' would be reset to 0. I'm having trouble expressing that as code that works.

Thanks!

Hi Everybody,

I am trying to make a simple comminicator by landline which will use DTMF signals on both sides problem is , I am looking for detecting the Line busy, Call in process , other party didnt answer , Does any one can help me how to make this or which IC. can be used or is there any other way to make.

Best Regards

Hi Pete,

When I tried "Verify" of the "dtmf_test.ino"

I get this error message:

Arduino: 1.6.5 (Windows 8.1), Board: "Arduino Uno"

C:\Program Files (x86)\Arduino\libraries\DTMF\DTMF.cpp: In member function 'void DTMF::detect(float*, int)':
C:\Program Files (x86)\Arduino\libraries\DTMF\DTMF.cpp:179:1: error: unable to find a register to spill in class 'POINTER_REGS'
}
^
C:\Program Files (x86)\Arduino\libraries\DTMF\DTMF.cpp:179:1: error: this is the insn:
(insn 42 40 44 6 (set (reg:SF 50 [ D.4208 ])
(mem:SF (post_inc:HI (reg:HI 63 [ ivtmp.118 ])) [2 MEM[base: _50, offset: 0B]+0 S4 A8])) C:\Program Files (x86)\Arduino\libraries\DTMF\DTMF.cpp:175 99 {*movsf}
(expr_list:REG_INC (reg:HI 63 [ ivtmp.118 ])
(nil)))
C:\Program Files (x86)\Arduino\libraries\DTMF\DTMF.cpp:179: confused by earlier errors, bailing out
Error compiling.

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.

Do I need to have the arduino uno plugged in and running the program? I thought "verify" would compile without.

Thanks,
Emerson

See messages 24, 28 and 29 in this thread. Let me know if that doesn't help.

Pete

Hi, I would like to use the keypad cellphone near the microphone to recognize the tones, what kind of microphone do you suggest?

edit:

Electret Microphone Amplifier - MAX4466 with Adjustable Gain - Electret Microphone Amplifier - MAX4466 with Adjustable Gain : ID 1063 : $6.95 : Adafruit Industries, Unique & fun DIY electronics and kits

Electret Microphone Amplifier - MAX9814 with Auto Gain Control - Electret Microphone Amplifier - MAX9814 with Auto Gain Control : ID 1713 : $7.95 : Adafruit Industries, Unique & fun DIY electronics and kits

or another in aliexpress ?

hi

my arduino keeps reading the DTMF decoder outputs as high, what might be the problem

hello from Argentina, I am a rookie, you can use Arduino Uno 328 and Dtmf Dt8870 to use as joystick pc

Yes, of course.
Use Google: Arduino USB Joystick, there is a lot of info.

Oh, so painful seeing floating point... so slow, times 7 tones!

You also need some relative signal strength comparisons and handling dropouts and other timing issues that occur in real-world reception of DTMF tones in the presence of noise and interference.

Here, use this if you must stay on 8 bit AVR.

If you have a 32-bit Teensy 3.x, I wrote a much better version is available in the audio library.

Hello, el_supremo . Please tell me whether it is possible to work your library with ATmega8 internal clock 8MHz ?