(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.
#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?
Which Arduino? On most Arduinos, 'double' is the same as 'float'.
Pete
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.
/*
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
}
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
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 Discrete Fourier transform - Wikipedia (scroll down to "unitary DFT").
el_supremo:
Why do you "need to perform" the IFFT? What is it going to tell you?
To compare with my FFT input.
el_supremo:
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.
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.
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
- Create the complex conjugate of the DFT coeficients,
- Perform the DFT of the result of (1),
- Create the complex conjugate of the result of (2),
- Scale the result of (3) by the number of points.
The code to insert the float values follows:
#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
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
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
Actually, I am using this source by Phyionet.
el_supremo:
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)?
Actually, I want to do that!
How? Do you have any idea what is involved?
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
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.
Filtering involves Digital Signal Processing. There is a useful online text about DSP which would give you a good introduction to filtering and also FFT and other aspects of DSP: http://www.dspguide.com/
Unfortunately, the Arduino forum is not the place to teach everything that you need to know and/or understand to enable you to implement an ECG platform.
Where are you getting the floating point numbers from in your message #9? How do you get -0.085, -0.080, etc.? The Physionet samples I've seen are 12-bit signed integers.
P.S. Why are you putting the samples in the EEPROM?
Pete
el_supremo:
Where are you getting the floating point numbers from in your message #9? How do you get -0.085, -0.080, etc.? The Physionet samples I've seen are 12-bit signed integers.
A.: Go to message #11. "this source" --> Phyionet ATM or stuff
The float values from there are like: -0.085, etc.
I downloaded samples (first sample) and copied their values.
el_supremo:
P.S. Why are you putting the samples in the EEPROM?
My teacher said me to do that... Now, I don't remember why.
Maybe just to test with FFT.
What do you really want to do? What is the long term plan? At the moment, you seem to be just wasting both your own and our time.
I want to do a real-time signal collector, filter and monitor for ECG signals.
But, I really want to know how.
Actually, a ECG platform, a research project from college.
I am questioning in this forum because the chosen device by my teacher was Arduino.
Actually, a ECG platform, a research project from college.
There's that "ECG platform" again. What is it? What is it going to do? Who is going to use it and how would they use it?
I want to do a real-time signal collector, filter and monitor for ECG signals.
But, I really want to know how.
You really need to get a handle on what exactly it is that you are supposed to be doing and why.
What do you already know about:
- real-time signal collection
- digital signal filtering
- C/C++ programming for an Arduino
You seem to be starting from zero knowledge about what is involved and, as I've mentioned before, this is not a teaching forum.
Do your college courses cover any of the subjects I've mentioned above? Your college is where you should be learning this stuff. If they don't teach it, then I don't see why you have a "research project" which involves subjects they don't cover.
I think you've bitten off far more than you can chew. You need to start with something much smaller and simpler and build your way up.
Pete
Okay, man.
Thank you, guys, very much.
I really appreciate your tips.
See ya.