### Initialize and execute FFT Source: https://github.com/kosme/arduinofft/wiki/Home Basic setup and execution flow for the ArduinoFFT library. The sample count must always be a power of 2. ```C++ #include const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2 const float signalFrequency = 1000; const float samplingFrequency = 5000; const uint8_t amplitude = 100; float vReal[samples]; float vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); /* Create FFT object */ void setup(){ // Setup code } void loop() { // Get samples FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */ FFT.compute(FFTDirection::Forward); /* Compute FFT */ FFT.complexToMagnitude(); /* Compute magnitudes */ float x = FFT.majorPeak(); // Rest of the code } ``` -------------------------------- ### Initialize ArduinoFFT Object Source: https://context7.com/kosme/arduinofft/llms.txt Demonstrates different constructor patterns for the ArduinoFFT class, including precision selection and optional caching. ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; // Must ALWAYS be a power of 2 const double samplingFrequency = 5000; // Hz double vReal[samples]; double vImag[samples]; // Basic constructor with double precision ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); // Constructor with windowing factor caching enabled (faster repeated windowing) ArduinoFFT FFT_cached = ArduinoFFT(vReal, vImag, samples, samplingFrequency, true); // Simple constructor (requires passing arrays to each function call) ArduinoFFT FFT_simple = ArduinoFFT(); ``` -------------------------------- ### ArduinoFFT Constructors Source: https://github.com/kosme/arduinofft/wiki/Api Details on how to instantiate ArduinoFFT objects with different configurations. ```APIDOC ## ArduinoFFT Constructors ### `ArduinoFFT()` Simplest constructor possible. Returns an arduinoFFT object that will operate on arguments of the type `T` where `T`is either `float`or `double`. This constructor was kept for backwards compatibility with and using it **demands** using the functions that **at the very least** receive the following parameters: * Pointers to the data arrays of type `T` * Number of samples * Sampling frequency ### `ArduinoFFT(T *vReal, T *vImag, uint_fast16_t samples, T samplingFrequency, bool windowingFactors)` Returns an arduinoFFT object that will operate on arguments of the type `T` where `T`is either `float`or `double`. #### Arguments * `vReal` Pointer to a data array of size `samples` and type `T` where the real part of the data is stored and will be processed. * `vImag` Pointer to a data array of size `samples` and type `T` where the imaginary part of the data is stored and will be processed. * `samples` Size of the data array in number of elements. * `samplingFrequency` floating point value of type `T` indicating the frequency in Hz at which the data sampling was performed. * `windowingFactors` (*optional*) *(Since v2.0)* Boolean factor to enable internal storage of the windowing factors, streamlining subsequent windowing operations. Defaults to **false**. ``` -------------------------------- ### ArduinoFFT Constructor Source: https://context7.com/kosme/arduinofft/llms.txt Demonstrates how to create an ArduinoFFT object with different precision levels and options for windowing factor caching. ```APIDOC ## ArduinoFFT Constructor Creates an FFT object with specified data arrays and sampling parameters. The constructor accepts pointers to real and imaginary data arrays, sample count, sampling frequency, and an optional flag to enable windowing factor caching for improved performance on repeated operations. ### Method Constructor ### Parameters - **vReal** (double*) - Pointer to the real data array. - **vImag** (double*) - Pointer to the imaginary data array. - **samples** (uint16_t) - The number of samples (must be a power of 2). - **samplingFrequency** (double) - The sampling frequency in Hz. - **enableCaching** (bool, optional) - If true, enables caching of windowing factors for faster repeated operations. ### Request Example ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; // Must ALWAYS be a power of 2 const double samplingFrequency = 5000; // Hz double vReal[samples]; double vImag[samples]; // Basic constructor with double precision ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); // Constructor with windowing factor caching enabled (faster repeated windowing) ArduinoFFT FFT_cached = ArduinoFFT(vReal, vImag, samples, samplingFrequency, true); // Simple constructor (requires passing arrays to each function call) ArduinoFFT FFT_simple = ArduinoFFT(); ``` ``` -------------------------------- ### Migration and Usage Notes Source: https://github.com/kosme/arduinofft/wiki/Api Important information for migrating from older versions and guidelines for using the library effectively. ```APIDOC # Migrating from versions prior to 2.0 * The object name is now capitalized and the constructor requires a floating-point data type, e.g. "ArduinoFFT" instead of "arduinoFFT". * All function names are camelCase case now (start with lower-case character), e.g. "windowing()" instead of "Windowing()". # About the number of samples The number of samples **MUST ALWAYS be a power of 2**. Any other value will produce an infinite loop during the computing phase. Acceptable values are: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, ~~2048~~, ~~4096~~, 8192, 16384. ### Note There is a bug causing an overflow when `samples==2048` or `samples==4096` and the dominant frequency is not properly detected. Don't use those values until further notice. ``` -------------------------------- ### Register ArduinoFFT Component Source: https://github.com/kosme/arduinofft/blob/master/CMakeLists.txt Use this CMake command to register the ArduinoFFT component, defining its source and include directories. Ensure the paths are correct relative to your project structure. ```cmake set(src_dirs ./src) set(include_dirs ./src) idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs}) ``` -------------------------------- ### Performance Optimizations for ArduinoFFT Source: https://context7.com/kosme/arduinofft/llms.txt Defines for compile-time optimization flags to improve performance. These must be defined before including the library header. Options include speed over precision, fast inverse square root approximation, and storing constants in program memory. ```cpp // Speed optimizations (define BEFORE including arduinoFFT.h) // Use reciprocal multiplication instead of division (faster, slightly less precise) #define FFT_SPEED_OVER_PRECISION // Use fast inverse square root approximation (significantly faster, works with float only) #define FFT_SQRT_APPROXIMATION // Store FFT constants in program memory (AVR only, saves RAM) #define USE_AVR_PROGMEM // Enable bit reversal on both real and imaginary input (for complex input signals) #define COMPLEX_INPUT // Custom square root function (overridden by FFT_SQRT_APPROXIMATION) #define sqrt_internal sqrtf // Use float version for speed #include "arduinoFFT.h" const uint16_t samples = 64; const float samplingFrequency = 5000; float vReal[samples]; float vImag[samples]; // Use float type for ~70% speed improvement on ESP32 // Enable windowing factor caching for ~50% speed improvement on repeated windowing ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency, true); void setup() { Serial.begin(115200); unsigned long startTime = micros(); for (uint16_t i = 0; i < samples; i++) { vReal[i] = analogRead(A0); vImag[i] = 0; } FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); FFT.compute(FFTDirection::Forward); FFT.complexToMagnitude(); float peak = FFT.majorPeak(); unsigned long endTime = micros(); Serial.print("Peak frequency: "); Serial.print(peak); Serial.print(" Hz, Processing time: "); Serial.print(endTime - startTime); Serial.println(" us"); } void loop() {} ``` -------------------------------- ### Perform ADC Sampling and FFT Analysis in C++ Source: https://context7.com/kosme/arduinofft/llms.txt Demonstrates a complete workflow for sampling an analog signal at a fixed frequency and calculating the dominant frequency component. Requires the sample count to be a power of two. ```cpp #include "arduinoFFT.h" #define CHANNEL A0 const uint16_t samples = 64; // Must be power of 2 const double samplingFrequency = 1000; // Hz, adjust based on signal of interest unsigned int sampling_period_us; unsigned long microseconds; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { sampling_period_us = round(1000000.0 / samplingFrequency); Serial.begin(115200); while (!Serial); Serial.println("FFT Analyzer Ready"); Serial.print("Sampling at "); Serial.print(samplingFrequency); Serial.print(" Hz, "); Serial.print(samples); Serial.println(" samples"); Serial.print("Frequency resolution: "); Serial.print(samplingFrequency / samples); Serial.println(" Hz"); } void loop() { // Sample at precise intervals microseconds = micros(); for (int i = 0; i < samples; i++) { vReal[i] = analogRead(CHANNEL); vImag[i] = 0; while (micros() - microseconds < sampling_period_us) { // Wait for next sample time } microseconds += sampling_period_us; } // Process signal FFT.dcRemoval(); // Remove DC offset FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); // Apply window FFT.compute(FFTDirection::Forward); // Compute FFT FFT.complexToMagnitude(); // Get magnitudes // Get dominant frequency double frequency, magnitude; FFT.majorPeak(&frequency, &magnitude); Serial.print("Dominant: "); Serial.print(frequency, 2); Serial.print(" Hz (magnitude: "); Serial.print(magnitude, 2); Serial.println(")"); delay(1000); // Wait before next analysis } ``` -------------------------------- ### void windowing(FFTWindow windowType, FFTDirection dir, bool withCompensation) Source: https://github.com/kosme/arduinofft/wiki/Api Performs a windowing operation on the data. ```APIDOC ## void windowing(FFTWindow windowType, FFTDirection dir, bool withCompensation) ### Description Performs a windowing operation on the data to give more or less weight to different data sections. ### Parameters - **windowType** (FFTWindow) - The type of window to apply. - **dir** (FFTDirection) - The direction of the operation. - **withCompensation** (bool) - Whether to apply compensation. ``` -------------------------------- ### Apply Windowing Functions Source: https://context7.com/kosme/arduinofft/llms.txt Applies various windowing functions to sampled data to reduce spectral leakage, with optional amplitude compensation. ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double samplingFrequency = 5000; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { // Fill vReal with sampled data, zero vImag for (uint16_t i = 0; i < samples; i++) { vReal[i] = analogRead(A0); vImag[i] = 0; } // Apply Hamming window (most common for general use) FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); // Alternative windows: // FFT.windowing(FFTWindow::Rectangle, FFTDirection::Forward); // No windowing (box car) // FFT.windowing(FFTWindow::Hann, FFTDirection::Forward); // Good frequency resolution // FFT.windowing(FFTWindow::Triangle, FFTDirection::Forward); // Bartlett window // FFT.windowing(FFTWindow::Nuttall, FFTDirection::Forward); // Low side-lobe levels // FFT.windowing(FFTWindow::Blackman, FFTDirection::Forward); // Good side-lobe suppression // FFT.windowing(FFTWindow::Blackman_Nuttall, FFTDirection::Forward); // FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // FFT.windowing(FFTWindow::Flat_top, FFTDirection::Forward); // Best amplitude accuracy // FFT.windowing(FFTWindow::Welch, FFTDirection::Forward); // With compensation factor to correct amplitude attenuation FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward, true); } ``` -------------------------------- ### Revision Function Source: https://github.com/kosme/arduinofft/wiki/Api Retrieves the current revision of the arduinoFFT library. ```APIDOC ## uint8_t revision(void) ### Description Returns the current revision of the arduinoFFT library with the format 0xMn where **M** is the mayor version number and **n** is the minor version number. For example 0x15 corresponds to version 1.5. ``` -------------------------------- ### windowing - Apply Window Function to Signal Source: https://context7.com/kosme/arduinofft/llms.txt Applies a windowing function to the sampled data to reduce spectral leakage. Supports various window types and optional compensation factors. ```APIDOC ## windowing - Apply Window Function to Signal Applies a windowing function to the sampled data to reduce spectral leakage. The function supports 10 different window types and can optionally apply compensation factors to correct signal attenuation caused by windowing. ### Method `windowing` ### Parameters - **windowType** (FFTWindow) - The type of window function to apply (e.g., Hamming, Hann, Blackman). - **direction** (FFTDirection) - Specifies the direction of the FFT operation (Forward or Reverse). - **applyCompensation** (bool, optional) - If true, applies compensation factors to correct amplitude attenuation caused by windowing. ### Request Example ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double samplingFrequency = 5000; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { // Fill vReal with sampled data, zero vImag for (uint16_t i = 0; i < samples; i++) { vReal[i] = analogRead(A0); vImag[i] = 0; } // Apply Hamming window (most common for general use) FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); // Alternative windows: // FFT.windowing(FFTWindow::Rectangle, FFTDirection::Forward); // No windowing (box car) // FFT.windowing(FFTWindow::Hann, FFTDirection::Forward); // Good frequency resolution // FFT.windowing(FFTWindow::Triangle, FFTDirection::Forward); // Bartlett window // FFT.windowing(FFTWindow::Nuttall, FFTDirection::Forward); // Low side-lobe levels // FFT.windowing(FFTWindow::Blackman, FFTDirection::Forward); // Good side-lobe suppression // FFT.windowing(FFTWindow::Blackman_Nuttall, FFTDirection::Forward); // FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // FFT.windowing(FFTWindow::Flat_top, FFTDirection::Forward); // Best amplitude accuracy // FFT.windowing(FFTWindow::Welch, FFTDirection::Forward); // With compensation factor to correct amplitude attenuation FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward, true); } ``` ``` -------------------------------- ### Perform FFT Computation Source: https://context7.com/kosme/arduinofft/llms.txt Executes the Cooley-Tukey FFT algorithm to transform time-domain signals into the frequency domain. ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double signalFrequency = 1000; const double samplingFrequency = 5000; const uint8_t amplitude = 100; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { Serial.begin(115200); // Generate a test sinusoidal signal double ratio = 6.28318531 * signalFrequency / samplingFrequency; for (uint16_t i = 0; i < samples; i++) { vReal[i] = amplitude * sin(i * ratio); vImag[i] = 0; // Must be zeroed before computation } // Apply windowing before FFT FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); // Compute forward FFT (time domain -> frequency domain) FFT.compute(FFTDirection::Forward); // vReal and vImag now contain complex frequency data Serial.println("FFT computed - real and imaginary parts available"); // To perform inverse FFT (frequency domain -> time domain): // FFT.compute(FFTDirection::Reverse); } void loop() {} ``` -------------------------------- ### Specify Square Root Function Source: https://github.com/kosme/arduinofft/wiki/Optimizations Allows selection of the square root function (e.g., `sqrt` or `sqrtf`). If not specified, `sqrt` is used by default. Define it before including the library. ```c++ #define sqrt_internal sqrt #include ``` ```c++ #define sqrt_internal sqrtf #include ``` -------------------------------- ### Enable Fast Square Root Approximation Source: https://github.com/kosme/arduinofft/wiki/Optimizations Supersedes `sqrt_internal`. Uses an approximation for square root calculations, similar to the 'Quake 3 fast inverse square root' method, for improved performance. Define it before including the library. ```c++ #define FFT_SQRT_APPROXIMATION #include ``` -------------------------------- ### compute - Perform FFT Computation Source: https://context7.com/kosme/arduinofft/llms.txt Executes the Fast Fourier Transform using the Cooley-Tukey algorithm. Supports both forward (time to frequency) and reverse (frequency to time) transformations. ```APIDOC ## compute - Perform FFT Computation Executes the Fast Fourier Transform using the Cooley-Tukey algorithm. The direction parameter specifies forward transformation (time to frequency domain) or reverse transformation (frequency to time domain). Results are stored in the real and imaginary arrays. ### Method `compute` ### Parameters - **direction** (FFTDirection) - Specifies the direction of the FFT: `Forward` for time-to-frequency, `Reverse` for frequency-to-time. ### Request Example ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double signalFrequency = 1000; const double samplingFrequency = 5000; const uint8_t amplitude = 100; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { Serial.begin(115200); // Generate a test sinusoidal signal double ratio = 6.28318531 * signalFrequency / samplingFrequency; for (uint16_t i = 0; i < samples; i++) { vReal[i] = amplitude * sin(i * ratio); vImag[i] = 0; // Must be zeroed before computation } // Apply windowing before FFT FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); // Compute forward FFT (time domain -> frequency domain) FFT.compute(FFTDirection::Forward); // vReal and vImag now contain complex frequency data Serial.println("FFT computed - real and imaginary parts available"); // To perform inverse FFT (frequency domain -> time domain): // FFT.compute(FFTDirection::Reverse); } void loop() {} ``` ``` -------------------------------- ### Enable FFT Speed Over Precision Source: https://github.com/kosme/arduinofft/wiki/Optimizations Use this definition to replace divisions with multiplications by reciprocals for faster computation, though it may introduce precision errors. Define it before including the library. ```c++ #define FFT_SPEED_OVER_PRECISION #include ``` -------------------------------- ### Remove DC Offset from Signal using dcRemoval Source: https://context7.com/kosme/arduinofft/llms.txt Call this before windowing and FFT to prevent DC bias from affecting frequency analysis. It centers the sampled signal around zero. ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double samplingFrequency = 5000; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { Serial.begin(115200); // Simulate ADC readings with DC offset (0-1023 range, centered at 512) double ratio = 6.28318531 * 1000 / samplingFrequency; for (uint16_t i = 0; i < samples; i++) { // Signal with 512 DC offset (typical for unsigned ADC) vReal[i] = 512 + 100 * sin(i * ratio); vImag[i] = 0; } Serial.print("Sample 0 before DC removal: "); Serial.println(vReal[0]); // Remove DC offset to center signal around zero FFT.dcRemoval(); Serial.print("Sample 0 after DC removal: "); Serial.println(vReal[0]); // Now proceed with normal FFT processing FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); FFT.compute(FFTDirection::Forward); FFT.complexToMagnitude(); double peak = FFT.majorPeak(); Serial.print("Detected frequency: "); Serial.println(peak); } void loop() {} ``` -------------------------------- ### Enable Complex Input Processing Source: https://github.com/kosme/arduinofft/wiki/Optimizations Processes both real and imaginary parts of the input data by performing bit reversal on both. Without this, the imaginary part is assumed irrelevant to save processing time. Define it before including the library. ```c++ #define COMPLEX_INPUT #include ``` -------------------------------- ### Windowing Function Source: https://github.com/kosme/arduinofft/wiki/Api Performs a windowing operation on the data to apply or remove windowing factors. Compensation can be optionally used. ```APIDOC ## void windowing(T *vData, uint_fast16_t samples, FFTWindow windowType, FFTDirection dir, T *windowingFactors, bool withCompensation) ### Description Performs a windowing operation on the data to give more or less weight to different data sections. ### Arguments * `windowType` Which windowing operation should be performed on the data. Accepted values are: * **FFTWindow::Rectangle** * **FFTWindow::Hamming** * **FFTWindow::Hann** * **FFTWindow::Triangle** * **FFTWindow::Nuttall** * **FFTWindow::Blackman** * **FFTWindow::Blackman_Nuttall** * **FFTWindow::Blackman_Harris** * **FFTWindow::Flat_top** * **FFTWindow::Welch** * `dir` Direction on which to perform the windowing operation, aka apply/remove windowing factors. Accepted values are: * **FFTDirection::Forward** Apply the windowing. * **FFTDirection::Reverse** Remove the windowing. * `withCompensation` (*optional*) *(Since v2.0)* Boolean value regarding the use of compensation factors to correct how the signal is modified during windowing. Defaults to **false**. See [Windowing](https://github.com/kosme/arduinoFFT/wiki/windowing) for more information regarding the window types. ``` -------------------------------- ### Detect Dominant Frequency with Parabolic Interpolation Source: https://context7.com/kosme/arduinofft/llms.txt Provides more accurate peak detection than linear interpolation by using parabolic interpolation. Useful when the true frequency does not align with FFT bin centers. ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double signalFrequency = 1234.5; // Non-bin-aligned frequency const double samplingFrequency = 5000; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { Serial.begin(115200); // Generate signal at non-bin-aligned frequency double ratio = 6.28318531 * signalFrequency / samplingFrequency; for (uint16_t i = 0; i < samples; i++) { vReal[i] = 100 * sin(i * ratio); vImag[i] = 0; } FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); FFT.compute(FFTDirection::Forward); FFT.complexToMagnitude(); // Compare linear vs parabolic interpolation double linearPeak = FFT.majorPeak(); double parabolaPeak = FFT.majorPeakParabola(); Serial.print("Actual frequency: "); Serial.println(signalFrequency); Serial.print("Linear interpolation: "); Serial.println(linearPeak, 2); Serial.print("Parabolic interpolation: "); Serial.println(parabolaPeak, 2); // Parabolic typically gives more accurate results // Get frequency and magnitude together double frequency, magnitude; FFT.majorPeakParabola(&frequency, &magnitude); Serial.print("Peak: "); Serial.print(frequency, 2); Serial.print(" Hz, Magnitude: "); Serial.println(magnitude, 2); } void loop() {} ``` -------------------------------- ### Convert Complex FFT Output to Magnitudes Source: https://context7.com/kosme/arduinofft/llms.txt Calculates magnitude values from complex FFT output. Must be called after compute() to obtain usable frequency bin amplitudes. ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double samplingFrequency = 5000; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { Serial.begin(115200); // Fill with sample data for (uint16_t i = 0; i < samples; i++) { vReal[i] = analogRead(A0); vImag[i] = 0; } FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); FFT.compute(FFTDirection::Forward); // Convert complex FFT results to magnitudes FFT.complexToMagnitude(); // Print magnitude spectrum (only first half is valid) Serial.println("Frequency Magnitudes:"); for (uint16_t i = 0; i < (samples >> 1); i++) { double frequency = (i * samplingFrequency) / samples; Serial.print(frequency); Serial.print(" Hz: "); Serial.println(vReal[i]); } } void loop() {} ``` -------------------------------- ### Store FFT Factors in Program Memory (AVR) Source: https://github.com/kosme/arduinofft/wiki/Optimizations Optimized for AVR architecture, this definition stores FFT computation factors in program memory instead of computing them on the fly. Define it before including the library. ```c++ #define USE_AVR_PROGMEM #include ``` -------------------------------- ### Replace Data Array Pointers with setArrays Source: https://context7.com/kosme/arduinofft/llms.txt Allows reuse of a single FFT object with different data buffers by replacing internal data array pointers. Useful for processing multiple signals or when array size changes. ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double samplingFrequency = 5000; double vReal1[samples]; double vImag1[samples]; double vReal2[samples]; double vImag2[samples]; ArduinoFFT FFT = ArduinoFFT(vReal1, vImag1, samples, samplingFrequency); void setup() { Serial.begin(115200); // Process first channel for (uint16_t i = 0; i < samples; i++) { vReal1[i] = analogRead(A0); vImag1[i] = 0; } FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); FFT.compute(FFTDirection::Forward); FFT.complexToMagnitude(); Serial.print("Channel 1 peak: "); Serial.println(FFT.majorPeak()); // Switch to second channel without creating new FFT object FFT.setArrays(vReal2, vImag2); for (uint16_t i = 0; i < samples; i++) { vReal2[i] = analogRead(A1); vImag2[i] = 0; } FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); FFT.compute(FFTDirection::Forward); FFT.complexToMagnitude(); Serial.print("Channel 2 peak: "); Serial.println(FFT.majorPeak()); } void loop() {} ``` -------------------------------- ### Set Arrays Function Source: https://github.com/kosme/arduinofft/wiki/Api Replaces the internal data array pointers with new pointers. This function is available since v2.0. ```APIDOC ## void setArrays(T *vReal, T *vImag, uint_fast16_t samples) *(Since v2.0)* ### Description Replaces the internal data array pointers with new pointers. ### Arguments * `vReal` Pointer to a data array of size `samples` and type `T` where the real part of the data is stored and will be processed. * `vImag` Pointer to a data array of size `samples` and type `T` where the imaginary part of the data is stored and will be processed. * `samples` (*optional*) Size of the data array in number of elements. Only necessary if the number of elements has changed since object creation. ``` -------------------------------- ### majorPeakParabola Functions Source: https://github.com/kosme/arduinofft/wiki/Api Functions for estimating the dominant frequency using parabolic interpolation. ```APIDOC ## majorPeakParabola Functions ### Description Returns or computes an estimation of the dominant frequency according to interpolation through the parabola equation of the biggest peak found on the magnitude array. ### Methods - T majorPeakParabola(void) - void majorPeakParabola(T *frequency, T *magnitude) - T majorPeakParabola(T *vData, uint_fast16_t samples, T samplingFrequency) - void majorPeakParabola(T *vData, uint_fast16_t samples, T samplingFrequency, T *frequency, T *magnitude) ``` -------------------------------- ### majorPeak Functions Source: https://github.com/kosme/arduinofft/wiki/Api Functions for estimating the dominant frequency using peak interpolation. ```APIDOC ## majorPeak Functions ### Description Returns or computes an estimation of the dominant frequency according to the interpolation of the biggest peak found on the magnitude array. ### Methods - T majorPeak(void) - void majorPeak(T *frequency, T *magnitude) - T majorPeak(T *vData, uint_fast16_t samples, T samplingFrequency) - void majorPeak(T *vData, uint_fast16_t samples, T samplingFrequency, T *frequency, T *magnitude) ``` -------------------------------- ### Data Processing Functions Source: https://github.com/kosme/arduinofft/wiki/Api Functions for transforming complex data into magnitudes, performing FFT computations, and removing DC offsets. ```APIDOC ## Data processing functions ### `void complexToMagnitude(void)` Processes the computed data and calculates magnitudes from complex numbers. The output will overwrite the first half of the real data array. ### `void complexToMagnitude(T *vReal, T *vImag, uint_fast16_t samples)` Processes the computed data and calculates magnitudes from complex numbers. The output will overwrite the first half of the real data array. #### Arguments * `vReal` Pointer to a data array of size `samples` and type `T` where the real part of the data is stored and will be processed. * `vImag` Pointer to a data array of size `samples` and type `T` where the imaginary part of the data is stored and will be processed. * `samples` Size of the data array in number of elements. ### `void compute(FFTDirection dir)` Performs the Fast Fourier Transformation using the [Cooley–Tukey algorithm](https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm). #### Arguments * `dir` Direction on which to perform the transformation. Accepted values are **FFTDirection::Forward** or **FFTDirection::Reverse** ### `void compute(T *vReal, T *vImag, uint_fast16_t samples, FFTDirection dir)` Performs the Fast Fourier Transformation using the [Cooley–Tukey algorithm](https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm). #### Arguments * `vReal` Pointer to a data array of size `samples` and type `T` where the real part of the data is stored and will be processed. * `vImag` Pointer to a data array of size `samples` and type `T` where the imaginary part of the data is stored and will be processed. * `samples` Size of the data array in number of elements. * `dir` Direction on which to perform the transformation. Accepted values are **FFTDirection::Forward** or **FFTDirection::Reverse** ### `void compute(T *vReal, T *vImag, uint_fast16_t samples, uint_fast8_t power, FFTDirection dir)` Performs the Fast Fourier Transformation using the [Cooley–Tukey algorithm](https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm). #### Arguments * `vReal` Pointer to a data array of size `samples` and type `T` where the real part of the data is stored and will be processed. * `vImag` Pointer to a data array of size `samples` and type `T` where the imaginary part of the data is stored and will be processed. * `samples` Size of the data array in number of elements. * `power` Log base 2 of `samples`. * `dir` Direction on which to perform the transformation. Accepted values are **FFTDirection::Forward** or **FFTDirection::Reverse** ### `void dcRemoval(void)` Offsets the sampled signal so that it is centered around the X-axis of a plot, removing any DC offset that could have been present during sampling. ``` -------------------------------- ### void dcRemoval(T *vData, uint_fast16_t samples) Source: https://github.com/kosme/arduinofft/wiki/Api Offsets the sampled signal to be centered around the X-axis, removing DC offset. ```APIDOC ## void dcRemoval(T *vData, uint_fast16_t samples) ### Description Offsets the sampled signal so that it is centered around the X-axis of a plot, removing any DC offset that could have been present during sampling. ### Parameters #### Arguments - **vData** (T*) - Pointer to a data array of size samples. - **samples** (uint_fast16_t) - Size of the data array. ``` -------------------------------- ### Detect Dominant Frequency with Linear Interpolation Source: https://context7.com/kosme/arduinofft/llms.txt Returns the frequency of the highest magnitude peak using linear interpolation. Must be called after complexToMagnitude(). ```cpp #include "arduinoFFT.h" const uint16_t samples = 64; const double signalFrequency = 1000; // Test signal at 1kHz const double samplingFrequency = 5000; const uint8_t amplitude = 100; double vReal[samples]; double vImag[samples]; ArduinoFFT FFT = ArduinoFFT(vReal, vImag, samples, samplingFrequency); void setup() { Serial.begin(115200); // Generate test signal double ratio = 6.28318531 * signalFrequency / samplingFrequency; for (uint16_t i = 0; i < samples; i++) { vReal[i] = amplitude * sin(i * ratio); vImag[i] = 0; } FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); FFT.compute(FFTDirection::Forward); FFT.complexToMagnitude(); // Get dominant frequency only double peakFrequency = FFT.majorPeak(); Serial.print("Dominant frequency: "); Serial.print(peakFrequency, 6); Serial.println(" Hz"); // Expected output: approximately 1000 Hz // Get both frequency and magnitude double frequency, magnitude; FFT.majorPeak(&frequency, &magnitude); Serial.print("Peak at "); Serial.print(frequency, 2); Serial.print(" Hz with magnitude: "); Serial.println(magnitude, 2); } void loop() {} ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.