diff options
| author | Ceimour <113631258+Ceimour@users.noreply.github.com> | 2023-04-30 08:50:18 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-30 15:50:18 +0200 |
| commit | c22e30a4a6ef014c7a5086ad47eaab7740a75ff2 (patch) | |
| tree | 5afdf4ed624a8b41dc4aea723a8c8f38d726545a /src/libs/arduinoFFT-develop/Examples | |
| parent | 40f7e1c7be6882e01058b5ccf64d5005c6105346 (diff) | |
Refactored Ppg for frequency based algorithm. (#1486)
New implementation of the heart rate sensor data processing using a frequency based PPG algorithm.
The HRS3300 settings are fine-tuned for better signal to noise at 10Hz.
The measurement delay is now set to 100ms.
Enable and use the ambient light sensor.
FFT implementation based on ArduinoFFT (https://github.com/kosme/arduinoFFT, GPLv3.0).
Diffstat (limited to 'src/libs/arduinoFFT-develop/Examples')
6 files changed, 721 insertions, 0 deletions
diff --git a/src/libs/arduinoFFT-develop/Examples/FFT_01/FFT_01.ino b/src/libs/arduinoFFT-develop/Examples/FFT_01/FFT_01.ino new file mode 100644 index 00000000..22b5024a --- /dev/null +++ b/src/libs/arduinoFFT-develop/Examples/FFT_01/FFT_01.ino @@ -0,0 +1,119 @@ +/* + + Example of use of the FFT libray + + Copyright (C) 2014 Enrique Condes + Copyright (C) 2020 Bim Overbohm (header-only, template, speed improvements) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ + +/* + In this example, the Arduino simulates the sampling of a sinusoidal 1000 Hz + signal with an amplitude of 100, sampled at 5000 Hz. Samples are stored + inside the vReal array. The samples are windowed according to Hamming + function. The FFT is computed using the windowed samples. Then the magnitudes + of each of the frequencies that compose the signal are calculated. Finally, + the frequency with the highest peak is obtained, being that the main frequency + present in the signal. +*/ + +#include "arduinoFFT.h" + +/* +These values can be changed in order to evaluate the functions +*/ +const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2 +const double signalFrequency = 1000; +const double samplingFrequency = 5000; +const uint8_t amplitude = 100; + +/* +These are the input and output vectors +Input vectors receive computed results from FFT +*/ +double vReal[samples]; +double vImag[samples]; + +/* Create FFT object */ +ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency); + +#define SCL_INDEX 0x00 +#define SCL_TIME 0x01 +#define SCL_FREQUENCY 0x02 +#define SCL_PLOT 0x03 + +void setup() +{ + Serial.begin(115200); + Serial.println("Ready"); +} + +void loop() +{ + /* Build raw data */ + double cycles = (((samples-1) * signalFrequency) / samplingFrequency); //Number of signal cycles that the sampling will read + for (uint16_t i = 0; i < samples; i++) + { + vReal[i] = int8_t((amplitude * (sin((i * (TWO_PI * cycles)) / samples))) / 2.0);/* Build data with positive and negative values*/ + //vReal[i] = uint8_t((amplitude * (sin((i * (twoPi * cycles)) / samples) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/ + vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows + } + /* Print the results of the simulated sampling according to time */ + Serial.println("Data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */ + Serial.println("Weighed data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.compute(FFTDirection::Forward); /* Compute FFT */ + Serial.println("Computed Real values:"); + PrintVector(vReal, samples, SCL_INDEX); + Serial.println("Computed Imaginary values:"); + PrintVector(vImag, samples, SCL_INDEX); + FFT.complexToMagnitude(); /* Compute magnitudes */ + Serial.println("Computed magnitudes:"); + PrintVector(vReal, (samples >> 1), SCL_FREQUENCY); + double x = FFT.majorPeak(); + Serial.println(x, 6); + while(1); /* Run Once */ + // delay(2000); /* Repeat after delay */ +} + +void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType) +{ + for (uint16_t i = 0; i < bufferSize; i++) + { + double abscissa; + /* Print abscissa value */ + switch (scaleType) + { + case SCL_INDEX: + abscissa = (i * 1.0); + break; + case SCL_TIME: + abscissa = ((i * 1.0) / samplingFrequency); + break; + case SCL_FREQUENCY: + abscissa = ((i * 1.0 * samplingFrequency) / samples); + break; + } + Serial.print(abscissa, 6); + if(scaleType==SCL_FREQUENCY) + Serial.print("Hz"); + Serial.print(" "); + Serial.println(vData[i], 4); + } + Serial.println(); +} diff --git a/src/libs/arduinoFFT-develop/Examples/FFT_02/FFT_02.ino b/src/libs/arduinoFFT-develop/Examples/FFT_02/FFT_02.ino new file mode 100644 index 00000000..7164dab1 --- /dev/null +++ b/src/libs/arduinoFFT-develop/Examples/FFT_02/FFT_02.ino @@ -0,0 +1,125 @@ +/* + + Example of use of the FFT libray to compute FFT for several signals over a range of frequencies. + The exponent is calculated once before the excecution since it is a constant. + This saves resources during the excecution of the sketch and reduces the compiled size. + The sketch shows the time that the computing is taking. + + Copyright (C) 2014 Enrique Condes + Copyright (C) 2020 Bim Overbohm (header-only, template, speed improvements) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "arduinoFFT.h" + +/* +These values can be changed in order to evaluate the functions +*/ +const uint16_t samples = 64; +const double sampling = 40; +const uint8_t amplitude = 4; +const double startFrequency = 2; +const double stopFrequency = 16.4; +const double step_size = 0.1; + +/* +These are the input and output vectors +Input vectors receive computed results from FFT +*/ +double vReal[samples]; +double vImag[samples]; + +/* Create FFT object */ +ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, sampling); + +unsigned long startTime; + +#define SCL_INDEX 0x00 +#define SCL_TIME 0x01 +#define SCL_FREQUENCY 0x02 +#define SCL_PLOT 0x03 + +void setup() +{ + Serial.begin(115200); + Serial.println("Ready"); +} + +void loop() +{ + Serial.println("Frequency\tDetected\ttakes (ms)"); + Serial.println("=======================================\n"); + for(double frequency = startFrequency; frequency<=stopFrequency; frequency+=step_size) + { + /* Build raw data */ + double cycles = (((samples-1) * frequency) / sampling); + for (uint16_t i = 0; i < samples; i++) + { + vReal[i] = int8_t((amplitude * (sin((i * (TWO_PI * cycles)) / samples))) / 2.0); + vImag[i] = 0; //Reset the imaginary values vector for each new frequency + } + /*Serial.println("Data:"); + PrintVector(vReal, samples, SCL_TIME);*/ + startTime=millis(); + FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */ + /*Serial.println("Weighed data:"); + PrintVector(vReal, samples, SCL_TIME);*/ + FFT.compute(FFTDirection::Forward); /* Compute FFT */ + /*Serial.println("Computed Real values:"); + PrintVector(vReal, samples, SCL_INDEX); + Serial.println("Computed Imaginary values:"); + PrintVector(vImag, samples, SCL_INDEX);*/ + FFT.complexToMagnitude(); /* Compute magnitudes */ + /*Serial.println("Computed magnitudes:"); + PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);*/ + double x = FFT.majorPeak(); + Serial.print(frequency); + Serial.print(": \t\t"); + Serial.print(x, 4); + Serial.print("\t\t"); + Serial.print(millis()-startTime); + Serial.println(" ms"); + // delay(2000); /* Repeat after delay */ + } + while(1); /* Run Once */ +} + +void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType) +{ + for (uint16_t i = 0; i < bufferSize; i++) + { + double abscissa; + /* Print abscissa value */ + switch (scaleType) + { + case SCL_INDEX: + abscissa = (i * 1.0); + break; + case SCL_TIME: + abscissa = ((i * 1.0) / sampling); + break; + case SCL_FREQUENCY: + abscissa = ((i * 1.0 * sampling) / samples); + break; + } + Serial.print(abscissa, 6); + if(scaleType==SCL_FREQUENCY) + Serial.print("Hz"); + Serial.print(" "); + Serial.println(vData[i], 4); + } + Serial.println(); +} diff --git a/src/libs/arduinoFFT-develop/Examples/FFT_03/FFT_03.ino b/src/libs/arduinoFFT-develop/Examples/FFT_03/FFT_03.ino new file mode 100644 index 00000000..ee2b2946 --- /dev/null +++ b/src/libs/arduinoFFT-develop/Examples/FFT_03/FFT_03.ino @@ -0,0 +1,114 @@ +/* + + Example of use of the FFT libray to compute FFT for a signal sampled through the ADC. + + Copyright (C) 2018 Enrique Condés and Ragnar Ranøyen Homb + Copyright (C) 2020 Bim Overbohm (header-only, template, speed improvements) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "arduinoFFT.h" + +/* +These values can be changed in order to evaluate the functions +*/ +#define CHANNEL A0 +const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2 +const double samplingFrequency = 100; //Hz, must be less than 10000 due to ADC +unsigned int sampling_period_us; +unsigned long microseconds; + +/* +These are the input and output vectors +Input vectors receive computed results from FFT +*/ +double vReal[samples]; +double vImag[samples]; + +/* Create FFT object */ +ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency); + +#define SCL_INDEX 0x00 +#define SCL_TIME 0x01 +#define SCL_FREQUENCY 0x02 +#define SCL_PLOT 0x03 + +void setup() +{ + sampling_period_us = round(1000000*(1.0/samplingFrequency)); + Serial.begin(115200); + Serial.println("Ready"); +} + +void loop() +{ + /*SAMPLING*/ + microseconds = micros(); + for(int i=0; i<samples; i++) + { + vReal[i] = analogRead(CHANNEL); + vImag[i] = 0; + while(micros() - microseconds < sampling_period_us){ + //empty loop + } + microseconds += sampling_period_us; + } + /* Print the results of the sampling according to time */ + Serial.println("Data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */ + Serial.println("Weighed data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.compute(FFTDirection::Forward); /* Compute FFT */ + Serial.println("Computed Real values:"); + PrintVector(vReal, samples, SCL_INDEX); + Serial.println("Computed Imaginary values:"); + PrintVector(vImag, samples, SCL_INDEX); + FFT.complexToMagnitude(); /* Compute magnitudes */ + Serial.println("Computed magnitudes:"); + PrintVector(vReal, (samples >> 1), SCL_FREQUENCY); + double x = FFT.majorPeak(); + Serial.println(x, 6); //Print out what frequency is the most dominant. + while(1); /* Run Once */ + // delay(2000); /* Repeat after delay */ +} + +void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType) +{ + for (uint16_t i = 0; i < bufferSize; i++) + { + double abscissa; + /* Print abscissa value */ + switch (scaleType) + { + case SCL_INDEX: + abscissa = (i * 1.0); + break; + case SCL_TIME: + abscissa = ((i * 1.0) / samplingFrequency); + break; + case SCL_FREQUENCY: + abscissa = ((i * 1.0 * samplingFrequency) / samples); + break; + } + Serial.print(abscissa, 6); + if(scaleType==SCL_FREQUENCY) + Serial.print("Hz"); + Serial.print(" "); + Serial.println(vData[i], 4); + } + Serial.println(); +} diff --git a/src/libs/arduinoFFT-develop/Examples/FFT_04/FFT_04.ino b/src/libs/arduinoFFT-develop/Examples/FFT_04/FFT_04.ino new file mode 100644 index 00000000..b125991d --- /dev/null +++ b/src/libs/arduinoFFT-develop/Examples/FFT_04/FFT_04.ino @@ -0,0 +1,110 @@ +/* + + Example of use of the FFT libray + + Copyright (C) 2018 Enrique Condes + Copyright (C) 2020 Bim Overbohm (header-only, template, speed improvements) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ + +/* + In this example, the Arduino simulates the sampling of a sinusoidal 1000 Hz + signal with an amplitude of 100, sampled at 5000 Hz. Samples are stored + inside the vReal array. The samples are windowed according to Hamming + function. The FFT is computed using the windowed samples. Then the magnitudes + of each of the frequencies that compose the signal are calculated. Finally, + the frequency spectrum magnitudes are printed. If you use the Arduino IDE + serial plotter, you will see a single spike corresponding to the 1000 Hz + frecuency. +*/ + +#include "arduinoFFT.h" + +/* +These values can be changed in order to evaluate the functions +*/ +const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2 +const double signalFrequency = 1000; +const double samplingFrequency = 5000; +const uint8_t amplitude = 100; + +/* +These are the input and output vectors +Input vectors receive computed results from FFT +*/ +double vReal[samples]; +double vImag[samples]; + +ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency); + +#define SCL_INDEX 0x00 +#define SCL_TIME 0x01 +#define SCL_FREQUENCY 0x02 +#define SCL_PLOT 0x03 + +void setup() +{ + Serial.begin(115200); +} + +void loop() +{ + /* Build raw data */ + double cycles = (((samples-1) * signalFrequency) / samplingFrequency); //Number of signal cycles that the sampling will read + for (uint16_t i = 0; i < samples; i++) + { + vReal[i] = int8_t((amplitude * (sin((i * (TWO_PI * cycles)) / samples))) / 2.0);/* Build data with positive and negative values*/ + //vReal[i] = uint8_t((amplitude * (sin((i * (twoPi * cycles)) / samples) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/ + vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows + } + FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */ + FFT.compute(FFTDirection::Forward); /* Compute FFT */ + FFT.complexToMagnitude(); /* Compute magnitudes */ + PrintVector(vReal, samples>>1, SCL_PLOT); + double x = FFT.majorPeak(); + while(1); /* Run Once */ + // delay(2000); /* Repeat after delay */ +} + +void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType) +{ + for (uint16_t i = 0; i < bufferSize; i++) + { + double abscissa; + /* Print abscissa value */ + switch (scaleType) + { + case SCL_INDEX: + abscissa = (i * 1.0); + break; + case SCL_TIME: + abscissa = ((i * 1.0) / samplingFrequency); + break; + case SCL_FREQUENCY: + abscissa = ((i * 1.0 * samplingFrequency) / samples); + break; + } + if(scaleType!=SCL_PLOT) + { + Serial.print(abscissa, 6); + if(scaleType==SCL_FREQUENCY) + Serial.print("Hz"); + Serial.print(" "); + } + Serial.println(vData[i], 4); + } + Serial.println(); +} diff --git a/src/libs/arduinoFFT-develop/Examples/FFT_05/FFT_05.ino b/src/libs/arduinoFFT-develop/Examples/FFT_05/FFT_05.ino new file mode 100644 index 00000000..a6f4df7a --- /dev/null +++ b/src/libs/arduinoFFT-develop/Examples/FFT_05/FFT_05.ino @@ -0,0 +1,124 @@ +/* + + Example of use of the FFT libray + + Copyright (C) 2014 Enrique Condes + Copyright (C) 2020 Bim Overbohm (header-only, template, speed improvements) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ + +/* + In this example, the Arduino simulates the sampling of a sinusoidal 1000 Hz + signal with an amplitude of 100, sampled at 5000 Hz. Samples are stored + inside the vReal array. The samples are windowed according to Hamming + function. The FFT is computed using the windowed samples. Then the magnitudes + of each of the frequencies that compose the signal are calculated. Finally, + the frequency with the highest peak is obtained, being that the main frequency + present in the signal. This frequency is printed, along with the magnitude of + the peak. +*/ + +#include "arduinoFFT.h" + +/* +These values can be changed in order to evaluate the functions +*/ +const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2 +const double signalFrequency = 1000; +const double samplingFrequency = 5000; +const uint8_t amplitude = 100; + +/* +These are the input and output vectors +Input vectors receive computed results from FFT +*/ +double vReal[samples]; +double vImag[samples]; + +/* Create FFT object */ +ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency); + +#define SCL_INDEX 0x00 +#define SCL_TIME 0x01 +#define SCL_FREQUENCY 0x02 +#define SCL_PLOT 0x03 + +void setup() +{ + Serial.begin(115200); + Serial.println("Ready"); +} + +void loop() +{ + /* Build raw data */ + double cycles = (((samples-1) * signalFrequency) / samplingFrequency); //Number of signal cycles that the sampling will read + for (uint16_t i = 0; i < samples; i++) + { + vReal[i] = int8_t((amplitude * (sin((i * (TWO_PI * cycles)) / samples))) / 2.0);/* Build data with positive and negative values*/ + //vReal[i] = uint8_t((amplitude * (sin((i * (twoPi * cycles)) / samples) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/ + vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows + } + /* Print the results of the simulated sampling according to time */ + Serial.println("Data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */ + Serial.println("Weighed data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.compute(FFTDirection::Forward); /* Compute FFT */ + Serial.println("Computed Real values:"); + PrintVector(vReal, samples, SCL_INDEX); + Serial.println("Computed Imaginary values:"); + PrintVector(vImag, samples, SCL_INDEX); + FFT.complexToMagnitude(); /* Compute magnitudes */ + Serial.println("Computed magnitudes:"); + PrintVector(vReal, (samples >> 1), SCL_FREQUENCY); + double x; + double v; + FFT.majorPeak(x, v); + Serial.print(x, 6); + Serial.print(", "); + Serial.println(v, 6); + while(1); /* Run Once */ + // delay(2000); /* Repeat after delay */ +} + +void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType) +{ + for (uint16_t i = 0; i < bufferSize; i++) + { + double abscissa; + /* Print abscissa value */ + switch (scaleType) + { + case SCL_INDEX: + abscissa = (i * 1.0); + break; + case SCL_TIME: + abscissa = ((i * 1.0) / samplingFrequency); + break; + case SCL_FREQUENCY: + abscissa = ((i * 1.0 * samplingFrequency) / samples); + break; + } + Serial.print(abscissa, 6); + if(scaleType==SCL_FREQUENCY) + Serial.print("Hz"); + Serial.print(" "); + Serial.println(vData[i], 4); + } + Serial.println(); +} diff --git a/src/libs/arduinoFFT-develop/Examples/FFT_speedup/FFT_speedup.ino b/src/libs/arduinoFFT-develop/Examples/FFT_speedup/FFT_speedup.ino new file mode 100644 index 00000000..a059a170 --- /dev/null +++ b/src/libs/arduinoFFT-develop/Examples/FFT_speedup/FFT_speedup.ino @@ -0,0 +1,129 @@ +/* + + Example of use of the FFT libray to compute FFT for a signal sampled through the ADC + with speedup through different arduinoFFT options. Based on examples/FFT_03/FFT_03.ino + + Copyright (C) 2020 Bim Overbohm (header-only, template, speed improvements) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ + +// There are two speedup options for some of the FFT code: + +// Define this to use reciprocal multiplication for division and some more speedups that might decrease precision +//#define FFT_SPEED_OVER_PRECISION + +// Define this to use a low-precision square root approximation instead of the regular sqrt() call +// This might only work for specific use cases, but is significantly faster. Only works for ArduinoFFT<float>. +//#define FFT_SQRT_APPROXIMATION + +#include "arduinoFFT.h" + +/* +These values can be changed in order to evaluate the functions +*/ +#define CHANNEL A0 +const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2 +const float samplingFrequency = 100; //Hz, must be less than 10000 due to ADC +unsigned int sampling_period_us; +unsigned long microseconds; + +/* +These are the input and output vectors +Input vectors receive computed results from FFT +*/ +float vReal[samples]; +float vImag[samples]; + +/* +Allocate space for FFT window weighing factors, so they are calculated only the first time windowing() is called. +If you don't do this, a lot of calculations are necessary, depending on the window function. +*/ +float weighingFactors[samples]; + +/* Create FFT object with weighing factor storage */ +ArduinoFFT<float> FFT = ArduinoFFT<float>(vReal, vImag, samples, samplingFrequency, weighingFactors); + +#define SCL_INDEX 0x00 +#define SCL_TIME 0x01 +#define SCL_FREQUENCY 0x02 +#define SCL_PLOT 0x03 + +void setup() +{ + sampling_period_us = round(1000000*(1.0/samplingFrequency)); + Serial.begin(115200); + Serial.println("Ready"); +} + +void loop() +{ + /*SAMPLING*/ + microseconds = micros(); + for(int i=0; i<samples; i++) + { + vReal[i] = analogRead(CHANNEL); + vImag[i] = 0; + while(micros() - microseconds < sampling_period_us){ + //empty loop + } + microseconds += sampling_period_us; + } + /* Print the results of the sampling according to time */ + Serial.println("Data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */ + Serial.println("Weighed data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.compute(FFTDirection::Forward); /* Compute FFT */ + Serial.println("Computed Real values:"); + PrintVector(vReal, samples, SCL_INDEX); + Serial.println("Computed Imaginary values:"); + PrintVector(vImag, samples, SCL_INDEX); + FFT.complexToMagnitude(); /* Compute magnitudes */ + Serial.println("Computed magnitudes:"); + PrintVector(vReal, (samples >> 1), SCL_FREQUENCY); + float x = FFT.majorPeak(); + Serial.println(x, 6); //Print out what frequency is the most dominant. + while(1); /* Run Once */ + // delay(2000); /* Repeat after delay */ +} + +void PrintVector(float *vData, uint16_t bufferSize, uint8_t scaleType) +{ + for (uint16_t i = 0; i < bufferSize; i++) + { + float abscissa; + /* Print abscissa value */ + switch (scaleType) + { + case SCL_INDEX: + abscissa = (i * 1.0); + break; + case SCL_TIME: + abscissa = ((i * 1.0) / samplingFrequency); + break; + case SCL_FREQUENCY: + abscissa = ((i * 1.0 * samplingFrequency) / samples); + break; + } + Serial.print(abscissa, 6); + if(scaleType==SCL_FREQUENCY) + Serial.print("Hz"); + Serial.print(" "); + Serial.println(vData[i], 4); + } + Serial.println(); +} |
