On Tue, Mar 30, 2010 at 9:57 PM, Olin Lathrop w= rote: > The recent discussion on DTMF decoding made me think about a project I had > been considering for a while. =A0I did some simulations to verify my math= was > right and look at filter time constants and the like. > > You can see the result at http://www.embedinc.com/temp/dtmf.gif. =A0The i= nput > is bursts of the DTMF tones 697, 770, and 853 Hz. =A0Each burst and the g= aps > between the bursts are 50mS long, which is the time you are supposed to be > able to detect a DTMF tone within. =A0The blue trace is the square of the > magnitude of the detected tone. =A0The algorithm was set up to detect 770= Hz, > which is the frequency of the center burst. > > As you can see, this worked very well. =A0The blue trace would have event= ually > reached 1.0 if the center burst persisted. =A0But clearly the center burs= t was > well detected and the other two were not, even though the frequencies > between adjacent tones differ by less than 11%. > > Below is the core code of the simulation. =A0The complete code contains t= oo > many distractions to show here, like CSV file writing and other logistics. > > =A0for sampn :=3D 0 to nsamp do begin =A0 =A0 {once for each input sample} > =A0 =A0t :=3D sampn * sampdt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 {make time of t= his sample} > =A0 =A0samp :=3D getsamp (t); =A0 =A0 =A0 =A0 =A0 =A0 =A0 {get input samp= le} > =A0 =A0r :=3D t * freq; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {make ref= erence frequency phase} > =A0 =A0ii :=3D trunc(r); > =A0 =A0r :=3D r - ii; > =A0 =A0r :=3D r * pi2; > =A0 =A0prods :=3D samp * sin(r); =A0 =A0 =A0 =A0 =A0 =A0{mix by ref freq = sine and cosine} > =A0 =A0prodc :=3D samp * cos(r); > =A0 =A0filter (filts, prods); =A0 =A0 =A0 =A0 =A0 =A0 {low pass filter mi= xer results} > =A0 =A0filter (filtc, prodc); > =A0 =A0magsq :=3D sqr(filts.val) + sqr(filtc.val); {make square of magnit= ude} > =A0 =A0magsq :=3D magsq * 4.0; =A0 =A0 =A0 =A0 =A0 =A0 =A0{normalize} > > Obviously you wouldn't normalize the result in the PIC, you'd adjust the > detection threshold instead. =A0The FILTER subroutine does a two pole low= pass > filter. =A0Each pole has a filter fraction of 1/128, which means it can be > realized inside a PIC with a right shift of 7 bits. =A0The input was samp= led > and processed every 100uS. > > > ******************************************************************** > Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products > (978) 742-9014. =A0Gold level PIC consultants since 2000. > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > Very nice! Some questions for the details: - filter() looks something like 1/128 * getsamp(t) + 1/128 * getsamp(t - sampdt) ? Or is it an IIR filter? - What is the trunc() bit? A peculiarity of the arcane language (I'm guessing fortran) you're using? Thanks, - Marcel -- = http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist