Remove contribution from the first point of the Fourier transform to add that of the last

Hello, I'm building a ECG using Arduino MEGA 2560. I've already built the circuit and now I'm on the data processing phase.

I want to measure the BPM in real time, for that I'm taking data from the patient (let's call it like that) for 8 seconds and then using the FFT (from the library "arduinoFFT.h") to get the predominant frequency, hence the BPM. And I do that continuously, each time I calculate the FFT I start collecting new data for 8 seconds and so on, so that way I get the BPM "in real time".

I wanted to know if there is a way to remove the contribution from the first point of the Fourier transform to add that of the last point (voltage in my case) measured, so that my FFT is continuously updated and the calculation is faster.

Thank you.

are you using a Pulse Sensor or electrodes?

Electrodes

OK - I'm unsure what you mean about first and last point (samples or frequency bands ?)

(a Pulse Sensor would give the BPM pretty easily)

``````/*

Heartbeat counter using FFT

Reads an analog input on pin 15 (heartbeat) which is stored inside the vReal array. The heartbeat
is windowed according to Hamming function. The FFT is computed using the windowed signal. 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, hence the BPM.

*/

#include "arduinoFFT.h"

arduinoFFT FFT = arduinoFFT(); /* Create FFT object */

const uint16_t samples = 256; /* This value MUST ALWAYS be a power of 2 */

double vReal[samples];
double vImag[samples];
double t[samples];

#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03

void setup() {
Serial.begin(38400);
while(!Serial);
}

void loop() {
/* Sampling */
for (uint16_t i = 0; i < samples; i++)
{
t[i] = micros(); /* Store the time */
//Serial.println(t[i]);
vReal[i] = analogRead(A15); /* Read the electrical signal of the heart */
vImag[i] = 0.0;
delay(31.25); /* Delay between readings of channel A15 */
}

const double samplingFrequency = (samples)/((t[samples - 1] - t[0])*pow(10, -6));
//Serial.println(samples);
//Serial.println((t[samples - 1] - t[0])*pow(10, -6));
//Serial.println(samplingFrequency);

FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */
FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
double x = FFT.MajorPeak(vReal, samples, samplingFrequency)*60;
Serial.print("BPM: ");
Serial.println(x, 6);
//delay(500); /* Repeat after delay */
}
``````

I'm storing in an array the voltage I read from the electrodes, I'm using 256 samples, and then I'm calculating the FFT. I'm repeating that all the time so that I get the actualised BPM. The thing is that if I have to read and store all new 256 it takes more time. I wanted to know if there is a way in which I don't have to do that. I could just read the next voltage value and put it in my Fourier transform (to do that I would have to eliminate the first voltage value I used so that I still have 256 samples). I don't know if I'm making myself clear.

You want to make a circular buffer? This link might show you how to make a moving average filter. Moving-Avarage-Filter--Arduino-Library-/MovingAverageFilter.cpp at master · sebnil/Moving-Avarage-Filter--Arduino-Library- (github.com)

so you mean shifting the data in `vReal[]` and inject the last analogRead() into the last slot of the array?

the calls to the library do modify the array, so you would need to have a spare buffer and use memcpy() to shift it and then inject into `vReal[]`

the library does not deal with a circular buffer but that could also be what you use for the spare buffer, saving you one memcpy()

Short-time FFT approach:

https://en.wikipedia.org/wiki/Short-time_Fourier_transform

https://manual.dewesoft.com/x/setupmodule/modules/general/math/freqdomainanalysis/stft

STFT is a well-known technique in signal processing to analyze non-stationary signals. STFT is segmenting the signal into narrow time intervals and takes the Fourier transform of each segment. In Dewesoft’s FFT setup you can set FFT’s resolution, Window, and Overlap and for better understanding what that means, let’s look at the picture below. Window size depends on FFT’s resolution, we can just say FFT size (representing a segment of a signal).

u

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.