I have been trying to apply Goertzel's algorithm to DTMF decoding on my launchpad. I have applied the algorithm successfully in octave to see that it works. However, when I try the same in my launchpad (MSP430G2553) - I do not get the expected results.
Is the problem because of the sampling rate? I have set the sampling rate to near 7kHz. Or am I doing something wrong in multiplication and division of floating point numbers.
I have attached my code below. For simplicity, I have attached the code for only one frequency signal - which also doesn't work.
My OCTAVE Code:
y = wavread("one.wav"); //DTMF signal for 1 Sampling rate - 8000Hz
i=1000; //Starting from the 1000th sample
Q2=0;
Q1=0;
while i<1206 //Applying goertzel's algorithm for 205 samples
Q0 =ceil( y(i) + 1.708*Q1 - Q2) //1.708 is the coeff. for 697Hz signal
Q2 = Q1
Q1 = Q0
i++
endwhile
mag1 = Q2*Q2 + Q1*Q1 - 1.7077*Q1*Q2 //If mag1 is above a threshold - 697Hz frequency is present in the signal
//Similarly applying Goertzel's algorithm for few other frequencies
i=1000
Q2=0
Q1=0
while i<1206
Q0 =ceil( y(i) + 1.646*Q1 - Q2)//
Q2 = Q1
Q1 = Q0
i++
endwhile
mag2 = Q2*Q2 + Q1*Q1 - 1.646*Q1*Q2
i=1000
Q2=0
Q1=0
while i<1206
Q0 =ceil( y(i) + 1.569*Q1 - Q2)
Q2 = Q1
Q1 = Q0
i++
endwhile
mag3 = Q2*Q2 + Q1*Q1 - 1.569*Q1*Q2
i=1000
Q2=0
Q1=0
while i<1206
Q0 = ceil(y(i) + 1.479*Q1 - Q2)
Q2 = Q1
Q1 = Q0
i++
endwhile
mag4 = Q2*Q2 + Q1*Q1 - 1.479*Q1*Q2
My LAUNCHPAD code:
#include "msp430g2553.h"
#define threshold 1000
void main ( void )
{
double Q2, Q1, Q0, mag, temp,coeff;
int i,j;
WDTCTL = WDTPW | WDTHOLD ; // Stop watchdog
P1DIR = BIT0 + BIT6; // both leds in output mode
P1SEL |= BIT1; // P1.1 in ADC channel mode
P1OUT = 0x00;
coeff = 1.56;
ADC10CTL0 = SREF_0 | ADC10SHT_3 | ADC10ON ;
// VCC and VSS refs , sample for 64 cycs , int ref off , ADC on , no ints
ADC10CTL1 = INCH_1 | SHS_0 | ADC10DIV_1 | ADC10SSEL_3 | CONSEQ_0 ;
// Input channel 1 , trigger using ADC10SC bit , clock division by 2,
//internal ADC clock , single channel single conversions
ADC10AE0 = BIT1 ; // Enable analog input on channel 1
ADC10CTL0|=ENC; // Enable conversions
for (;;) // Loop forever taking measurements
{
Q2 = 0;
Q1 = 0;
for(i=0; i<206; i++)
{
ADC10CTL0|=ADC10SC; // Trigger new conversion
while ( ADC10CTL1 & ADC10BUSY) { nop(); } // Loop while conversion takes place
temp = ADC10MEM;
Q0 = ((temp*3.3)/200) + (coeff*Q1) - Q2;
Q2 = Q1;
Q1 = Q0;
}
mag = Q2*Q2 + Q1*Q1 - (coeff*Q1*Q2);
if (mag>=threshold)
{
P1OUT |= BIT0;
for(j=0;j<30000;j++){nop();}
P1OUT &= ~BIT0;
}
else
{
P1OUT |= BIT6;
for(j=0;j<30000;j++){nop();}
P1OUT &= ~BIT6;
}
}
}
When the octave code is run for DTMF signal '1' - it gives 500 times more value for mag1 than other magnitudes (mag2, mag3 and mag4) - showing the presence of 697Hz signal.
My launchpad code doesn't seem to work that way.
Any help would be welcome.