Pages: [1]   Go Down
Author Topic: Improving FHT resolution  (Read 810 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
void setup(){
  Serial.begin(115200);
  ADCSRA = 0xe7; // set the adc to free running mode
  ADMUX = 0x41; // use adc1
  DIDR1 = 0x01;
}

Code:
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
« Last Edit: August 12, 2013, 06:35:08 pm by FantasticMrSimpson » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Norway
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).
« Last Edit: August 12, 2013, 01:48:06 pm by FantasticMrSimpson » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18815
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

also this may be of use to you

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

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 97
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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().
Logged

USA
Offline Offline
Sr. Member
****
Karma: 15
Posts: 372
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: August 13, 2013, 09:56:38 am by tmd3 » Logged

Pages: [1]   Go Up
Jump to: