Show Posts
Pages: [1]
1  Using Arduino / Audio / Re: DTMF decoder library on: September 05, 2012, 08:49:52 pm
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
2  Using Arduino / Programming Questions / Re: Goertzel for reliable DTMF Decoding on: September 02, 2012, 08:02:27 pm
Alright thank you, I'll take a whack at it tonight. I'm at work currently so I won't be able to test it until around midnight.

3  Using Arduino / Programming Questions / Re: Goertzel for reliable DTMF Decoding on: September 02, 2012, 06:58:18 pm

I do not want a hardware solution. I already have a perfectly working hardware solution and I am now looking to eliminate it all together. Thanks for your help!


I appreciate the help, but I really just want to get a functional Goertzel algorithm coded. Finalized, the code shouldn't take more than 50 lines of code. I just don't understand the math well enough to lay it out. I understand the steps, the flowchart, and a small amount of the math. I just need some one, who understands the math, to copy the equations and the lay them out like shown in the flow chart as seen here http://www.ti.com/lit/an/spra066/spra066.pdf. Even if the arduino can't sample at 9000, I believe I can adjust the sample rate and "N" later.

Also, Pete, I would really like to know how you monitored the frequency at which it took a sample. That would help immensely, as i would need to adjust it after I implemented it into another batch of code I'm currently working on. The other code shouldn't consume much and I only need to sample at >3300Hz.
4  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 02, 2012, 06:23:27 pm
Are you using the modified code or the original?

Can you post your code for recording the frequency?

Also I don't believe you can just change the sampling rate without changing "N".
5  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 02, 2012, 06:01:21 pm
I'm not 100% sure what you are asking, I believe the sampling code is in the goertzel.cpp and it happens at the analogRead(0);
6  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 02, 2012, 05:19:06 pm
Literally all I need is the formula(s) in order and the inputs labeled so I know where to put them. I am able to modify parts but understanding the whole thing is beyond me. I do know that the basic modified equations still apply if you change N to 115 and the sample rate to 9000
7  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 02, 2012, 05:08:38 pm
While yes, the formula was modified for that chip, the formula should still be sound if you change the sample rate to 9000 and "N" to 115
8  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 02, 2012, 04:58:34 pm
Alright so I made a few changes and made a little progress. It provides predictable results and is accurate to some degree. I found a couple errors in his code and then started making equation adjustments along the way. Since I'm rather poor at math I used this document http://www.ti.com/lit/an/spra066/spra066.pdf to help a tad and just tweaked things to as close of a reading as possible.

Here is the .ino
Code:
/*
  Blinks a light on a 16mhz Arduino when it detects an A4 (440 hz), tone
 the tuning fork pitch and something easily generated by the Tone library
  or a google search.

  The Goertzel algorithm is long standing so see
  http://en.wikipedia.org/wiki/Goertzel_algorithm for a full description.
  It is often used in DTMF tone detection as an alternative to the Fast
  Fourier Transform because it is quick with low overheard because it
  is only searching for a single frequency rather than showing the
  occurrence of all frequencies.
 
  This work is entirely based on the Kevin Banks code found at
  http://www.eetimes.com/design/embedded/4024443/The-Goertzel-Algorithm
  so full credit to him for his generic implementation and breakdown. I've
  simply massaged it into an Arduino library. I recommend reading his article
  for a full description of whats going on behind the scenes.

  Created by Jacob Rosenthal, June 20, 2012.
  Released into the public domain.
*/


/*
Crudely Revised By: SexualMoose
Frequencies generated by iPhone/iPod at full volume
Frequencies are found in a 80Hz range proportional to the target.
When looking for 697 Frequency recognition starts ~70Hz below target and stop about ~10Hz above
this range shifts down proportional to the increase in the target frequency
i.e. when looking for 1633 its starts ~1480Hz and ends ~1560Hz
*/
#include <Goertzel.h>

int sensorPin = 0;
int led = 13;

float target_freq=1633.0; //must be an integer of 9000/N and be less than
                         //sampling_frequency/2 (thanks to Nyquist)
float n=115.0;
float sampling_freq=9000;

Goertzel goertzel = Goertzel(target_freq,n,sampling_freq);

void setup(){
  pinMode(led, OUTPUT);     
  Serial.begin(9600);
}

void loop()
{
  delay(10);
  sensorPin = analogRead(0);
  Serial.println(sensorPin);
  goertzel.sample(sensorPin); //Will take n samples
 
  float magnitude = goertzel.detect();  //check them for target_freq
 
  if(magnitude>1000) //if you're getting false hits or no hits adjust this
    digitalWrite(led, HIGH); //if found, enable led
  else
    digitalWrite(led, LOW); //if not found, or lost, disable led
   
  Serial.println(magnitude);
}

Here is the Goertzel.cpp
Code:
/*
  The Goertzel algorithm is long standing so see
  http://en.wikipedia.org/wiki/Goertzel_algorithm for a full description.
  It is often used in DTMF tone detection as an alternative to the Fast
  Fourier Transform because it is quick with low overheard because it
  is only searching for a single frequency rather than showing the
  occurrence of all frequencies.

  This work is entirely based on the Kevin Banks code found at
  http://www.eetimes.com/design/embedded/4024443/The-Goertzel-Algorithm
  so full credit to him for his generic implementation and breakdown. I've
  simply massaged it into an Arduino library. I recommend reading his article
  for a full description of whats going on behind the scenes.

  Created by Jacob Rosenthal, June 20, 2012.
  Released into the public domain.
*/
// include core Wiring API
#include "Arduino.h"

// include this library's description file
#include "Goertzel.h"

float SAMPLING_RATE;
float TARGET;
float N;
float coeff;
float Q1;
float Q2;
float sine;
float cosine;

byte testData[160];

Goertzel::Goertzel(float TARGET_FREQUENCY, float BLOCK)
{
#if F_CPU == 16000000L
Goertzel(TARGET_FREQUENCY, BLOCK, 9000.0);
#else
Goertzel(TARGET_FREQUENCY, BLOCK, 9000.0);
#endif
}

Goertzel::Goertzel(float TARGET_FREQUENCY,float BLOCK,float SAMPLING_FREQ)
{

  SAMPLING_RATE=SAMPLING_FREQ; //on 16mhz, ~8928.57142857143, on 8mhz ~44444
  TARGET=TARGET_FREQUENCY; //must be integer of SAMPLING_RATE/N
  N=BLOCK; //Block size
  int k;
  float omega;

  k = (int) (N * (TARGET_FREQUENCY / SAMPLING_RATE) + 0.93);
  omega = (2.0 * PI * k) / N;
  sine = sin(omega);
  cosine = cos(omega);
  coeff = 2.0 * cosine;

  ResetGoertzel();
}


/* Call this routine before every "block" (size=N) of samples. */
void Goertzel::ResetGoertzel(void)
{
  Q2 = 0;
  Q1 = 0;
}


/* Call this routine for every sample. */
void Goertzel::ProcessSample(byte sample)
{
  float Q0;
  Q0 = coeff * Q1 - Q2 + (float) sample;
  Q2 = Q1;
  Q1 = Q0;
}


/* Basic Goertzel */
/* Call this routine after every block to get the complex result. */
void Goertzel::GetRealImag(float *realPart, float *imagPart)
{
  *realPart = (Q1 - Q2 * cosine);
  *imagPart = (Q2 * sine);
}


/* Sample some test data. */
void Goertzel::sample(int sensorPin)
{
  for (int index = 0; index < N; index++)
  {
    testData[index] = (byte) analogRead(0);
  }
}


float Goertzel::detect()
{

  int index;

  float magnitudeSquared;
  float magnitude;
  float real;
  float imag;

  /* Process the samples. */
  for (index = 0; index < N; index++)
  {
    ProcessSample(testData[index]);
  }

  /* Do the "standard Goertzel" processing. */
  GetRealImag(&real, &imag);

  magnitudeSquared = real*real + imag*imag;
  magnitude = (sqrt(magnitudeSquared)/2);

  ResetGoertzel();
  return magnitude;
}


And here is a link to test out the modified library:
https://www.dropbox.com/sh/9lmbik1v6k1tgt3/Wl2xlBTypU


Here's what I'd like to do:
I need help turning the equations in this document into arduino  code http://www.ti.com/lit/an/spra066/spra066.pdf. If anyone could help me out with that I'd super appreciate it. It doesn't have to be much, just a frame work so I know where to put the variables. Thanks for your help!
9  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 02, 2012, 10:52:01 am
Yup that's my problem too. Well, if anyone else has any ideas or even another library, let me know. Thanks for giving it a try pete !
10  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 01, 2012, 11:30:35 pm
Any suggestions on how to modify it to work? This is obviously not my code and the math is beyond me. So, if you have any suggestions or alternatives, let me know.

Thank you
11  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 01, 2012, 04:41:37 pm
On a Duemilanove or UNO pin 13 has a resistor and led on the board, but I added a brighter LED because the one on the board is rather dim and hard to see. The pin directly above it is ground. http://www.arduino.cc/en/Tutorial/BlinkingLED

As stated in my last post I already fixed the audio connection to follow this suggested schematic http://coolarduino.wordpress.com/2012/06/22/audio-input-to-arduino/ You'd be hard pressed to damage an analog input with audio out.

Even with the volume at max an iphone/ipod wont put out more than ~3volts which would max out the reading somewhere around 613.8.

The code and the library were posted in the first post via a link. I figured that would be more appropriate because you need the library to test the code anyway.
Here is the code anyway:
Code:
/*
  Blinks a light on a 16mhz Arduino when it detects an A4 (440 hz), tone
 the tuning fork pitch and something easily generated by the Tone library
  or a google search.

  The Goertzel algorithm is long standing so see
  http://en.wikipedia.org/wiki/Goertzel_algorithm for a full description.
  It is often used in DTMF tone detection as an alternative to the Fast
  Fourier Transform because it is quick with low overheard because it
  is only searching for a single frequency rather than showing the
  occurrence of all frequencies.
 
  This work is entirely based on the Kevin Banks code found at
  http://www.eetimes.com/design/embedded/4024443/The-Goertzel-Algorithm
  so full credit to him for his generic implementation and breakdown. I've
  simply massaged it into an Arduino library. I recommend reading his article
  for a full description of whats going on behind the scenes.

  Created by Jacob Rosenthal, June 20, 2012.
  Released into the public domain.
*/
#include <Goertzel.h>

int sensorPin = A0;
int led = 13;

float target_freq=440.0; //must be an integer of 9000/N and be less than
                         //sampling_frequency/2 (thanks to Nyquist)
float n=20.0;
float sampling_freq=9000.0;

Goertzel goertzel = Goertzel(target_freq,n,sampling_freq);

void setup(){
  pinMode(led, OUTPUT);     
  Serial.begin(9600);
}

void loop()
{
  goertzel.sample(sensorPin); //Will take n samples
 
  float magnitude = goertzel.detect();  //check them for target_freq
 
  if(magnitude>1000) //if you're getting false hits or no hits adjust this
    digitalWrite(led, HIGH); //if found, enable led
  else
    digitalWrite(led, LOW); //if not found, or lost, disable led
   
  Serial.println(magnitude);
}
12  Using Arduino / Programming Questions / Re: Goertzel or FFT for reliable DTMF Decoding on: September 01, 2012, 02:53:22 pm
I did, indeed, forget that you cannot simply wire up ground to analog an expect results, but I fail to see how I may have cause damage. Analog is a 0 to 5 volt input. In a rather oversimplified way, if it accepts a +5v input then connecting it to a ground or audio out shouldn't harm it. Analog is an input. So, its not going to short out with ground and a headphone jack is only going to put out a maximum ~3volts and a couple milliamps. So, unless I'm missing something (which is totally possible), no damage should occur.

Also after wiring it up correctly, with a different arduino(in case I damaged it smiley-razz), the results were exactly the same. Nothing happens unless you lower the magnitude and then the LED fires in +/-100hz ranges that are no where near the target range.

Also, I'm confused on how to use the FFT Library you linked me to. It only provides 2 examples and one requires a codec shield. The other one only outputs data in binary form. How would I go about getting a frequency as a number or getting it to recognize certain frequencies?

Again, thanks for you help.
13  Using Arduino / Programming Questions / Goertzel for reliable DTMF Decoding on: September 01, 2012, 01:37:26 am
I've been looking all over the web for a simple Arduino library for the implementation of either Goertzel or FFT. My goal is to use something like this to decode DTMF tones reliably. The closest thing I could find was this https://github.com/jacobrosenthal/Goertzel. I attempted to use the library example, but the results were less than perfect. I put an LED between digital 13 and the ground right above it. Then I plugged the headphone out from my iphone into A0 and ground. Volume was set at full. The default target frequency is 440.

First test:
No matter the tone or shape generated the LED did not light.

Second test:
I changed the "magnitude" to 500 and the led triggered from around 350 to 670 which is hugely unacceptable

Third test:
I spent some time changing the magnitude and target frequencies with no avail. Either the LED never triggered or it would trigger in +/-200 range of the target frequency.

As a side note, I am not very mathematically inclined. Otherwise i would've just taken apart the algorithm myself and made an Arduino library.

Anyway, if anyone has any good Arduino software solutions for decoding DTMF or any suggestions on how to make this or another library work, it would be greatly appreciated. I do not want a hardware solution. I already have a perfectly working hardware solution and I am now looking to eliminate it all together. Thanks for your help!
Pages: [1]