Remove contribution from the first point of the Fourier transform to add that of the last – #6 by schrodingal – Programming Questions

/*
 
  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);
  Serial.println("Ready");
}

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 */
}

Read more here: Source link