aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/arduinoFFT-develop/Examples/FFT_speedup
diff options
context:
space:
mode:
authorCeimour <113631258+Ceimour@users.noreply.github.com>2023-04-30 08:50:18 -0500
committerGitHub <noreply@github.com>2023-04-30 15:50:18 +0200
commitc22e30a4a6ef014c7a5086ad47eaab7740a75ff2 (patch)
tree5afdf4ed624a8b41dc4aea723a8c8f38d726545a /src/libs/arduinoFFT-develop/Examples/FFT_speedup
parent40f7e1c7be6882e01058b5ccf64d5005c6105346 (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/FFT_speedup')
-rw-r--r--src/libs/arduinoFFT-develop/Examples/FFT_speedup/FFT_speedup.ino129
1 files changed, 129 insertions, 0 deletions
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();
+}