Go Down

Topic: Improving FHT resolution (Read 913 times) previous topic - next topic

FantasticMrSimpson

Aug 12, 2013, 05:36 pm Last Edit: Aug 13, 2013, 01:35 am by FantasticMrSimpson Reason: 1
I currently have code for an FHT but I need it to be able to identify changes as small as 4Hz.
Following another forum post I have changed my ADSCRA to 0xe7 but this gives the frequency to the nearest 37Hz and having read up on the ADSCRA function I realised that this is the best it can do. I need it to be as accurate as possible between 70-400Hz.

I don't mind if it takes longer to process, I just need a higher resolution.

Code: [Select]
void setup(){
 Serial.begin(115200);
 ADCSRA = 0xe7; // set the adc to free running mode
 ADMUX = 0x41; // use adc1
 DIDR1 = 0x01;
}


Code: [Select]
void loop(){
 for (int i = 0 ; i < FHT_N ; i++) { // save 256 samples
   while(!(ADCSRA & 0x10)); // wait for adc to be ready
   ADCSRA = 0xf7; // restart adc
   byte m = ADCL; // fetch adc data
   byte j = ADCH;
   int q = (j << 8) | m; // form into an int
   q -= 0x0200; // form into a signed int
   q <<= 6; // form into a 16b signed int
   fht_input[i] = q; // put real data into bins
 }
 fht_window(); // window the data for better frequency response
 fht_reorder(); // reorder the data before doing the fht
 fht_run(); // process the data in the fht
 fht_mag_log(); // take the output of the fht
 binSelect();
 detect();
}


Thanks

FantasticMrSimpson

I have tried to use the code posted by g_u_e_s_t in this forum: http://forum.arduino.cc/index.php?topic=179095.15

But that hasn't worked for me. Please help.

lamjacom

As I undersand this, you need to caputre data at 800 Hz sample rate. That will give you the bins from 0Hz to 400Hz with a resolution of 3.15 Hz

FantasticMrSimpson

#3
Aug 12, 2013, 08:40 pm Last Edit: Aug 12, 2013, 08:48 pm by FantasticMrSimpson Reason: 1
Yep, sample rate has to be at least twice the highest frequency. Poisson distribution or Nquist distribution or something, certainly one of the distributions (it's been a while).

Nick Gammon

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Your other post deleted.

- Moderator
http://www.gammon.com.au/electronics

thepaynetrain

Its the nyquist-shannon sampling frequency you need to be paying attention to.

http://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem

that should give you an idea of sampling rates.

Need any help give me a shout

And stop posting twice. Bad FantasticMrFox. Stop it...

thepaynetrain

also this may be of use to you

http://www.waitingforfriday.com/index.php/Fast_Hartley_Transformation_Library_for_AVR_microcontrollers

FantasticMrSimpson

My FHT does work, It's just changing the sampling rate which I'm having trouble with because the ADCSRA function has a resolution of 37Hz at it's best.

g_u_e_s_t

to sample slower, you can either setup the ADC to sample on a slower interrupt, or just use analogRead().  the latter is probably easier to get started with.  you can call analogRead(), and then put a delay in for the right amount of time.  be sure to comment out all the ADC setup code before using analogRead().

tmd3

#9
Aug 13, 2013, 04:53 pm Last Edit: Aug 13, 2013, 04:56 pm by tmd3 Reason: 1
You can try parabolic interpolation.  The theory is that the continuous Fourier transform of the input signal looks like a parabola near a peak; the practice is to locate a peak among three adjacent frequency bins, fit a parabola to the magnitudes at those bins, and estimate the location of the vertex.  Here's a link that describes how to do it: https://ccrma.stanford.edu/~jos/parshl/Peak_Detection_Steps_3.html.

Alternatively, you could give up on the digital Fourier transform, and use autocorrelation instead.  Here's a scholarly paper that describes autocorrelation and the YIN algorithm for frequency estimation: http://www.ircam.fr/pcm/cheveign/pss/2002_JASA_YIN.pdf.  

Here's a link to an Arduino-based guitar tuner project, using the YIN algorithm, that looks to be very much like the one you're attempting: http://deambulatorymatrix.blogspot.com/2010/11/digital-chromatic-guitar-tuner-2008.html

Edit: fixed link

Go Up