Arduino FFT库
Arduino FFT (FAST FOURIER TRANSFORM 快速傅里叶变换 )Library
Notes:
- For a fasher frequency analysis library, check out the FHT!
- The serial output of the examples is in binary, not ASCII. This means it will not be human readable on the serial port. Change serial.write() to serial.print() to fix this. You may need to write a for() loop to manually output each frequency bin.
About the Arduino FFT Library
The Arduino FFT library is a fast implementation of a standard FFT algorithm which operates on only real data. It can give you up to 256 frequency bins at 16b depth, at a minimum of ~7ms update rate. It is adjustable from 16 to 256 bins, and has several output methods to suit various needs. It can be set to 16b linear, 8b linear, 8b logarithmic, or 8b octave output. All of these different modes are detailed in the read_me file (inside the FFT library folder). Since it takes in 16b, fixed point numbers, it has a noise floor of around -72dB in the low frequencies, and -76dB in the high frequencies. When using the onboard ADC, the ADC's noise floor is on the same order as the FFT's noise floor, giving somewhere between a 9b and 10b SNR (-55dB).
Examples
- - XX :
Arduino_FFT Functions
- fft_run() - This is the main FFT function call. It takes no variables and returns no variables. It assumes there is a block of data already in SRAM, and that it is already re-ordered. The data is stored in array called fft_input[], which contains 2 16b values per FFT data point - one for real, the other for imaginary. If you are filling the array yourself, place the real values in the even bins, and the imaginary values in the odd bins. For example:
- fft_input[0] = real1, fft_input[1] = imaginary1
- fft_input[2] = real2, fft_input[3] = imaginary2
Therefore, there are 2 times as many points in the array as there are FFT bins. If you are using only real data (i.e. values sampled from the ADC), then put those values into the even numbered bins, and be sure to write 0 to the odd valued bins. The final output is kept in fft_input[], with the even bins being the real magnitudes, and the odd bins being the imaginary magnitudes. The bins are in sequence of increasing frequncy. For example:
- fft_input[0] & fft_input[1] = bin0 magnitudes (0hz -> Fs/N)
- fft_input[2] & fft_input[3] = bin1 magnitudes (Fs/N -> 2Fs/N)
You will have to run one of the magnitude functions to get useful data from these bins.
-这是主要的FFT函数调用。它不需要变量并且不返回任何变量。它假设SRAM中已经存在一个数据块,并且已经重新排序了。数据存储在名为fft_input []的阵列中,每个FFT数据点包含2个16b值,一个用于实数,另一个用于虚数。如果你自己填充数组,将真正的值放在均匀的分区中,并将奇数值中的虚数值。例如:
- fft_input[0] = real1, fft_input[1] = imaginary1
- fft_input[2] = real2, fft_input[3] = imaginary2
因此,阵列中有两倍的FFT分区。如果您仅使用实际数据(即从ADC采样的值),则将这些值放入均匀的数据箱中,并确保将0写入奇数值仓。最终输出保存在fft_input []中,偶数分数为真实幅度,奇数分数为虚数。垃圾箱按照频率递增的顺序。例如:
- fft_input[0] & fft_input[1] = bin0 magnitudes (0hz -> Fs/N)
- fft_input[2] & fft_input[3] = bin1 magnitudes (Fs/N -> 2Fs/N)
您将必须运行其中一个大小函数来从这些分区获取有用的数据。
- fft_reorder()
- This reorders the FFT inputs to get them ready for the special way in which the FFT algorithm processes data. Unless you do this yourself with another piece of code, you have to call this before running fft_run(). It takes no variables and returns no variables. This runs on the array fft_input[], so the data must be first filled into that array before this function is called.
- 这将对FFT输入进行重新排序,使其能够准备好FFT算法处理数据的特殊方式。 除非你自己使用另一段代码,否则你必须在运行fft_run()之前调用它。 它不需要变量并且不返回任何变量。 这在数组fft_input[]上运行,所以在调用此函数之前,必须首先将数据填充到该数组中。
- fft_window()
- This function multiplies the input data by a window function to help increase the frequency resolution of the FFT data. It takes no variables, and returns no variables. This processes the data in fft_input[], so that data must first be placed in that array before it is called. It must also be called before fft_reorder() or fft_run().
- 该功能将输入数据乘以窗口函数,以帮助增加FFT数据的频率分辨率。 它不需要任何变量,并且不返回变量。 这将处理fft_input []中的数据,因此在调用数据之前必须首先将数据放在该数组中。 它也必须在fft_reorder()或fft_run()之前调用。
- fft_mag_lin8()
- This gives the magnitude of each bin in the FFT. It sums the squares of the imaginary and real parts, and then takes the square root, rounding the answer to 8b precision (it uses a lookup table, and scales the values to fit the full 8b range. It takes no variables, and returns no variables. It operates on fft_input[], and returns the data in an array called fft_lin_out8[]. You can then use the data in fft_lin_out8[]. The magnitude is only calculated for the first N/2 bins, as the second half of an FFT is identical to the first half for all real inputs. Therefore, fft_lin_out8[] has N/2 8b values, with each index representing the bin order. For example:
- fft_lin_out8[0] = first bin magnitude (0hz -> Fs/N)
- fft_lin_out8[1] = second bin magnitude (Fs/N -> 2Fs/N)
The output can be scaled to maximize the resolution using the SCALE factor. See the #define section for more detials.
- 这给出了FFT中每个仓的幅度。 它将虚部和实部的平方相加,然后取平方根,将答案舍入到8b精度(它使用查找表,并将值缩放以适应完整的8b范围,不需要变量,不返回 变量,它在fft_input []上运行,并返回一个名为fft_lin_out8 []的数组,然后可以使用fft_lin_out8 []中的数据,仅对第一个N / 2 bin进行计算, FFT与所有实际输入的前半部分相同,因此fft_lin_out8 []具有N / 2个8b值,每个索引表示bin顺序,例如:
- fft_lin_out8[0] = first bin magnitude (0hz -> Fs/N)
- fft_lin_out8[1] = second bin magnitude (Fs/N -> 2Fs/N)
可以缩放输出以使用SCALE因子最大化分辨率。 有关更多的detials,请参阅下文#define部分。
- fft_mag_lin()
- This gives the magnitude of each bin in the FFT. It sums the squares of the imaginary and real, and then takes the square root. It uses a lookup table to calculate the square root, so it has limited precision. You can think of it as an 8b value times a 4b exponent. It covers the full 16b range, but only has 8b of precision at any point in that range. The data is taken in from fft_input[] and returned in fft_lin_out[]. The values are in sequential order, and there are only N/2 values total, as the FFT of a real signal is symetric about the center frequency.
- 这给出了FFT中每个仓的幅度。 它将虚拟和实数的平方相加,然后取平方根。 它使用查找表来计算平方根,因此精度有限。 你可以把它当成8b值乘以4b指数。 它覆盖了整个16b范围,但在该范围内的任何点只有8b的精度。 数据从fft_input []中获取,并在fft_lin_out []中返回。 这些值按顺序排列,总共只有N / 2个值,因为实际信号的FFT与中心频率相对应。
- fft_mag_log()
- This gives the magnitude of each bin in the FFT. It sums the squares of the imaginary and real, and then takes the square root, and then takes the log base 2 of that value. Therefore, the output is compressed in a logarithmic fashion, and is essentially in decibels (times a scaling factor). It takes no variables, and returns no variables. It uses a lookup table to calculate the log of the square root, and scales the output over the full 8b range {the equation is 16*(log2((img2 + real2)1/2))}. It is only an 8b value, and the values are taken from fft_input[], and returned in fft_log_out[]. The output values are in sequential order of FFT frequency bins, and there are only N/2 total bins, as the second half of the FFT result is redundant for real inputs.
- 这给出了FFT中每个仓的幅度。 它将虚数和实数的平方相加,然后取平方根,然后取该值的log base 2。 因此,输出以对数方式被压缩,并且基本上以分贝(乘以缩放因子)。 它不需要任何变量,并且不返回变量。 它使用查找表来计算平方根的对数,并在整个8b范围内缩放输出 {the equation is 16*(log2((img2 + real2)1/2))} 。 它只是一个8b值,值取自fft_input[],并返回fft_log_out[]。 输出值按照FFT频率仓的顺序排列,只有N/2个总存储区,因为FFT结果的后半部分对于实际输入是冗余的。
- fft_mag_octave()
- This outputs the RMS value of the bins in an octave (doubling of frequencies) format. This is more useful in some ways, as it is closer to how humans perceive sound. It doesn't take any variables, and doesn't return any variables. The input is taken from fft_output[] and returned in fft_oct_out[]. The data is represented as an 8b value of 16*log2(sqrt(mag)). There are LOG_N bins, and they are given as follows:
- FFT_N = 256 : bins = [0, 1, 2:4, 5:8, 9:16, 17:32, 3:64, 65:128]
- FFT_N = 128 : bins = [0, 1, 2:4, 5:8, 9:16, 17:32, 3:64]
Where, for example, (5:8) is a summation of all bins, 5 through 8. The data for each bin is squared, imaginary and real parts, and then added with all the squared magnitudes for the range. It is then divided down by the number of bins (which can be turned off - see #defines section), and the square root is taken, followed by the log being computed.
- 这将以八度(频率倍增)格式输出机箱的RMS值。 这在某些方面更有用,因为它更接近于人类如何看待声音。 它不需要任何变量,也不返回任何变量。 输入取自fft_output []并在fft_oct_out []中返回。 数据表示为8b * log2(sqrt(mag))的8b值。 有LOG_N bin,它们给出如下:
- FFT_N = 256:bins = [0,1,2:4,5:8,9:16,17:32,3:64,65:128]
- FFT_N = 128:bins = [0,1,2:4,5:8,9:16,17:32,3:64]
例如,(5:8)是5到8之间的所有仓的总和。每个仓的数据是平方,虚数和实数,然后加上范围的所有平方的数值。 然后将其除以数目(可以关闭 - 请参见#defines部分),并取平方根,然后计算日志。
Arduino_FFT #Define options
These values allow you to modify the FFT code to fit your needs. For the most part, they just turn off stuff you aren't using. By default most functions are off, so you will have to turn them on to use them. You must also declare these #defines before the #include statements in your sketch.
这些值允许您修改FFT代码以适应您的需要。 在很大程度上,他们只是关闭你没有使用的东西。 默认情况下,大多数功能都关闭,所以您必须打开它们才能使用它们。 您还必须在草图中的#include语句之前声明这些#define。
FFT_N - Sets the FFT size. Possible options are 16, 32, 64, 128, 256. 256 is the defualt. - 设置FFT大小。 可能的选项是16,32,64,128,256。默认是256。
SCALE
- Sets the scaling factor for fft_mag_lin8(). Since 8b resolution is pretty poor, you will want to scale the values to max out the full range. Setting SCALE multiplies the output by a constant before doing the square root, so you have maximum resolution. It does consume slightly more resources, but is pretty minimal. SCALE can be any number from 1 -> 255. By default it is 1. 1, 2, 4, 128, and 256 consume the least resources.
- 设置fft_mag_lin8() 的缩放因子。 由于8b分辨率很差,您将需要将值缩放到全范围内。 设置SCALE在执行平方根之前将输出乘以常数,因此您具有最大分辨率。 它消耗更多的资源,但是很少。 SCALE可以是从1 -> 255的任何数字。默认情况下,它是1,2,4,128和256消耗最少的资源。
WINDOW
- Turns on or off the window function resources. If you are not using fft_window(), then you should set WINDOW 0 (off). By default its 1 (on).
- 打开或关闭窗口功能资源。 如果你不使用fft_window(),那么你应该设置WINDOW 0(off)。 默认情况下其1(开)。
REORDER
- Turns on or off the reorder function resources. If you are not using fft_reorder(), then you should set REORDER 0 (off). By default its 1 (on).
- 打开或关闭重新排序功能资源。 如果你不使用fft_reorder(),那么你应该设置REORDER 0(off)。 默认情况下其1(on)。
LOG_OUT
- Turns on or off the log function resources. If you are using fft_mag_log(), then you should set LOG_OUT 1 (on). By default its 0 (off).
- 打开或关闭日志功能资源。 如果你使用fft_mag_log(),那么你应该设置LOG_OUT 1(on)。 默认为0(关)。
LIN_OUT
- Turns on or off the lin output function resources. If you are using fft_mag_lin(), then you should set LIN_OUT 1 (on). By default its 0 (off).
- 打开或关闭lin输出功能资源。 如果你使用fft_mag_lin(),那么你应该设置LIN_OUT 1(on)。 默认为0(关)。
LIN_OUT8
- Turns on or off the lin8 output function resources. If you are using fft_mag_lin8(), then you should set LIN_OUT8 1 (on). By default its 0 (off).
- 打开或关闭lin8输出功能资源。 如果你使用fft_mag_lin8(),那么你应该设置LIN_OUT8 1(on)。 默认为0(关)。
OCTAVE
- This turns on or off the octave output function resources. If you are using fft_mag_octave(), then you should set OCTAVE 1 (on). by default it is 0 (off).
- 打开或关闭八度输出功能资源。 如果你使用fft_mag_octave(),那么你应该设置OCTAVE 1(on)。 默认为0(关)。
OCT_NORM
- This turns on or off the octave normilisation feature. This is the part of fft_mat_octave() that divides each bin grouping by the number of bins averaged. Since a lot of sound sources are pink noise (they drop off in amplitude as the frequency increases), the scale tends to drop off rather quickly. This artificially boosts the higher frequencies when off (OCT_NORM 0). By default, the normilisation is on (OCT_NORM 1).
- 这会打开或关闭八度守规矩特征。 这是fft_mat_octave()的一部分,它将每个bin分组除以平均值的数量。 由于很多声源都是粉红色的噪音(随着频率的增加,它们的幅度会下降),所以音阶会比较快地下降。 当人为关闭(OCT_NORM 0)时,人为地提高频率。 默认情况下,正常化(OCT_NORM 1)。
更多建议和问题欢迎反馈至 YFRobot论坛
欢迎加入群聊:技术交流群