From c22e30a4a6ef014c7a5086ad47eaab7740a75ff2 Mon Sep 17 00:00:00 2001 From: Ceimour <113631258+Ceimour@users.noreply.github.com> Date: Sun, 30 Apr 2023 08:50:18 -0500 Subject: 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). --- .../Examples/FFT_speedup/FFT_speedup.ino | 129 +++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 src/libs/arduinoFFT-develop/Examples/FFT_speedup/FFT_speedup.ino (limited to 'src/libs/arduinoFFT-develop/Examples/FFT_speedup') 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 . + +*/ + +// 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. +//#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 FFT = ArduinoFFT(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> 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(); +} -- cgit v1.2.3-70-g09d2