Go Down

Topic: ECG, FFT and IFFT (Read 161 times) previous topic - next topic

blackleg15

(Before all, I'm sorry for my bad English)

Hello, guys. I'm just a beginner on Arduino but I have a little question.

I'm studying Arduino to make a ECG platform. My reference source is: Physionet Database.

The float values are on the EEPROM.

I have a piece of code that perform (I think) FFT in double values.

To have sure about the code, I need to perform IFFT in the result of the operation.

Code: [Select]

#include <EEPROM.h>
#include "arduinoFFT.h"

#define SAMPLES 512             
#define SAMPLING_FREQUENCY 1000

unsigned int sampling_period_us;
unsigned long microseconds;
double vReal[SAMPLES];
double vImag[SAMPLES];

arduinoFFT FFT = arduinoFFT();

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


void loop(){
    int eepromAdd = 0;
 
    for(int i=0; i<SAMPLES; i++){
        microseconds = micros();   
        vReal[i] = EEPROM.get(eepromAdd, vReal[i]);
        vImag[i]=0;
        eepromAdd += sizeof(float);
    }
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
   
    for(int i=0; i<SAMPLES; i++){
     
      //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
      //Serial.print(" ");
      Serial.println(vReal[i], 3 );
    }   
    while(1);   
} //end loop


Can anyone help me to find a way to perform IFFT in double values?

el_supremo

#1
May 25, 2018, 11:18 pm Last Edit: May 25, 2018, 11:21 pm by el_supremo
Which Arduino? On most Arduinos, 'double' is the same as 'float'.

Pete
Don't send me technical questions via Private Message.

blackleg15

Arduino Mega.

Yep, 'double' was wrong.

I mean 'float', sorry.

jremington

#3
Today at 01:53 am Last Edit: Today at 01:58 am by jremington
The correct way to test an FFT program is to prepare input data with a known transform, and verify that the FFT operation gives the expected result (except for a possible amplitude scale factor).

For example, prepare a simple sine wave input and verify that the resulting power spectrum has a single peak at the correct frequency.

The following code does that to test a much faster version of the FFT than the one you are using.

Code: [Select]
/*
 fft_test_sine
 example sketch for testing the OpenMusicLabs fft library.
 This generates a simple sine wave data set consisting
 of two frequences f1 and f2, transforms it, calculates
 and prints the amplitude of the transform.
 */

// do #defines BEFORE #includes
#define LIN_OUT 1 // use the lin output function
#define FFT_N 64 // set to 64 point fft

#include <FFT.h> // include the library

void setup() {
  Serial.begin(9600); // output on the serial port
}

void loop() {
  int i,k;
  float f1=2.0,f2=5.0;  //the two input frequencies (bin values)
  for (i = 0 ; i < FFT_N ; i++) { // create samples
    // amplitudes are 1000 for f1 and 500 for f2
    k=1000*sin(2*PI*f1*i/FFT_N)+500.*sin(2*PI*f2*i/FFT_N);
    fft_input[2*i] = k; // put real data into even bins
    fft_input[2*i+1] = 0; // set odd bins to 0
  }
 
  fft_window();  //Try with and without this line, it smears

  fft_reorder(); // reorder the data before doing the fft
  fft_run(); // process the data using the fft
  fft_mag_lin(); // calculate the magnitude of the output

  // print the frequency index and amplitudes

  Serial.println("bin  amplitude");
  for (i=0; i<FFT_N/2; i++) {
    Serial.print(i);
    Serial.print("       ");
    Serial.println(2*fft_lin_out[i]); //*2 for "negative frequency" amplitude
  }
  Serial.println("Done");
  while(1); //wait here
}





el_supremo

The arduinoFFT library doesn't appear to have an explicit way of doing an IFFT.
Why do you "need to perform" the IFFT? What is it going to tell you?

To add to what @jremington has just posted, the result of an IFFT won't necessarily produce exactly the same data as your input to the FFT, so it's not a good test of an FFT library.

Pete
Don't send me technical questions via Private Message.

jremington

#5
Today at 04:35 am Last Edit: Today at 04:38 am by jremington
Quote
an IFFT won't necessarily produce exactly the same data as your input to the FFT,
Good point. In fact, most of them don't.

If you apply the N point discrete Fourier transform in the forward and then the inverse direction, the original data are returned, but multiplied by a factor of N (unless the code explicitly takes this factor into account).

There is no standard about how to deal with that factor. In some cases N divides explicitly into the reverse transform, but in other definitions (like that used in Mathematica), the forward and reverse transforms are multiplied by 1/sqrt(N), so that forward and reverse return the original data.

This is discussed in https://en.wikipedia.org/wiki/Discrete_Fourier_transform (scroll down to "unitary DFT").

blackleg15

Why do you "need to perform" the IFFT? What is it going to tell you?
To compare with my FFT input.

To add to what @jremington has just posted, the result of an IFFT won't necessarily produce exactly the same data as your input to the FFT, so it's not a good test of an FFT library.
I thought IFFT would result the same data as input to the FFT, haha. Sorry, I'm just a beginner.

My teacher told me to verify that, but, well... ok.

He told me like "Do FFT and then IFFT to make sure FFT is working well".

Look, I need to apply filters (low pass/high pass/band pass/band stop) in the ECG signals to clear it.

How can I do that? Can you guys help me? I really would like to learn.

jremington

#7
Today at 06:05 am Last Edit: Today at 06:09 am by jremington
Quote
He told me like "Do FFT and then IFFT to make sure FFT is working well".
If you work a bit at this, you will end up understanding the material much better than your instructor.

You absolutely must have a good low pass filter in the electrode/amplifier setup that prevents any signals with frequency higher than 1/2 your sample frequency from entering the Arduino. Otherwise the results will be uninterpretable.

For example, if your Arduino sample frequency is 100 Hz, under no circumstances can you allow a signal with frequency greater than 50 Hz get to the input.

Look up "sampling theorem" and "Nyquist limit" for more information.

stowite

The FFT is just a fast and accurate algorithm to perform the Discrete Fourier Transform (DFT) .

The inverse of  a DFT can be obtained by
1) Create the complex conjugate of the DFT coeficients,
2) Perform the DFT of the result of (1),
3) Create the complex conjugate of the result of (2),
4) Scale the result of (3) by the number of points.


blackleg15

The code to insert the float values follows:

Code: [Select]

#include <EEPROM.h>

struct MyObject {
  float field1;
  byte field2;
  char name[10];
};

void setup() {

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  float f;  //Variable to store in EEPROM.
  int eepromAdd = 0;   //Location we want the data to be put.


  //One simple call, with the address first and the object second.
  EEPROM.put( eepromAdd,-0.085); eepromAdd += sizeof(float);
  EEPROM.put( eepromAdd,-0.080); eepromAdd += sizeof(float);
  EEPROM.put( eepromAdd,-0.070); eepromAdd += sizeof(float);
  EEPROM.put( eepromAdd,-0.075); eepromAdd += sizeof(float);
  EEPROM.put( eepromAdd,-0.095); eepromAdd += sizeof(float);
  EEPROM.put( eepromAdd,-0.090); eepromAdd += sizeof(float);
.
.   ~more EEPROM.put~
.
  Serial.println(eepromAdd);//printing the address
 
  Serial.println(EEPROM.get(4,f),3);//2nd float
  Serial.println(EEPROM.get(8,f),3);//3rd float
  Serial.println(EEPROM.get(12,f),3);//4th float
}


PS: ECG samples from Physionet Database; Sample rate: 2 miliseconds

el_supremo

I've had a brief look at the ECG samples available at Physionet. Are you using this set? If so, each sample contains the raw ECG and a filtered version. Presumably the raw samples have already been low-passed

Quote
I'm studying Arduino to make a ECG platform
What exactly are you trying to implement on the MEGA - what do you mean by a "platform"? If all you're going to do is some offline processing of samples from the Physionet database (e.g. filtering, beat detection), the MEGA will suffice. But if you want to do real-time collection, analysis and display of ECGs, the MEGA would not be my first choice :)

Pete
Don't send me technical questions via Private Message.

blackleg15

Actually, I am using this source by Phyionet.

But if you want to do real-time collection, analysis and display of ECGs, the MEGA would not be my first choice :)
Oh... really?

Actually, I want to do that!

Can you explain me why and to say me a alternative device/way to do that (any other choice)?

el_supremo

Quote
Actually, I want to do that!
How? Do you have any idea what is involved?

Quote
Look, I need to apply filters (low pass/high pass/band pass/band stop) in the ECG signals to clear it.
How can I do that? Can you guys help me? I really would like to learn.
What is your level of education?
If you don't know which filter(s) you would use to reduce noise in a signal and you don't already know how to do it, you are a very long way from implementing an "ECG platform".

Pete
Don't send me technical questions via Private Message.

blackleg15

#13
Today at 09:45 pm Last Edit: Today at 09:48 pm by blackleg15
I am a college student of Information Technology. Actually, all of this is a research project.

I'm 19 years old.

I saw my teacher spreading it and I became interested. I really appreciate it.

But... I know just a little bit of information.

However, 4 friends of mine are helping me, even my teacher.

Go Up