Title: **Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 12:02 pm**

Post by:

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?

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?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 12:15 pm**

Post by:

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

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

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 12:37 pm**

Post by:

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?

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?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 01:00 pm**

Post by:

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.

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

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?Parseval's theorem states that the energy in the time domain is the same as the energy in the frequency domain.

How can i calculate ADC in per bin?

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

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 01:22 pm**

Post by:

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

I must magnitude divid to 64 to be actual magnitude in per bin?

Please say one example to do it

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 01:28 pm**

Post by:

Your means is if my 2n=128Yes.

I must magnitude divid to 64 to be actual magnitude in per bin?

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?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 02:07 pm**

Post by:

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

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

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 02:28 pm**

Post by:

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?

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?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 02:36 pm**

Post by:

20 log(x) = 10 log(x²)).

X is magnitude?

X is magnitude?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 02:37 pm**

Post by:

Yes. But that's a mathematical identity that holds true for all (positive) x.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 02:43 pm**

Post by:

0.0063 get from sensivity of microphone

If mic sensivity be -44dBV the by under equiption you can calculated

If mic sensivity be -44dBV the by under equiption you can calculated

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 02:48 pm**

Post by:

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

Keep in mind that 20 log(x/y) = 10 log(x²) - 20 log(y).

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 02:51 pm**

Post by:

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?

If i convert adc to dB and then do fft on it

Does magnitude is equal dB in per bin?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 02:58 pm**

Post by:

Like this

K=analogread(A0)

Vrms=(k*5/1023)*0.707

dB=20log(Vrms/0.0063)+94-44-gain

Then dB enter fft lib and show dB per bin

K=analogread(A0)

Vrms=(k*5/1023)*0.707

dB=20log(Vrms/0.0063)+94-44-gain

Then dB enter fft lib and show dB per bin

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 03:01 pm**

Post by:

I think it is difficultThat 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.

If i convert adc to dB and then do fft on it

Does magnitude is equal dB in per bin?

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 03:10 pm**

Post by:

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

??

That souce code show magnitude for me

Do that value magnitude set in this equiption?

dB=10log(magnitude^2)-c

??

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 03:15 pm**

Post by:

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.

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

Note that this function calculates the square root. Don't do that, it's unnecessary.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 03:18 pm**

Post by:

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?

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?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 03:23 pm**

Post by:

Yes. But instead of calculating magnitude[k] ² as sqrt(vReal[k]² + vImag[k]²)², calculate it directly as vReal[k]² + vImag[k]².

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 03:25 pm**

Post by:

Is this a personal project? Is it an assignment for your studies? What's your background in mathematics and DSP?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 03:30 pm**

Post by:

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

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

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 05, 2018, 03:35 pm**

Post by:

Why in 0 Hz magnitude is maximum and in low frequency magnitude is greater than middle and hight frequency ?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 03:36 pm**

Post by:

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.

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.

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 05, 2018, 03:37 pm**

Post by:

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

Title: **Re: Question about magnitude**

Post by:**DVDdoug** on **Jun 05, 2018, 07:51 pm**

Post by:

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

Title: **Re: Question about magnitude**

Post by:**MarkT** on **Jun 05, 2018, 11:30 pm**

Post by:

I think it is difficultYou _cannot_ convert to dB before the FFT, the FFT is a linear operation on voltages.

If i convert adc to dB and then do fft on it

Does magnitude is equal dB in per bin?

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

Title: **Re: Question about magnitude**

Post by:**DVDdoug** on **Jun 06, 2018, 03:29 am**

Post by:

Quote

The reason is the wavelength of low frequencies is larger, nothing to do with the averageI'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.

power spectral density of music since speakers can reproduce any signal and are ideally

flat response across the band.

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 06, 2018, 09:36 am**

Post by:

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)

You might find people who know more about this topic than myself on StackOverflow Signal Processing.

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)

You might find people who know more about this topic than myself on StackOverflow Signal Processing.

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 06, 2018, 10:41 am**

Post by:

Here's some MATLAB/Octave code that may help you to get an idea of what's going on:

Output:

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)

Code: [Select]

`close all;`

nb_samples = 128; % 128 samples → 128 frequency bins

n = (0:nb_samples-1)';

f_s = 256; % 256 Hz sample frequency

f_1 = 32; % Sine wave with a frequency of 32 Hz

A_1 = 1; % and amplitude of 1

f_2 = 60; % Sine wave with a frequency of 60 Hz

A_2 = 0.5; % and amplitude of 0.5

t = n / f_s; % Generate a vector with time

sine_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 window

fft_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 window

window = 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)

Title: **Re: Question about magnitude**

Post by:**MarkT** on **Jun 06, 2018, 01:15 pm**

Post by:

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**

Post by:

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 ?

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**

Post by:

Quote

Maximum adc is 1024No, 1023.

Title: **Fft result to voltage**

Post by:**Noisecontrol** on **Jun 14, 2018, 03:50 pm**

Post by:

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**

Post by:

...fft result ...¿Fast Fourier Transform?

Title: **Re: Fft result to voltage**

Post by:**Noisecontrol** on **Jun 14, 2018, 04:02 pm**

Post by:

¿Fast Fourier Transform?Yes

Title: **Re: Fft result to voltage**

Post by:**DVDdoug** on **Jun 14, 2018, 04:41 pm**

Post by:

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.

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**

Post by:

I didnt find any documantion about convert fft results to adc or voltage in google.

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

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**

Post by:

Quote

I didnt find any documantion about convert fft results to adc or voltage in google.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**

Post by:

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 library

void 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 amplitude

0 1000

1 0

2 0

3 0

4 0

5 0

6 0

7 0

8 0

9 0

10 0

11 0

12 0

13 0

14 0

15 0

Done

Title: **Re: Fft result to voltage**

Post by:**Noisecontrol** on **Jun 14, 2018, 06:21 pm**

Post by:

Presumably you mean DAC, which standard Arduinos do not have, but why would anyone bother to document something so simple?No i want to convert fft results in per bin to voltageCode: [Select]`analogWrite(pin,bin_value);`

Title: **Re: Fft result to voltage**

Post by:**jremington** on **Jun 14, 2018, 06:31 pm**

Post by:

Quote

No i want to convert fft results in per bin to voltageExplain 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**

Post by:

We've been over this in your previous thread (http://forum.arduino.cc/index.php?topic=551490.15).

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

Please don't cross-post!

You have to correct for a couple of things:

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.

Here's the result:

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

If you want the RMS voltage, I already gave you the formula in your previous thread.

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

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

Please don't cross-post!

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]

`%% Setup`

close all;

N = 128; % 128 samples → 128 frequency bins

samples = (0:N-1)';

f_s = 256; % 256 Hz sample frequency

f = 64; % Sine wave with a frequency of 64 Hz

A = 1.25; % and amplitude of 1.25 V peak

V_bias = 2.5;

V_ref = 5;

ADC_bits = 10;

ADC_factor = 2^ADC_bits;

t = samples / f_s; % Generate a vector with time

sine_V = A*sin(2*pi*f*t); % Sine wave in volts

sine_V = sine_V + V_bias; % Bias

sine = sine_V * ADC_factor / V_ref; % Sine wave as sampled by the Arduino

subplot(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 correction

sine = sine - V_bias * ADC_factor / V_ref; % Subtract bias again

%% Windowing

window = hamming(N);

mean_window = mean(window);

windowed_sine = window.*sine; % Apply window function

subplot(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])

%% FFT

fft_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 want the RMS voltage, I already gave you the formula in your previous thread.

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

Title: **Re: Question about magnitude**

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

Post by:

Threads merged. Again.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 14, 2018, 08:17 pm**

Post by:

You have to correct for a couple of things:If you have source code of this process for arduino please share it.

- 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)

I dont know MATLAB code

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 14, 2018, 08:38 pm**

Post by:

If you have source code of this process for arduino please share it.I don't have the Arduino code for this, and I can't test it.

I dont know MATLAB code

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 14, 2018, 09:42 pm**

Post by:

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?

Adc factor how calculated?

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?

Adc factor how calculated?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 14, 2018, 10:25 pm**

Post by:

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.

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 14, 2018, 10:49 pm**

Post by:

For calculate mean window i must get avarage Vreal of window function ?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 14, 2018, 11:01 pm**

Post by:

The window function is real by definition. But yes.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 14, 2018, 11:37 pm**

Post by:

Please explain about fft_sin

Is fft _sin complex number like A+jB?

Is fft _sin complex number like A+jB?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 14, 2018, 11:41 pm**

Post by:

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.

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 12:05 am**

Post by:

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

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

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 12:07 am**

Post by:

It is the magnitude of the results of the FFT.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 08:02 am**

Post by:

Then magnitude per bin is equal to sin_fft

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 09:05 am**

Post by:

Yes.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 09:25 am**

Post by:

About ADC reference voltage,

I use arduino uno and i want to use 5 volt pin

How much is v_ref?

I use arduino uno and i want to use 5 volt pin

How much is v_ref?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 09:38 am**

Post by:

Then V_ref is 5V.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 09:52 am**

Post by:

After calculating correct_fft, the value of correct_fft will be in terms of voltage in per bin?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 10:01 am**

Post by:

Yes. But because of windowing and discretization, you'll get non-zero values in neighboring bins.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 10:22 am**

Post by:

Yes. But because of windowing and discretization, you'll get non-zero values in neighboring bins.I didnt understand you

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 10:38 am**

Post by:

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 10:45 am**

Post by:

Understood your means

What is reason of it?

What is reason of it?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 10:51 am**

Post by:

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?

Are you still trying to do A-weighting?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 10:54 am**

Post by:

Maybe because of a slight oscillation in the main frequency. If the distance between frequencies increases, this problem can be solved

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 11:00 am**

Post by:

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

I try and show my code to you to help me about it

Thanks a lot

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 11:13 am**

Post by:

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.

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 11:27 am**

Post by:

I find a circuit for a weighting

Is it your means?

Is it your means?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 11:41 am**

Post by:

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

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 11:51 am**

Post by:

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 12:34 pm**

Post by:

How a android mobile do digital filter?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 15, 2018, 12:43 pm**

Post by:

Probably using cascaded digital BiQuad filters.

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.

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 12:59 pm**

Post by:

Can do it by aurdino?

How can i find sample of it in arduino code?

How can i find sample of it in arduino code?

Title: **Re: Question about magnitude**

Post by:**MarkT** on **Jun 15, 2018, 02:01 pm**

Post by:

Understood your meansThe fourier transform is only mathematically defined for periodic waveforms (that repeat for ever)

What is reason of it?

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

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 15, 2018, 03:30 pm**

Post by:

Can do bilinear transform by aurdino?

How can i find sample of it in arduino code?

How can i find sample of it in arduino code?

Title: **Re: Question about magnitude**

Post by:**MarkT** on **Jun 15, 2018, 03:43 pm**

Post by:

Can do bilinear transform by aurdino?No, you do this as filter design time - the easiest way to design digital filters

How can i find sample of it in arduino code?

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.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 17, 2018, 09:03 pm**

Post by:

Hello peiter

I do that formula but didnt convert magnitude to voltage

I do that formula but didnt convert magnitude to voltage

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 17, 2018, 09:06 pm**

Post by:

There's nothing I can do without more information. Post your exact code.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 19, 2018, 06:01 pm**

Post by:

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!!!

And output

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 library

void 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 amplitude

0 2

1 0

2 0

3 0

4 2

5 0

6 0

7 0

8 1

9 0

10 0

11 0

12 2

13 0

14 0

15 0

16 0

17 0

18 0

19 0

20 500

21 0

22 0

23 0

24 1

25 0

26 0

27 0

28 0

29 0

30 0

31 0

Done

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 19, 2018, 06:09 pm**

Post by:

The result is correct, your original sine wave is not. You have to divide by the sampling rate, not by the number of samples.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 19, 2018, 06:17 pm**

Post by:

Please write equiption of it for calculate frequency

Where sin wave is not corrected?

Where sin wave is not corrected?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 19, 2018, 06:20 pm**

Post by:

It's in the MATLAB script already.

In Arduino code:

In Arduino code:

Code: [Select]

`int k = 1000 * sin(2*PI*f1*i/19200.0);`

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 19, 2018, 06:27 pm**

Post by:

Thanks a lot it is ok

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 19, 2018, 07:49 pm**

Post by:

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?

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 library

void 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);

}

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 19, 2018, 09:30 pm**

Post by:

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:

By the way, you need a strong anti-aliasing filter, especially at these low sampling rates.

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 library

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

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 19, 2018, 10:11 pm**

Post by:

Filter For what range frequency to remve?

What is UL in calculate frequncy that you wrote?

What is UL in calculate frequncy that you wrote?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 19, 2018, 10:19 pm**

Post by:

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.

UL means unsigned long. An int would overflow.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 20, 2018, 08:10 pm**

Post by:

Hello

Peiter thanks for your help

Your code was correct

Now i could calculated correction factor for in per bin and convert dB to dBA

:(

Peiter thanks for your help

Your code was correct

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

75 Hz: AMP:0.60 C:0.00 AMP(A):0.00

150 Hz: AMP:0.20 C:0.04 AMP(A):0.01

225 Hz: AMP:0.12 C:0.11 AMP(A):0.01

300 Hz: AMP:0.10 C:0.20 AMP(A):0.02

375 Hz: AMP:0.12 C:0.30 AMP(A):0.04

450 Hz: AMP:0.12 C:0.40 AMP(A):0.05

525 Hz: AMP:0.00 C:0.51 AMP(A):0.00

600 Hz: AMP:0.09 C:0.61 AMP(A):0.05

676 Hz: AMP:0.11 C:0.70 AMP(A):0.08

751 Hz: AMP:0.06 C:0.78 AMP(A):0.05

826 Hz: AMP:0.11 C:0.86 AMP(A):0.09

901 Hz: AMP:0.00 C:0.92 AMP(A):0.00

976 Hz: AMP:0.36 C:0.98 AMP(A):0.36

1051 Hz: AMP:0.41 C:1.03 AMP(A):0.42

1126 Hz: AMP:0.35 C:1.08 AMP(A):0.38

1201 Hz: AMP:0.11 C:1.12 AMP(A):0.13

1277 Hz: AMP:0.13 C:1.15 AMP(A):0.15

1352 Hz: AMP:0.09 C:1.18 AMP(A):0.10

1427 Hz: AMP:0.15 C:1.21 AMP(A):0.18

1502 Hz: AMP:0.14 C:1.23 AMP(A):0.17

1577 Hz: AMP:0.11 C:1.25 AMP(A):0.14

1652 Hz: AMP:0.14 C:1.27 AMP(A):0.17

1727 Hz: AMP:0.05 C:1.28 AMP(A):0.07

1802 Hz: AMP:0.10 C:1.29 AMP(A):0.13

1878 Hz: AMP:0.09 C:1.31 AMP(A):0.11

1953 Hz: AMP:0.08 C:1.31 AMP(A):0.10

2028 Hz: AMP:0.10 C:1.32 AMP(A):0.13

2103 Hz: AMP:0.03 C:1.33 AMP(A):0.03

2178 Hz: AMP:0.08 C:1.33 AMP(A):0.11

2253 Hz: AMP:0.12 C:1.34 AMP(A):0.16

2328 Hz: AMP:0.00 C:1.34 AMP(A):0.00

2403 Hz: AMP:0.14 C:1.34 AMP(A):0.19

2478 Hz: AMP:0.03 C:1.34 AMP(A):0.03

2554 Hz: AMP:0.06 C:1.34 AMP(A):0.08

2629 Hz: AMP:0.06 C:1.34 AMP(A):0.08

2704 Hz: AMP:0.00 C:1.34 AMP(A):0.00

2779 Hz: AMP:0.06 C:1.34 AMP(A):0.08

2854 Hz: AMP:0.00 C:1.33 AMP(A):0.00

2929 Hz: AMP:0.11 C:1.33 AMP(A):0.15

3004 Hz: AMP:0.05 C:1.33 AMP(A):0.07

3079 Hz: AMP:0.15 C:1.32 AMP(A):0.20

3155 Hz: AMP:0.12 C:1.32 AMP(A):0.16

3230 Hz: AMP:0.10 C:1.31 AMP(A):0.13

3305 Hz: AMP:0.00 C:1.31 AMP(A):0.00

3380 Hz: AMP:0.09 C:1.30 AMP(A):0.11

3455 Hz: AMP:0.06 C:1.30 AMP(A):0.08

3530 Hz: AMP:0.11 C:1.29 AMP(A):0.15

3605 Hz: AMP:0.05 C:1.29 AMP(A):0.07

3680 Hz: AMP:0.03 C:1.28 AMP(A):0.03

3756 Hz: AMP:0.10 C:1.27 AMP(A):0.12

3831 Hz: AMP:0.00 C:1.27 AMP(A):0.00

3906 Hz: AMP:0.10 C:1.26 AMP(A):0.13

3981 Hz: AMP:0.06 C:1.25 AMP(A):0.08

4056 Hz: AMP:0.10 C:1.24 AMP(A):0.13

4131 Hz: AMP:0.08 C:1.24 AMP(A):0.10

4206 Hz: AMP:0.09 C:1.23 AMP(A):0.11

4281 Hz: AMP:0.06 C:1.22 AMP(A):0.07

4357 Hz: AMP:0.08 C:1.21 AMP(A):0.10

4432 Hz: AMP:0.10 C:1.20 AMP(A):0.12

4507 Hz: AMP:0.08 C:1.19 AMP(A):0.09

4582 Hz: AMP:0.11 C:1.19 AMP(A):0.13

4657 Hz: AMP:0.00 C:1.18 AMP(A):0.00

4732 Hz: AMP:0.06 C:1.17 AMP(A):0.07

4807 Hz: AMP:0.00 C:1.16 AMP(A):0.00

4882 Hz: AMP:0.06 C:1.15 AMP(A):0.07

4957 Hz: AMP:0.00 C:1.14 AMP(A):0.00

5033 Hz: AMP:0.00 C:1.13 AMP(A):0.00

5108 Hz: AMP:0.05 C:1.12 AMP(A):0.06

5183 Hz: AMP:0.10 C:1.11 AMP(A):0.11

5258 Hz: AMP:0.14 C:1.10 AMP(A):0.16

5333 Hz: AMP:0.00 C:1.10 AMP(A):0.00

5408 Hz: AMP:0.03 C:1.09 AMP(A):0.03

5483 Hz: AMP:0.10 C:1.08 AMP(A):0.10

5558 Hz: AMP:0.08 C:1.07 AMP(A):0.08

5634 Hz: AMP:0.11 C:1.06 AMP(A):0.11

5709 Hz: AMP:0.08 C:1.05 AMP(A):0.08

5784 Hz: AMP:0.14 C:1.04 AMP(A):0.14

5859 Hz: AMP:0.06 C:1.03 AMP(A):0.06

5934 Hz: AMP:0.09 C:1.02 AMP(A):0.09

6009 Hz: AMP:0.00 C:1.01 AMP(A):0.00

6084 Hz: AMP:0.10 C:1.00 AMP(A):0.10

6159 Hz: AMP:0.00 C:0.99 AMP(A):0.00

6235 Hz: AMP:0.03 C:0.98 AMP(A):0.03

6310 Hz: AMP:0.06 C:0.97 AMP(A):0.06

6385 Hz: AMP:0.00 C:0.96 AMP(A):0.00

6460 Hz: AMP:0.03 C:0.95 AMP(A):0.02

6535 Hz: AMP:0.06 C:0.94 AMP(A):0.06

6610 Hz: AMP:0.05 C:0.94 AMP(A):0.05

6685 Hz: AMP:0.05 C:0.93 AMP(A):0.05

6760 Hz: AMP:0.14 C:0.92 AMP(A):0.12

6836 Hz: AMP:0.10 C:0.91 AMP(A):0.09

6911 Hz: AMP:0.12 C:0.90 AMP(A):0.11

6986 Hz: AMP:0.06 C:0.89 AMP(A):0.05

7061 Hz: AMP:0.08 C:0.88 AMP(A):0.07

7136 Hz: AMP:0.03 C:0.87 AMP(A):0.02

7211 Hz: AMP:0.10 C:0.86 AMP(A):0.09

7286 Hz: AMP:0.06 C:0.85 AMP(A):0.05

7361 Hz: AMP:0.09 C:0.84 AMP(A):0.07

7436 Hz: AMP:0.00 C:0.83 AMP(A):0.00

7512 Hz: AMP:0.03 C:0.83 AMP(A):0.02

7587 Hz: AMP:0.00 C:0.82 AMP(A):0.00

7662 Hz: AMP:0.05 C:0.81 AMP(A):0.04

7737 Hz: AMP:0.03 C:0.80 AMP(A):0.02

7812 Hz: AMP:0.11 C:0.79 AMP(A):0.08

7887 Hz: AMP:0.05 C:0.78 AMP(A):0.04

7962 Hz: AMP:0.08 C:0.77 AMP(A):0.06

8037 Hz: AMP:0.05 C:0.76 AMP(A):0.04

8113 Hz: AMP:0.00 C:0.76 AMP(A):0.00

8188 Hz: AMP:0.08 C:0.75 AMP(A):0.06

8263 Hz: AMP:0.03 C:0.74 AMP(A):0.02

8338 Hz: AMP:0.00 C:0.73 AMP(A):0.00

8413 Hz: AMP:0.00 C:0.72 AMP(A):0.00

8488 Hz: AMP:0.05 C:0.71 AMP(A):0.04

8563 Hz: AMP:0.00 C:0.71 AMP(A):0.00

8638 Hz: AMP:0.00 C:0.70 AMP(A):0.00

8714 Hz: AMP:0.06 C:0.69 AMP(A):0.04

8789 Hz: AMP:0.06 C:0.68 AMP(A):0.04

8864 Hz: AMP:0.06 C:0.67 AMP(A):0.04

8939 Hz: AMP:0.10 C:0.67 AMP(A):0.07

9014 Hz: AMP:0.09 C:0.66 AMP(A):0.06

9089 Hz: AMP:0.11 C:0.65 AMP(A):0.07

9164 Hz: AMP:0.10 C:0.64 AMP(A):0.06

9239 Hz: AMP:0.06 C:0.64 AMP(A):0.04

9315 Hz: AMP:0.06 C:0.63 AMP(A):0.04

9390 Hz: AMP:0.06 C:0.62 AMP(A):0.04

9465 Hz: AMP:0.00 C:0.61 AMP(A):0.00

9540 Hz: AMP:0.06 C:0.61 AMP(A):0.04

:(

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 20, 2018, 08:31 pm**

Post by:

What is your question?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 20, 2018, 08:52 pm**

Post by:

I want to know in th source code ,amplitude that caculated is in range 0 to 1023 or Not

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 20, 2018, 09:11 pm**

Post by:

No. It's in the documentation (http://wiki.openmusiclabs.com/wiki/FHTFunctions).

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 20, 2018, 10:02 pm**

Post by:

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?

Do in this code if amplitude *2 it become peak amp?

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 20, 2018, 10:52 pm**

Post by:

I don't understand your question.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 22, 2018, 02:24 pm**

Post by:

Hello pieter

I change code to this and use 3.3 V of ardino pin

Result is for frequency 1051 Hz is 2928

I dont know how this number change to voltage

Please help me and say what is furmula for do it and write it for me

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 library

const 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:16000

75 HZ:7936

150 HZ:23

225 HZ:36

300 HZ:6

375 HZ:11

450 HZ:9

525 HZ:30

600 HZ:20

676 HZ:30

751 HZ:4

826 HZ:19

901 HZ:59

976 HZ:1664

1051 HZ:2928

1126 HZ:1296

1201 HZ:29

1277 HZ:20

1352 HZ:17

1427 HZ:31

1502 HZ:10

1577 HZ:21

1652 HZ:20

1727 HZ:24

1802 HZ:11

1878 HZ:14

1953 HZ:46

2028 HZ:780

2103 HZ:1224

2178 HZ:468

2253 HZ:23

2328 HZ:17

2403 HZ:7

2478 HZ:5

2554 HZ:12

2629 HZ:13

2704 HZ:19

2779 HZ:17

2854 HZ:12

2929 HZ:15

3004 HZ:13

3079 HZ:81

3155 HZ:130

3230 HZ:54

3305 HZ:12

3380 HZ:26

3455 HZ:20

3530 HZ:38

3605 HZ:17

3680 HZ:36

3756 HZ:32

3831 HZ:20

3906 HZ:13

3981 HZ:4

4056 HZ:55

4131 HZ:370

4206 HZ:468

4281 HZ:135

4357 HZ:26

4432 HZ:16

4507 HZ:16

4582 HZ:7

4657 HZ:26

4732 HZ:27

4807 HZ:13

4882 HZ:3

4957 HZ:12

5033 HZ:8

5108 HZ:28

5183 HZ:178

5258 HZ:197

5333 HZ:46

5408 HZ:8

5483 HZ:9

5558 HZ:26

5634 HZ:46

5709 HZ:17

5784 HZ:9

5859 HZ:26

5934 HZ:6

6009 HZ:9

6084 HZ:1

6159 HZ:20

6235 HZ:72

6310 HZ:74

6385 HZ:10

6460 HZ:13

6535 HZ:11

6610 HZ:36

6685 HZ:25

6760 HZ:35

6836 HZ:20

6911 HZ:29

6986 HZ:6

7061 HZ:17

7136 HZ:13

7211 HZ:19

7286 HZ:59

7361 HZ:52

7436 HZ:2

7512 HZ:17

7587 HZ:7

7662 HZ:12

7737 HZ:44

7812 HZ:42

7887 HZ:6

7962 HZ:6

8037 HZ:5

8113 HZ:8

8188 HZ:8

8263 HZ:20

8338 HZ:44

8413 HZ:29

8488 HZ:1

8563 HZ:3

8638 HZ:9

8714 HZ:44

8789 HZ:51

8864 HZ:18

8939 HZ:10

9014 HZ:14

9089 HZ:12

9164 HZ:8

9239 HZ:10

9315 HZ:31

9390 HZ:36

9465 HZ:17

9540 HZ:9

I dont know how this number change to voltage

Please help me and say what is furmula for do it and write it for me

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 22, 2018, 03:23 pm**

Post by:

I dont know how this number change to voltageNo. 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.

Please help me and say what is furmula for do it and write it for me

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 22, 2018, 06:58 pm**

Post by:

Why k value in above code is biger than 1024?

Code: [Select]

fht_input[i] = k; // put real data into bins

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 22, 2018, 07:05 pm**

Post by:

Write down mathematically what happens with k, then you know why.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 22, 2018, 08:44 pm**

Post by:

Write down mathematically what happens with k, then you know why.My math is bad

I wish to have good math

I have to leave this project after one month effort .it doesnt have any thrive

Title: **Re: Question about magnitude**

Post by:**PieterP** on **Jun 22, 2018, 08:47 pm**

Post by:

Whining about it won't help. Trying will.

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Jun 23, 2018, 04:22 am**

Post by:

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?

Thus per 1 ADC is equal voltage/65536

For example for 5 volt is equal 0.000076 volt

Is it true?

Title: **Re: Question about magnitude**

Post by:**Noisecontrol** on **Aug 05, 2018, 08:27 pm**

Post by:

Hello

Finally make sound level meter after 4 month

It show dBA

Leq

Sone

Phone

Ta

NRR

O

Finally make sound level meter after 4 month

It show dBA

Leq

Sone

Phone

Ta

NRR

O