# Arduino Forum

## Using Arduino => Audio => Topic started by: Noisecontrol on Jun 05, 2018, 12:02 pm

Post by: Noisecontrol on Jun 05, 2018, 12:02 pm
Hello
I use this code for analyize sound

https://github.com/kosme/arduinoFFT/blob/master/Examples/FFT_03/FFT_03.ino

What is magnitude ?
Is it amplitude?
What relation is between magnitude and amplitude and ADC?
Post by: PieterP on Jun 05, 2018, 12:15 pm
Please, edit your post to use code tags. Parts of your code were removed and caused the entire post to be printed in italic. You would have known that if you'd have read the guidelines in the sticky posts on 'how to use this forum'.

Magnitude refers to the distance between a point in the complex plane and the origin. Sometimes, this can be the distance squared.

It is proportional to the sum of the amplitudes of the sinusoidal waves at the input with a frequency that falls within the frequency bin in question.
You probably have to divide by the number of frequency bins for it to be correct, if the library doesn't already do this.

Pieter
Post by: Noisecontrol on Jun 05, 2018, 12:37 pm
Hi pieter
I am sorry
I edit my post

Amplitude= ((magitude ^2)-(frquency^2))^0.5
Is it true?

What is relation between ampltude and ADC in per bin?
How can i calculate ADC in per bin?
Post by: PieterP on Jun 05, 2018, 01:00 pm
When you calculate the FFT of 2n samples, you get a complex number for each of the 2n frequency bins. These frequency bins are symmetrical around the Nyquist frequency (sample frequency / 2), or symmetrical around the origin (i.e. negative frequencies). This means that you only need half of the frequency bins (because the other half is the same).
The magnitude is the distance between these complex numbers and the origin: Magnitude(a+bi) = sqrt(a²+b²).

The way the FFT works, it scales the result by the window size (2n).
So you have to divide the results by 2n to get the actual magnitude.
However, this also includes the negative frequencies, so it will be half of what you would expect. Solution: multiply by two again.

In short: actual magnitude of result (a+bi) = sqrt(a²+b²)/n

Interpretation: if you apply a sine wave with an amplitude of 1 to the input, the magnitude of the resulting frequency bin will be one as well. (Depending on the resolution, and only if the frequency of the sine wave is a natural multiple of the frequency resolution of the FFT, otherwise, it will be smeared out across neighboring bins as well.)

Note: when you're interested in the energy of each frequency bin, or if you want to express it in dB, calculating the square root is a complete waste of resources.

What is relation between ampltude and ADC in per bin?
How can i calculate ADC in per bin?
Parseval's theorem states that the energy in the time domain is the same as the energy in the frequency domain.
However, for a discrete Fourier transform (of which the FFT is an implementation) you have to scale it by a factor of n (or 2n, if you care about negative frequencies).
Post by: Noisecontrol on Jun 05, 2018, 01:22 pm
Your means is if my 2n=128
I must magnitude divid to 64 to be actual magnitude in per bin?
Please say one example to do it
Post by: PieterP on Jun 05, 2018, 01:28 pm
Your means is if my 2n=128
I must magnitude divid to 64 to be actual magnitude in per bin?
Yes.

I can't explain it quickly without a good mathematical foundation. It is not an easy topic. You should probably do your own research to try and grasp the mathematics behind all of it.
Or just blindly do what everyone else does, without understanding it, that'll probably work just fine in this case.

What do you want to do with the result?
Post by: Noisecontrol on Jun 05, 2018, 02:07 pm
I want to make a sound level meter that show result in dB A_weighting
For get a weighing must first analyze sound and then wighted
There are a equiption that convert adc to Vrms and then dB
dB =20log(Vrms/0.0063)+94-sensivity mic-gain
If i can Vrms in per bin .i can calculate dB per bin and then i can weight them and calculate overall SPl in dBA
Post by: PieterP on Jun 05, 2018, 02:28 pm
I already explained how to get the magnitude of the frequency bins. You're interested in the power spectral density, which can be estimated by the magnitude squared.

To convert it to a logarithmic scale, just take the logarithm of the results. This is the power in Bels. Multiply by ten to get decibels.

Now you're still stuck in ADC units. You have to scale everything by a factor of 5V/1024 to convert it to Volts (or Watts). Just add 20*log(5.0/1024) to the result.

Remember: actual magnitude squared of (a+bi) = |a+bi|²/n²  = (a²+b²)/n². No need to take the square root. Just use a factor of 10 before your logarithm instead of 20 (because 20 log(x) = 10 log(x²)).

Then add 94 and the mic gain to set your reference level and compensate for the microphone's sensitivity.

Edit: where did you get that factor 1/0.0063 and 94?
Post by: Noisecontrol on Jun 05, 2018, 02:36 pm
20 log(x) = 10 log(x²)).

X is magnitude?
Post by: PieterP on Jun 05, 2018, 02:37 pm
Yes. But that's a mathematical identity that holds true for all (positive) x.
Post by: Noisecontrol on Jun 05, 2018, 02:43 pm
0.0063 get from sensivity of microphone
If mic sensivity be -44dBV the by under equiption you can calculated
Post by: PieterP on Jun 05, 2018, 02:48 pm
In that case, why do you add those other two terms?
Keep in mind that 20 log(x/y) = 10 log(x²) - 20 log(y).
Post by: Noisecontrol on Jun 05, 2018, 02:51 pm
I think it is difficult
If i convert adc to dB and then do fft on it
Does magnitude is equal dB in per bin?
Post by: Noisecontrol on Jun 05, 2018, 02:58 pm
Like this
Vrms=(k*5/1023)*0.707
dB=20log(Vrms/0.0063)+94-44-gain

Then dB enter fft lib and show dB per bin
Post by: PieterP on Jun 05, 2018, 03:01 pm
I think it is difficult
If i convert adc to dB and then do fft on it
Does magnitude is equal dB in per bin?
That won't help. You have to do the conversion either way. And if you do it before the FFT, you'll lose a lot of precision. On top of that you would have to divide, which is many times slower than the subtraction you have to do after the log.

No:
dB = 10 log (magnitude ²) - c

Where c is the compensation for voltage reference, ADC resolution, amplification and microphone sensitivity. It is constant, so you only have to calculate it once.
magnitude² = (a²+b²)/n²
And FFT[k] = a+bi for frequency bin k.

As for the Vpeak to VRMS conversion: I don't know, honestly, I'd have to work that out on a piece of paper and verify in MATLAB or Octave.
Post by: Noisecontrol on Jun 05, 2018, 03:10 pm
a and b what is it?

That  souce code show magnitude for me

Do that value magnitude  set in this equiption?
dB=10log(magnitude^2)-c
??
Post by: PieterP on Jun 05, 2018, 03:15 pm
https://github.com/kosme/arduinoFFT/blob/d8c22a897e637bb1719dfbef84f83a279c634eef/src/arduinoFFT.cpp#L165 (https://github.com/kosme/arduinoFFT/blob/d8c22a897e637bb1719dfbef84f83a279c634eef/src/arduinoFFT.cpp#L165)

a = vReal[k], b = vImag[k]

Note that this function calculates the square root. Don't do that, it's unnecessary.
Post by: Noisecontrol on Jun 05, 2018, 03:18 pm
FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */

This part code calculate magnitude in per frequncey bin
You say me that per mag divid to 64 then set in this equiption
dB=10log( magnitude^2)- c

Is it true?
Post by: PieterP on Jun 05, 2018, 03:23 pm
Yes. But instead of calculating magnitude[k] ² as sqrt(vReal[k]² + vImag[k]²)², calculate it directly as vReal[k]² + vImag[k]².
Post by: PieterP on Jun 05, 2018, 03:25 pm
Is this a personal project? Is it an assignment for your studies? What's your background in mathematics and DSP?
Post by: Noisecontrol on Jun 05, 2018, 03:30 pm
It is personal and i didnt studied math
I know industrial acoustic but dont know FFt
I have personal project that first i must determin dBA in enviroment and then do another part project
Post by: Noisecontrol on Jun 05, 2018, 03:35 pm
Why in 0 Hz magnitude is maximum and in low frequency  magnitude is greater than middle and hight frequency ?
Post by: PieterP on Jun 05, 2018, 03:36 pm
I don't have much experience with the actual applications of the FFT, and I didn't study all of the maths (yet), so I think there might be other people (on this forum or elsewhere) who could do a better job at explaining it to you. There are many resources online, but it's pretty hard if you don't have one complete, chronological explanation to follow.
Some maths knowledge is required as well. Sadly, you can't just learn it by reading a couple of forum posts. You have to read up on the theories behind all of it, and then do the calculations for yourself.
Post by: PieterP on Jun 05, 2018, 03:37 pm
Why in 0 Hz magnitude is maximum and in low frequency  magnitude is greater than middle and hight frequency ?
Probably because you have a DC offset on your input (you should bias your input to 2.5V and then compensate for that in software).
Post by: DVDdoug on Jun 05, 2018, 07:51 pm
Quote
Why in 0 Hz magnitude is maximum and in low frequency  magnitude is greater than middle and hight frequency ?
There is no 0Hz component to sound* but the input is usually biased/DC offset because the Arduino can't directly read the negative-half of an audio signal.

If the input is not biased/offset your waveform will be half-wave rectified, so it will again have a positive DC (zero Hz) bias, but it will also be badly distorted and your FFT will be totally fouled-up.

With real world sounds there is usually more energy in the low frequencies (that's one of the reasons woofers are bigger than tweeters), but it depends on the sound...   A bass guitar obviously has more low-frequency energy than a trumpet.

White noise has equal energy at all frequencies.   With white noise all of your FFT bins should be equal.

Pink has equal energy in each octave.    On a linear scale the higher octaves are "wider" than the lower octaves, so pink noise is rolled-off -3dB per octave.   Most spectrum analyzers show the frequency bands as octaves (or as a log scale) so pink noise "looks flat" on a spectrum analyzer.

And if you are generating white or pink noise from a speaker, remember that your speaker & microphone are imperfect.

* Air pressure (absolute or relative) is zero Hz (or near zero Hz).   Since there is air pressure here on earth there is a 0Hz component.    But microphones don't pick-up constant-static air pressure, regular speakers can't put-out 0Hz, and although you can sometimes feel  air pressure with your ears, it is not sound.
Post by: MarkT on Jun 05, 2018, 11:30 pm
I think it is difficult
If i convert adc to dB and then do fft on it
Does magnitude is equal dB in per bin?
You _cannot_ convert to dB before the FFT, the FFT is a linear operation on voltages.

DVDdoug:
Quote
With real world sounds there is usually more energy in the low frequencies (that's one of the reasons woofers are bigger than tweeters),
The reason is the wavelength of low frequencies is larger, nothing to do with the average
power spectral density of music since speakers can reproduce any signal and are ideally
flat response across the band.

The interesting question is why microphones don't have to be large for low frequencies...
Post by: DVDdoug on Jun 06, 2018, 03:29 am
Quote
The reason is the wavelength of low frequencies is larger, nothing to do with the average
power spectral density of music since speakers can reproduce any signal and are ideally
flat response across the band.
I'm not talking about wavelength.   The voice coil in a woofer is larger than a tweeter and it can handle more power.   If you remove the crossover and run full-power into the woofer nothing bad will happen.   If you run full-bandwidth full-power into the tweeter you might fry it.
Post by: PieterP on Jun 06, 2018, 09:36 am
I think you lose the notion of "RMS Voltage" when applying the FFT. The RMS over the entire spectrum is the same (corrected for your processing gain (sqrt(2n)) and the coherent gain of your window (rms(window))). However, you can't use the entire spectrum, you have to use the energy per frequency bin to be able to weigh them.
So the question here is: what is the relationship between the energy in the bin and the RMS voltage of the original sine wave.

I think your formula applies to the time domain, where you can use a digital filter to do the weighting, and then just taking the RMS voltage of the resulting signal.

ANSI S1.42 specifies the (continuous) transfer functions for such an a-weighting filter. (here (https://pims.grc.nasa.gov/plots/user/acoustics/FrequencyWeightingEquations.pdf))

You could either filter it in the analog domain, using op-amps and analog filters:
http://sound.whsites.net/project17.htm (http://sound.whsites.net/project17.htm)

Or you could transform it into the digital domain and use a discrete digital filter. Usually, a bilinear transform is used. It is an approximation of the mapping between the s-plane and the z-plane. However, some people note that this produces an error at the higher end of the spectrum, which could be a problem for you. You could use some kind of regression or optimization to minimize the error in the higher regions as well.
But there's a catch: according to Nyquist, you need a sampling rate of at least twice the frequency of the highest frequency in your analog signal. Every frequency higher than half of your sampling rate will cause aliasing, and completely mess up your results.
This implies two things: you need a sampling frequency of at least 40 kHz (2×20 kHz), preferably higher.
You need a (strong) analog filter to make sure that very little frequencies above 20 kHz remain in the signal that you send to the ADC. (Note: this is true when applying digital filters, but also when applying an FFT!)
The maximum sampling frequency of the Arduino's ADC is about 10 kHz. That's nowhere near enough.

That being said, you might be interested in this: How to prove that A-weighting doesn't work (http://sound.whsites.net/articles/a-weighting.html)

Post by: PieterP on Jun 06, 2018, 10:41 am
Here's some MATLAB/Octave code that may help you to get an idea of what's going on:

Code: [Select]
`close all;nb_samples = 128;  % 128 samples → 128 frequency binsn = (0:nb_samples-1)';f_s = 256;       % 256 Hz sample frequencyf_1   = 32;      % Sine wave with a frequency of 32 HzA_1   = 1;       % and amplitude of 1f_2   = 60;      % Sine wave with a frequency of 60 HzA_2   = 0.5;     % and amplitude of 0.5t = n / f_s;     % Generate a vector with timesine_1 = A_1*sin(2*pi*f_1*t);sine_2 = A_2*sin(2*pi*f_2*t);sine = sine_1 + sine_2;subplot(2,2,1);plot(t, sine, '-o');title('Original sine waves');rms_original = rms(sine);db_rms_original = 20*log10(rms_original);%% Without windowfft_sine = fft(sine);freq = n*f_s/nb_samples;subplot(2,2,2);stem(freq, abs(fft_sine)/nb_samples);title('Magnitude per frequency bin after FFT (without window)');energy_fft = sum(abs(fft_sine).^2)/nb_samples^2;db_energy_fft = 10*log10(energy_fft);energy_gain = sqrt(energy_fft)/rms_original;db_energy_gain = db_energy_fft - db_rms_original;fprintf("Without window\n");fprintf("==============\n");fprintf("V_RMS       = %f (%f dB)\n", rms_original, db_rms_original);fprintf("Energy_FFT  = %f (%f dB)\n", sqrt(energy_fft), db_energy_fft);fprintf("Energy gain = %f (%f dB)\n\n", energy_gain, db_energy_gain);%% With windowwindow = hamming(nb_samples);rms_window = rms(window);db_rms_window = 20*log10(rms_window);windowed_sine = window.*sine;subplot(2,2,3);hold on;plot(t, windowed_sine, '-o');plot(t, window, '-k');plot(t, -window, '-k');title('Sine waves after applying window');fft_sine = fft(windowed_sine);freq = n*f_s/nb_samples;subplot(2,2,4);stem(freq, abs(fft_sine)/nb_samples);title('Magnitude per frequency bin after FFT (with window)');energy_fft = sum(abs(fft_sine).^2)/nb_samples^2;db_energy_fft = 10*log10(energy_fft);energy_gain = sqrt(energy_fft)/rms_original;db_energy_gain = db_energy_fft - db_rms_original;fprintf("With window\n");fprintf("===========\n");fprintf("V_RMS                = %f (%f dB)\n", rms_original, db_rms_original);fprintf("Energy_FFT           = %f (%f dB)\n", sqrt(energy_fft), db_energy_fft);fprintf("Energy gain          = %f (%f dB)\n", energy_gain, db_energy_gain);fprintf("Coherent window gain = %f (%f dB)\n\n", rms_window, db_rms_window);`

Output:
 Without window==============V_RMS       = 0.790569 (-2.041200 dB)Energy_FFT  = 0.790569 (-2.041200 dB)Energy gain = 1.000000 (0.000000 dB)With window===========V_RMS                = 0.790569 (-2.041200 dB)Energy_FFT           = 0.496454 (-6.082415 dB)Energy gain          = 0.627971 (-4.041215 dB)Coherent window gain = 0.627969 (-4.041233 dB)

Note that some energy is lost due to the windowing, so you'll have to make up for that.

(http://forum.arduino.cc/index.php?action=dlattach;topic=551490.0;attach=261039)
Post by: MarkT on Jun 06, 2018, 01:15 pm
I'm not talking about wavelength.   The voice coil in a woofer is larger than a tweeter and it can handle more power.   If you remove the crossover and run full-power into the woofer nothing bad will happen.   If you run full-bandwidth full-power into the tweeter you might fry it.
A lot of bass drivers are 1" coils, whatever size the cone is. You pay a lot of money for larger coils and magnets,
its the majority of the materials cost.  Standard hifi powers of 50W peak, average music, then the average power is a few watts and nothing cooks.  PA system, everything is different, larger, vented, speaker motors are commonplace.

Bass drivers use thicker coils, as they have much larger excursion than tweeters so can have 10 to 100 times
the amount of copper in the coil to help spread the heat.
Title: A question
Post by: Noisecontrol on Jun 14, 2018, 03:06 pm
Hello
Maximum adc is 1024 then why  when adc analized by fft ,magnitude value in per bin frequency could be greater than 1024 ?
If magnitude in per frequency should not
be less than 1024 ?
Title: Re: A question
Post by: TolpuddleSartre on Jun 14, 2018, 03:46 pm
Quote
No, 1023.
Title: Fft result to voltage
Post by: Noisecontrol on Jun 14, 2018, 03:50 pm
How can i fft result ( magnitude)convert to voltage in per frequency bin?
Title: Re: Fft result to voltage
Post by: vffgaston on Jun 14, 2018, 03:54 pm
...fft result ...
¿Fast Fourier Transform?
Title: Re: Fft result to voltage
Post by: Noisecontrol on Jun 14, 2018, 04:02 pm
¿Fast Fourier Transform?
Yes
Title: Re: Fft result to voltage
Post by: DVDdoug on Jun 14, 2018, 04:41 pm
I don't know how it's scaled, but if you can't find it in the documentation you can calibrate it.

For example, feed-in a 1V, 1kHz, signal and see what you get.    Then, you can use the map() function to map the values to voltage.   If you feed-in a 1V, 100Hz, signal you should get (about) the same reading in the 100Hz bin.  And if you mix the two signals both bins should still read (about) the same as before.

Choose frequencies that are in the center of the bin frequencies.

...If you need a way to generate sine waves, Audacity (https://www.audacityteam.org/) can make a WAV file. that you can play on your soundcard.     You can also mix in Audacity so you can try with two (or more) known frequencies.   But since mixing is done by summation, you'll want to generate waves at -6dB (half of the maximum) or less.    And, you'll need a multimeter to measure the voltage.
Title: Re: Fft result to voltage
Post by: Noisecontrol on Jun 14, 2018, 05:01 pm

But when fft analized a signal , we have expected that get amplitud in per frequency base that factor analized. in other word if adc is amplitude of a signal in per time we have expected frequncies have same unit amplituid
Title: Re: Fft result to voltage
Post by: jremington on Jun 14, 2018, 05:38 pm
Quote
Presumably you mean DAC, which standard Arduinos do not have, but why would anyone bother to document something so simple?

Code: [Select]
`    analogWrite(pin,bin_value);`
Title: Re: A question
Post by: jremington on Jun 14, 2018, 05:53 pm
Quote
Maximum adc is 1024 then why  when adc analized by fft ,magnitude value in per bin frequency could be greater than 1024 ?
Possibly, depending on how the FFT results are scaled. Different FFT subroutine packages scale the output differently.

Here is an idea: write some simple programs and learn how the FFT works.

That way you can answer questions like this yourself, and learn something in the process.

Example using the OpenMusicLabs FFT library:
Code: [Select]
`/*  fft_test_constant  example sketch for testing the fft library.  This generates a constant data set demonstrating the DC  offset term. Enable the fft_window() line to see the effect of  windowing.*/// do #defines BEFORE #includes#define LIN_OUT 1 // use the lin output function#define FFT_N 32 // set to 32 point fft#include <FFT.h> // include the libraryvoid setup() {  int i, k;  Serial.begin(9600); // output on the serial port  for (i = 0 ; i < FFT_N ; i++) { // create data samples    fft_input[2 * i] = 1000; // put real data into even bins    fft_input[2 * i + 1] = 0; // set odd bins to 0  }  //  fft_window();  //Try with and without this line, it smears  fft_reorder(); // reorder the data before doing the fft  fft_run(); // process the data using the fft  fft_mag_lin(); // calculate the magnitude of the output  // print the frequency index and amplitudes  Serial.println("bin  amplitude");  for (i = 0; i < FFT_N / 2; i++) {    Serial.print(i);    Serial.print("       ");    Serial.println(fft_lin_out[i]);  }  Serial.println("Done");}void loop() {}`

Output:
Code: [Select]
`bin  amplitude0       10001       02       03       04       05       06       07       08       09       010       011       012       013       014       015       0Done`
Title: Re: Fft result to voltage
Post by: Noisecontrol on Jun 14, 2018, 06:21 pm
Presumably you mean DAC, which standard Arduinos do not have, but why would anyone bother to document something so simple?

Code: [Select]
`    analogWrite(pin,bin_value);`
No i want to convert fft results in per bin to voltage
Title: Re: Fft result to voltage
Post by: jremington on Jun 14, 2018, 06:31 pm
Quote
No i want to convert fft results in per bin to voltage
Explain this comment, and explain why you think analogWrite() does not do what you want.
Title: Re: Fft result to voltage
Post by: PieterP on Jun 14, 2018, 06:34 pm

You even started a third thread (http://forum.arduino.cc/index.php?topic=553150.0) on the topic.

You have to correct for a couple of things:
• Subtract the bias voltage (expressed in ADC units) from the sampled signal
• Use the complex modulus of the FFT result to get the magnitude
• Divide by the number of samples to correct for the FFT processing gain
• Multiply by 2 to account for magnitude "lost" in negative part of the spectrum
• Divide by the average amplitude of the windowing function
• Convert the magnitude in ADC units to a voltage (*5/1024)

Here's a MATLAB/Octave script that does exactly that, together with the result, to get an understanding of what's going on. See line 58 for the actual conversion.
Code: [Select]
`%% Setupclose all;N = 128;  % 128 samples → 128 frequency binssamples = (0:N-1)';f_s = 256;     % 256 Hz sample frequencyf   = 64;      % Sine wave with a frequency of 64 HzA   = 1.25;    % and amplitude of 1.25 V peakV_bias = 2.5;V_ref = 5;ADC_bits = 10;ADC_factor = 2^ADC_bits;t = samples / f_s;     % Generate a vector with timesine_V = A*sin(2*pi*f*t); % Sine wave in voltssine_V = sine_V + V_bias; % Bias sine = sine_V * ADC_factor / V_ref; % Sine wave as sampled by the Arduinosubplot(2,2,1);plot(samples, sine, '-o');axis([0 N 0 ADC_factor])title('Original 1.25 V peak, 64 Hz sine wave (ADC Units)');%% DC offset correctionsine = sine - V_bias * ADC_factor / V_ref; % Subtract bias again%% Windowingwindow = hamming(N);mean_window = mean(window);windowed_sine = window.*sine; % Apply window functionsubplot(2,2,3);hold on;plot(samples, windowed_sine, '-o');plot(samples, ADC_factor * window / 2, '-k');plot(samples, -ADC_factor * window / 2, '-k');title('Sine wave after applying window');axis([0 N -ADC_factor/2 ADC_factor/2])%% FFTfft_sine = fft(windowed_sine);freq = samples * f_s / N;subplot(2,2,2);stem(freq, abs(fft_sine));axis([0 f_s 0 inf]);title('Magnitude per frequency bin after FFT');corrected_fft = fft_sine / N * 2 / mean_window * V_ref / ADC_factor;subplot(2,2,4);half = length(freq) / 2;stem(freq(1:half), abs(corrected_fft(1:half)));axis([0 f_s / 2 0 inf]);title('Magnitude per frequency bin after FFT (corrected)');`

Here's the result:
(http://forum.arduino.cc/index.php?action=dlattach;topic=551490.0;attach=262243)

If you're using a dB scale, express the divisions as a sum of constant logarithms, using the identities log(x*y) = log(x)+log(y) and log(x/y) = log(x) - log(y).

Pieter
Post by: Coding Badly on Jun 14, 2018, 07:19 pm

Post by: Noisecontrol on Jun 14, 2018, 08:17 pm
You have to correct for a couple of things:
• Subtract the bias voltage (expressed in ADC units) from the sampled signal
• Use the complex modulus of the FFT result to get the magnitude
• Divide by the number of samples to correct for the FFT processing gain
• Multiply by 2 to account for magnitude "lost" in negative part of the spectrum
• Divide by the average amplitude of the windowing function
• Convert the magnitude in ADC units to a voltage (*5/1024)

If you have source code of this process for arduino please share it.
I dont know MATLAB code
Post by: PieterP on Jun 14, 2018, 08:38 pm
If you have source code of this process for arduino please share it.
I dont know MATLAB code
I don't have the Arduino code for this, and I can't test it.
The principle is explained in my post, you can look at the MATLAB implementation for inspiration.
You should be able to read it, even if you don't know the exact syntax. Line 58 is the most important line.
Can you explain what you don't understand?

Like I said before, using FFT doesn't seem to be the standard way to perform A-weighting, you should probably look into digital filters instead.
Post by: Noisecontrol on Jun 14, 2018, 09:42 pm
corrected_fft = fft_sine / N * 2 / mean_window * V_ref / ADC_factor;

What is fft_sin and N and mean_window and v_ref and adc factor?

fft_sin is magnituid in per bin?
N is samples for example 128?
mean_window what is it and how calculated?
V_ref is 5 or 3.3 volt?
Post by: PieterP on Jun 14, 2018, 10:25 pm
They're defined above.

fft_sine is the result of the FFT, either as complex number, or the modulus of that complex number.
N is the number of bins (or the number of samples).
mean_window is the average value of the window function you're using.
V_ref is the ADC reference voltage, it depends on what Arduino you're using and how it's configured.
ADC_factor = 2^10 = 1024 if you're using the internal 10-bit ADC.
Post by: Noisecontrol on Jun 14, 2018, 10:49 pm
For calculate mean window i must get avarage Vreal of window function ?
Post by: PieterP on Jun 14, 2018, 11:01 pm
The window function is real by definition. But yes.
Post by: Noisecontrol on Jun 14, 2018, 11:37 pm
Is fft _sin complex number like A+jB?
Post by: PieterP on Jun 14, 2018, 11:41 pm
It's more efficient if you calculate the modulus first, but from a mathematical standpoint it doesn't matter, because |r(a+bi)| = r|a+bi|.

It is the result of the FFT, and you want the magnitude, so you take the modulus. Then you multiply that modulus by the aforementioned correction factors.
Post by: Noisecontrol on Jun 15, 2018, 12:05 am
I didnt understand
My english is not good please say simple to do it
Sin_fft is equal to magnitude or not?
If not how can i calculate sin_fft
Post by: PieterP on Jun 15, 2018, 12:07 am
It is the magnitude of the results of the FFT.
Post by: Noisecontrol on Jun 15, 2018, 08:02 am
Then magnitude per bin is equal  to sin_fft
Post by: PieterP on Jun 15, 2018, 09:05 am
Yes.
Post by: Noisecontrol on Jun 15, 2018, 09:25 am
I use arduino uno and i want to use 5 volt pin
How much is v_ref?
Post by: PieterP on Jun 15, 2018, 09:38 am
Then V_ref is 5V.
Post by: Noisecontrol on Jun 15, 2018, 09:52 am
After calculating correct_fft, the value of correct_fft will be in terms of voltage in per bin?
Post by: PieterP on Jun 15, 2018, 10:01 am
Yes. But because of windowing and discretization, you'll get non-zero values in neighboring bins.
Post by: Noisecontrol on Jun 15, 2018, 10:22 am
Yes. But because of windowing and discretization, you'll get non-zero values in neighboring bins.
I didnt understand you
Post by: PieterP on Jun 15, 2018, 10:38 am
Take a look at the image I posted earlier. You start with a 64 Hz sine wave of 1.25 V peak. The corrected FFT shows an amplitude of 1.25 in the 64 Hz bin, as you would expect, but the 62 Hz and 66 Hz bins are not zero.
Post by: Noisecontrol on Jun 15, 2018, 10:45 am
What is reason of it?
Post by: PieterP on Jun 15, 2018, 10:51 am
Because of the windowing, in this case. But you get the same problem if your input frequency is not an integer multiple of the bin frequency. There's not much you can do about it.

Are you still trying to do A-weighting?
Post by: Noisecontrol on Jun 15, 2018, 10:54 am
Maybe because of a slight oscillation in the main frequency. If the distance between frequencies increases, this problem can be solved
Post by: Noisecontrol on Jun 15, 2018, 11:00 am
I try to analize sound and then caculated dB flat in per bin if it be corrected by a reffrence sound level meter,I can convert dB flat to A weighting and test it.but the hardest part of this project make a amplifire microphon and messurment adc and convert to voltage in per bin by fft.
I try and show my code to you to help me about it
Thanks a lot
Post by: PieterP on Jun 15, 2018, 11:13 am
A-weighting is normally done in the time-domain, using analog filters. Newer devices use digital filters. I couldn't find any online references on using FFT for A-weighting.
If your goal is to create a working A-weighting system, I'd use digital filters.
If you want to learn about DSP and the Fourier transform, to try a new approach to A-weighting, I think you'll have to study the maths behind it first.
Post by: Noisecontrol on Jun 15, 2018, 11:27 am
I find a circuit for a weighting
Post by: Noisecontrol on Jun 15, 2018, 11:41 am
If you see some sound level meter aplication that analized sound in dBA  like audiotools , i think it a-weighting by fft cuz there are no any circuit to do a_weighting in mobile
Post by: PieterP on Jun 15, 2018, 11:51 am
I'm pretty sure that it uses digital filters. You can "convert" analog filters to digital filters. The bilinear transform does exactly that, for example. It's a first-order approximation, but it should do the trick.
Post by: Noisecontrol on Jun 15, 2018, 12:34 pm
How a android mobile do digital filter?
Post by: PieterP on Jun 15, 2018, 12:43 pm
You factor the discrete-time transfer function into second-order polynomials (both the numerator and the denominator), and then you use the coefficients of these polynomials as the coefficients of the BiQuad filters.

Or you could calculate the convolution of the difference equation explicitly. But I think that could result in numeric instability.

Either way, it's going to be much easier than using an FFT.
Post by: Noisecontrol on Jun 15, 2018, 12:59 pm
Can do it by aurdino?
How can i find sample of it in arduino code?
Post by: MarkT on Jun 15, 2018, 02:01 pm
What is reason of it?

The fourier transform is only mathematically defined for periodic waveforms (that repeat for ever)
The DFT (of which FFT is an implementation) is only meaningful if the signal wraps around to the
beginning seamlessly - otherwise you have to use a window to reduce (but not eliminate) wrap-around
artifacts.

The best window is probably Kaiser-Bessel.  It takes a tuning parameter so you can select the properties
Post by: Noisecontrol on Jun 15, 2018, 03:30 pm
Can do bilinear transform by aurdino?
How can i find sample of it in arduino code?
Post by: MarkT on Jun 15, 2018, 03:43 pm
Can do bilinear transform by aurdino?
How can i find sample of it in arduino code?
No, you do this as filter design time - the easiest way to design digital filters
is to find an online calculator, but normally they only exist for low-pass, band-pass
or high-pass, not a specific weighting function.

So the idea is find an analog A-weighting filter, put its poles and zeroes through
the bilinear transform to get Z-transform poles and zeroes, and feed that into
a digital filter tool.
Post by: Noisecontrol on Jun 17, 2018, 09:03 pm
Hello peiter
I do that formula but didnt convert magnitude to voltage
Post by: PieterP on Jun 17, 2018, 09:06 pm
Post by: Noisecontrol on Jun 19, 2018, 06:01 pm
Hello
I use this code for anlaize a sin wave with 300 Hz
Why the bin is not correct cuz when i want to calculate freqency  by this equiption fs*bin/N
Frequency is not correct
19200*20/64=6000 Hz but my freqency sin wave was 300Hz!!!

Code: [Select]
`#define LIN_OUT 1  #define FFT_N 64#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#include <FFT.h> // include the libraryvoid setup() {  Serial.begin(115200); // output on the serial port  //19200khz  sbi(ADCSRA, ADPS2);  sbi(ADCSRA, ADPS1);  cbi(ADCSRA, ADPS0);}void loop() {    int i,k;  float f1=300;     //the two input frequencies (bin values)  for (i = 0 ; i < FFT_N ; i++)   {     k=1000*sin(2*PI*f1*i/FFT_N);    fft_input[2*i] = k; // put real data into even bins    //Serial.println(k);    fft_input[2*i+1] = 0; // set odd bins to 0  }  fft_reorder(); // reorder the data before doing the fft  fft_run(); // process the data using the fft  fft_mag_lin(); // calculate the magnitude of the output  // print the frequency index and amplitudes  Serial.println("bin  amplitude");  for (i=0; i<FFT_N/2 ; i++) {    {      Serial.print(i); Serial.print("   ");      Serial.println(fft_lin_out[i]);     }     }  Serial.println("Done");  while(1); //wait here}`

And output

Code: [Select]
`bin  amplitude0   21   02   03   04   25   06   07   08   19   010   011   012   213   014   015   016   017   018   019   020   50021   022   023   024   125   026   027   028   029   030   031   0Done`
Post by: PieterP on Jun 19, 2018, 06:09 pm
The result is correct, your original sine wave is not. You have to divide by the sampling rate, not by the number of samples.
Post by: Noisecontrol on Jun 19, 2018, 06:17 pm
Please write equiption of it for calculate frequency

Where sin wave is not corrected?
Post by: PieterP on Jun 19, 2018, 06:20 pm
It's in the MATLAB script already.

In Arduino code:
Code: [Select]
`int k = 1000 * sin(2*PI*f1*i/19200.0);`
Post by: Noisecontrol on Jun 19, 2018, 06:27 pm
Thanks a lot it is ok

Post by: Noisecontrol on Jun 19, 2018, 07:49 pm
Hello again
I change code to recive signal by a microphone sensor. It show amplitude and frequncy but i dont know why when i make a tone for example 1000 hz arduino show max amplitude in 525 hz or when send a tone with 2000 hz it show max amplitude in 975 Hz or with tone 8000 ,it show 3975
Do i must freqency multiply 2?

Code: [Select]
`#define LOG_OUT 1 // use the log output function#define FHT_N 256 // set to 256 point fht#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#include <FHT.h> // include the libraryvoid setup() {  Serial.begin(115200); // use the serial port  TIMSK0 = 0; // turn off timer0 for lower jitter  ADCSRA = 0xe5; // set the adc to free running mode  ADMUX = 0x40; // use adc0  DIDR0 = 0x01; // turn off the digital input for adc0    //19200khz  sbi(ADCSRA, ADPS2);  sbi(ADCSRA, ADPS1);  cbi(ADCSRA, ADPS0);}void loop() { // { // reduces jitter    cli();  // UDRE interrupt slows this way down on arduino1.0    for (int i = 0 ; i < FHT_N ; i++) { // save 256 samples      while(!(ADCSRA & 0x10)); // wait for adc to be ready      ADCSRA = 0xf5; // restart adc      byte m = ADCL; // fetch adc data      byte j = ADCH;      int k = (j << 8) | m; // form into an int      k -= 0x0200; // form into a signed int      k <<= 6; // form into a 16b signed int      fht_input[i] = k; // 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    sei();    Serial.println("start");    for (byte i = 0 ; i < FHT_N/2 ; i++) {   Serial.print(i*19200/FHT_N); Serial.print("/");      Serial.println(fht_log_out[i]); // send out the data    } // } while(1);}`
Post by: PieterP on Jun 19, 2018, 09:30 pm
Your ADC configuration is all wrong. You're sampling at the wrong rate, because you reset the ADC configuration after the first measurement. Try this:
Code: [Select]
`#define LOG_OUT 1 // use the log output function#define FHT_N 256 // set to 256 point fht#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#include <FHT.h> // include the libraryvoid setup() {  Serial.begin(115200); // use the serial port  ADCSRB = 0; // Free running mode  ADMUX = (DEFAULT << 6) | 0; // A0  sbi(ADCSRA, ADEN); // Enable ADC  sbi(ADCSRA, ADATE); // Auto trigger  sbi(ADCSRA, ADSC); // Start conversion  // 19.231 kHz  sbi(ADCSRA, ADPS2);  sbi(ADCSRA, ADPS1);  cbi(ADCSRA, ADPS0);}void loop() {  do {    cli();  // UDRE interrupt slows this way down on arduino1.0    for (int i = 0 ; i < FHT_N ; i++) { // save 256 samples      while (!(ADCSRA & _BV(ADIF))); // wait for adc to be ready      sbi(ADCSRA, ADIF); // Clear interrupt flag      byte m = ADCL; // fetch adc data      byte j = ADCH;      int k = (j << 8) | m; // form into an int      k -= 0x0200; // form into a signed int      k <<= 6; // form into a 16b signed int      fht_input[i] = k; // 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    sei();    for (uint8_t i = 0 ; i < FHT_N / 2 ; i++) {      Serial.print(i * 19231UL / FHT_N); Serial.print(" Hz:\t");      Serial.println(fht_log_out[i]); // send out the data    }  } while(0);  while(1);}`

By the way, you need a strong anti-aliasing filter, especially at these low sampling rates.
Post by: Noisecontrol on Jun 19, 2018, 10:11 pm
Filter For what range frequency to remve?
What is UL in calculate frequncy that you wrote?
Post by: PieterP on Jun 19, 2018, 10:19 pm
Everything above half the sampling rate must be attenuated as much as possible. Read up on the Nyquist-Shannon theorem.

UL means unsigned long. An int would overflow.
Post by: Noisecontrol on Jun 20, 2018, 08:10 pm
Hello
Now i could calculated correction factor for in per bin and convert dB to dBA

Code: [Select]
`0 Hz: AMP:0.65 C:0.00 AMP(A):0.0075 Hz: AMP:0.60 C:0.00 AMP(A):0.00150 Hz: AMP:0.20 C:0.04 AMP(A):0.01225 Hz: AMP:0.12 C:0.11 AMP(A):0.01300 Hz: AMP:0.10 C:0.20 AMP(A):0.02375 Hz: AMP:0.12 C:0.30 AMP(A):0.04450 Hz: AMP:0.12 C:0.40 AMP(A):0.05525 Hz: AMP:0.00 C:0.51 AMP(A):0.00600 Hz: AMP:0.09 C:0.61 AMP(A):0.05676 Hz: AMP:0.11 C:0.70 AMP(A):0.08751 Hz: AMP:0.06 C:0.78 AMP(A):0.05826 Hz: AMP:0.11 C:0.86 AMP(A):0.09901 Hz: AMP:0.00 C:0.92 AMP(A):0.00976 Hz: AMP:0.36 C:0.98 AMP(A):0.361051 Hz: AMP:0.41 C:1.03 AMP(A):0.421126 Hz: AMP:0.35 C:1.08 AMP(A):0.381201 Hz: AMP:0.11 C:1.12 AMP(A):0.131277 Hz: AMP:0.13 C:1.15 AMP(A):0.151352 Hz: AMP:0.09 C:1.18 AMP(A):0.101427 Hz: AMP:0.15 C:1.21 AMP(A):0.181502 Hz: AMP:0.14 C:1.23 AMP(A):0.171577 Hz: AMP:0.11 C:1.25 AMP(A):0.141652 Hz: AMP:0.14 C:1.27 AMP(A):0.171727 Hz: AMP:0.05 C:1.28 AMP(A):0.071802 Hz: AMP:0.10 C:1.29 AMP(A):0.131878 Hz: AMP:0.09 C:1.31 AMP(A):0.111953 Hz: AMP:0.08 C:1.31 AMP(A):0.102028 Hz: AMP:0.10 C:1.32 AMP(A):0.132103 Hz: AMP:0.03 C:1.33 AMP(A):0.032178 Hz: AMP:0.08 C:1.33 AMP(A):0.112253 Hz: AMP:0.12 C:1.34 AMP(A):0.162328 Hz: AMP:0.00 C:1.34 AMP(A):0.002403 Hz: AMP:0.14 C:1.34 AMP(A):0.192478 Hz: AMP:0.03 C:1.34 AMP(A):0.032554 Hz: AMP:0.06 C:1.34 AMP(A):0.082629 Hz: AMP:0.06 C:1.34 AMP(A):0.082704 Hz: AMP:0.00 C:1.34 AMP(A):0.002779 Hz: AMP:0.06 C:1.34 AMP(A):0.082854 Hz: AMP:0.00 C:1.33 AMP(A):0.002929 Hz: AMP:0.11 C:1.33 AMP(A):0.153004 Hz: AMP:0.05 C:1.33 AMP(A):0.073079 Hz: AMP:0.15 C:1.32 AMP(A):0.203155 Hz: AMP:0.12 C:1.32 AMP(A):0.163230 Hz: AMP:0.10 C:1.31 AMP(A):0.133305 Hz: AMP:0.00 C:1.31 AMP(A):0.003380 Hz: AMP:0.09 C:1.30 AMP(A):0.113455 Hz: AMP:0.06 C:1.30 AMP(A):0.083530 Hz: AMP:0.11 C:1.29 AMP(A):0.153605 Hz: AMP:0.05 C:1.29 AMP(A):0.073680 Hz: AMP:0.03 C:1.28 AMP(A):0.033756 Hz: AMP:0.10 C:1.27 AMP(A):0.123831 Hz: AMP:0.00 C:1.27 AMP(A):0.003906 Hz: AMP:0.10 C:1.26 AMP(A):0.133981 Hz: AMP:0.06 C:1.25 AMP(A):0.084056 Hz: AMP:0.10 C:1.24 AMP(A):0.134131 Hz: AMP:0.08 C:1.24 AMP(A):0.104206 Hz: AMP:0.09 C:1.23 AMP(A):0.114281 Hz: AMP:0.06 C:1.22 AMP(A):0.074357 Hz: AMP:0.08 C:1.21 AMP(A):0.104432 Hz: AMP:0.10 C:1.20 AMP(A):0.124507 Hz: AMP:0.08 C:1.19 AMP(A):0.094582 Hz: AMP:0.11 C:1.19 AMP(A):0.134657 Hz: AMP:0.00 C:1.18 AMP(A):0.004732 Hz: AMP:0.06 C:1.17 AMP(A):0.074807 Hz: AMP:0.00 C:1.16 AMP(A):0.004882 Hz: AMP:0.06 C:1.15 AMP(A):0.074957 Hz: AMP:0.00 C:1.14 AMP(A):0.005033 Hz: AMP:0.00 C:1.13 AMP(A):0.005108 Hz: AMP:0.05 C:1.12 AMP(A):0.065183 Hz: AMP:0.10 C:1.11 AMP(A):0.115258 Hz: AMP:0.14 C:1.10 AMP(A):0.165333 Hz: AMP:0.00 C:1.10 AMP(A):0.005408 Hz: AMP:0.03 C:1.09 AMP(A):0.035483 Hz: AMP:0.10 C:1.08 AMP(A):0.105558 Hz: AMP:0.08 C:1.07 AMP(A):0.085634 Hz: AMP:0.11 C:1.06 AMP(A):0.115709 Hz: AMP:0.08 C:1.05 AMP(A):0.085784 Hz: AMP:0.14 C:1.04 AMP(A):0.145859 Hz: AMP:0.06 C:1.03 AMP(A):0.065934 Hz: AMP:0.09 C:1.02 AMP(A):0.096009 Hz: AMP:0.00 C:1.01 AMP(A):0.006084 Hz: AMP:0.10 C:1.00 AMP(A):0.106159 Hz: AMP:0.00 C:0.99 AMP(A):0.006235 Hz: AMP:0.03 C:0.98 AMP(A):0.036310 Hz: AMP:0.06 C:0.97 AMP(A):0.066385 Hz: AMP:0.00 C:0.96 AMP(A):0.006460 Hz: AMP:0.03 C:0.95 AMP(A):0.026535 Hz: AMP:0.06 C:0.94 AMP(A):0.066610 Hz: AMP:0.05 C:0.94 AMP(A):0.056685 Hz: AMP:0.05 C:0.93 AMP(A):0.056760 Hz: AMP:0.14 C:0.92 AMP(A):0.126836 Hz: AMP:0.10 C:0.91 AMP(A):0.096911 Hz: AMP:0.12 C:0.90 AMP(A):0.116986 Hz: AMP:0.06 C:0.89 AMP(A):0.057061 Hz: AMP:0.08 C:0.88 AMP(A):0.077136 Hz: AMP:0.03 C:0.87 AMP(A):0.027211 Hz: AMP:0.10 C:0.86 AMP(A):0.097286 Hz: AMP:0.06 C:0.85 AMP(A):0.057361 Hz: AMP:0.09 C:0.84 AMP(A):0.077436 Hz: AMP:0.00 C:0.83 AMP(A):0.007512 Hz: AMP:0.03 C:0.83 AMP(A):0.027587 Hz: AMP:0.00 C:0.82 AMP(A):0.007662 Hz: AMP:0.05 C:0.81 AMP(A):0.047737 Hz: AMP:0.03 C:0.80 AMP(A):0.027812 Hz: AMP:0.11 C:0.79 AMP(A):0.087887 Hz: AMP:0.05 C:0.78 AMP(A):0.047962 Hz: AMP:0.08 C:0.77 AMP(A):0.068037 Hz: AMP:0.05 C:0.76 AMP(A):0.048113 Hz: AMP:0.00 C:0.76 AMP(A):0.008188 Hz: AMP:0.08 C:0.75 AMP(A):0.068263 Hz: AMP:0.03 C:0.74 AMP(A):0.028338 Hz: AMP:0.00 C:0.73 AMP(A):0.008413 Hz: AMP:0.00 C:0.72 AMP(A):0.008488 Hz: AMP:0.05 C:0.71 AMP(A):0.048563 Hz: AMP:0.00 C:0.71 AMP(A):0.008638 Hz: AMP:0.00 C:0.70 AMP(A):0.008714 Hz: AMP:0.06 C:0.69 AMP(A):0.048789 Hz: AMP:0.06 C:0.68 AMP(A):0.048864 Hz: AMP:0.06 C:0.67 AMP(A):0.048939 Hz: AMP:0.10 C:0.67 AMP(A):0.079014 Hz: AMP:0.09 C:0.66 AMP(A):0.069089 Hz: AMP:0.11 C:0.65 AMP(A):0.079164 Hz: AMP:0.10 C:0.64 AMP(A):0.069239 Hz: AMP:0.06 C:0.64 AMP(A):0.049315 Hz: AMP:0.06 C:0.63 AMP(A):0.049390 Hz: AMP:0.06 C:0.62 AMP(A):0.049465 Hz: AMP:0.00 C:0.61 AMP(A):0.009540 Hz: AMP:0.06 C:0.61 AMP(A):0.04`
:(
Post by: PieterP on Jun 20, 2018, 08:31 pm
Post by: Noisecontrol on Jun 20, 2018, 08:52 pm
I want to know in th source code ,amplitude that caculated is in range 0 to 1023 or Not
Post by: PieterP on Jun 20, 2018, 09:11 pm
No. It's in the documentation (http://wiki.openmusiclabs.com/wiki/FHTFunctions).
Post by: Noisecontrol on Jun 20, 2018, 10:02 pm
Why in the sin wave example code if amplitude multiplay 2 it become equal peak amplitude .
Do in this code if amplitude *2 it become peak amp?
Post by: PieterP on Jun 20, 2018, 10:52 pm
Post by: Noisecontrol on Jun 22, 2018, 02:24 pm
Hello pieter
I change code to this and use 3.3 V of ardino pin

Code: [Select]
`#define LIN_OUT 1 // use the log output function#define FHT_N 256 // set to 256 point fht#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#include <FHT.h> // include the libraryconst double a12200 = pow(12200,2);const double a206 = pow(20.6,2);const double a1077 = pow(107.7,2);const double a7379 = pow(737.9,2);const double CORR = 0;const int GAIN = 1;int f;double RA,CF,f2,f4,C,ADCNUM;void setup() {  Serial.begin(115200); // use the serial port  ADCSRB = 0; // Free running mode  ADMUX = (DEFAULT << 6) | 0; // A0  sbi(ADCSRA, ADEN); // Enable ADC  sbi(ADCSRA, ADATE); // Auto trigger  sbi(ADCSRA, ADSC); // Start conversion  // 19.231 kHz  sbi(ADCSRA, ADPS2);  sbi(ADCSRA, ADPS1);  cbi(ADCSRA, ADPS0);}void loop() { do {    cli();  // UDRE interrupt slows this way down on arduino1.0    for (int i = 0 ; i < FHT_N ; i++) { // save 256 samples      while (!(ADCSRA & _BV(ADIF))); // wait for adc to be ready      sbi(ADCSRA, ADIF); // Clear interrupt flag      byte m = ADCL; // fetch adc data      byte j = ADCH;      int k = (j << 8) | m; // form into an int      k -= 0x0200; // form into a signed int      k <<= 6; // form into a 16b signed int      fht_input[i] = k; // put re3l 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_lin(); // take the output of the fht    sei();    for (uint8_t i = 0 ; i < FHT_N / 2 ; i++) {      f=i * 19231UL / FHT_N;      Serial.print(f);      Serial.print(" HZ:");      Serial.println(fht_lin_out[i]); // send out the data    }  } while(0);  while(1);}`

Result is for frequency 1051 Hz is 2928

Code: [Select]
`0 HZ:1600075 HZ:7936150 HZ:23225 HZ:36300 HZ:6375 HZ:11450 HZ:9525 HZ:30600 HZ:20676 HZ:30751 HZ:4826 HZ:19901 HZ:59976 HZ:16641051 HZ:29281126 HZ:12961201 HZ:291277 HZ:201352 HZ:171427 HZ:311502 HZ:101577 HZ:211652 HZ:201727 HZ:241802 HZ:111878 HZ:141953 HZ:462028 HZ:7802103 HZ:12242178 HZ:4682253 HZ:232328 HZ:172403 HZ:72478 HZ:52554 HZ:122629 HZ:132704 HZ:192779 HZ:172854 HZ:122929 HZ:153004 HZ:133079 HZ:813155 HZ:1303230 HZ:543305 HZ:123380 HZ:263455 HZ:203530 HZ:383605 HZ:173680 HZ:363756 HZ:323831 HZ:203906 HZ:133981 HZ:44056 HZ:554131 HZ:3704206 HZ:4684281 HZ:1354357 HZ:264432 HZ:164507 HZ:164582 HZ:74657 HZ:264732 HZ:274807 HZ:134882 HZ:34957 HZ:125033 HZ:85108 HZ:285183 HZ:1785258 HZ:1975333 HZ:465408 HZ:85483 HZ:95558 HZ:265634 HZ:465709 HZ:175784 HZ:95859 HZ:265934 HZ:66009 HZ:96084 HZ:16159 HZ:206235 HZ:726310 HZ:746385 HZ:106460 HZ:136535 HZ:116610 HZ:366685 HZ:256760 HZ:356836 HZ:206911 HZ:296986 HZ:67061 HZ:177136 HZ:137211 HZ:197286 HZ:597361 HZ:527436 HZ:27512 HZ:177587 HZ:77662 HZ:127737 HZ:447812 HZ:427887 HZ:67962 HZ:68037 HZ:58113 HZ:88188 HZ:88263 HZ:208338 HZ:448413 HZ:298488 HZ:18563 HZ:38638 HZ:98714 HZ:448789 HZ:518864 HZ:188939 HZ:109014 HZ:149089 HZ:129164 HZ:89239 HZ:109315 HZ:319390 HZ:369465 HZ:179540 HZ:9`

I dont know how this number change to voltage

Post by: PieterP on Jun 22, 2018, 03:23 pm
I dont know how this number change to voltage
No. I cannot keep on holding your hand like this. I already gave you the formulas you need, and the documentation of the FHT library tells you what the different functions do to the output, how to interpret it, and the mathematical formulas used to calculate these results.
Post by: Noisecontrol on Jun 22, 2018, 06:58 pm
Why k value in above code is biger than 1024?
Code: [Select]
`fht_input[i] = k; // put real data into bins`
Post by: PieterP on Jun 22, 2018, 07:05 pm
Write down mathematically what happens with k, then you know why.
Post by: Noisecontrol on Jun 22, 2018, 08:44 pm
Write down mathematically what happens with k, then you know why.
I wish to have good math
I have to leave this project after one month effort .it doesnt have any thrive
Post by: PieterP on Jun 22, 2018, 08:47 pm
Whining about it won't help. Trying will.
Post by: Noisecontrol on Jun 23, 2018, 04:22 am
I think k is 16 bit thus range of it is 0 to 65536
Thus per 1 ADC  is equal voltage/65536
For example for 5 volt is equal 0.000076 volt
Is it true?