Doing DFT without using FFT function
Afficher commentaires plus anciens
Hi all,
I'm working on a project that handles ECG data from arduino and ran into some problems while computing the discrete fourier transform of the ECG. I would like to view the transforms and data collection in real time. While the real time data collection works fine, I would prefer not to use the fft function because for academic uses, the hard coded formula of the fourier transform has more learning value. The code in entirety is as shown below:
clear
delete(instrfindall);
%initialize communication with arduino
arduino = serial('COM6');
arduino.Baudrate=9600;
fopen(arduino);
%initialize figures
figure;
%fig1 = figure;
%fig2 = figure;
%fig3 = figure;
%fig4 = figure;
%initialize sample and counter
sampleSize = 500;
a=1;
while (a < sampleSize) %doubles as a counter, 1000 samples takes about 10seconds
%collects raw data in string format
timeRaw = fgets(arduino);
ecgRaw = fgets(arduino);
%converts string data to numbers
time = str2double(timeRaw) / 1000;
ecg = str2double(ecgRaw);
%data allocation
dataTime(a,1) = time;
dataECG(a,1) = ecg;
%FFT
frequency = 1/time;
fftEcg = fft(ecg);
for k = 1:a
X(k,1) = 0;
for n = 1:a
X(k,1) = X(k,1)+(dataECG(n,1)*exp((-1j)*2*pi*(n-1)*(k-1)/a));
end
end
mag(a,1) = abs(X(a,1));
dataFreq(a,1) = frequency;
dataFft(a,1) = fftEcg;
%low pass filter, set at 50Hz
%sampling freq 80~90Hz, partly determined by delay in arduino
if (frequency < 10)
Y = fftEcg;
dataY(a,1) = Y;
else
Y = 0;
dataY(a,1) = Y;
end
%inverse FFT
dataIfft(a,1) = ifft(Y);
%plotting of figures, subplots are too small, 4 windows too messy
subplot(411);
%figure(fig1);
plot(dataTime,dataECG,'k-');
xlabel('Time (sec)');
ylabel('x(t) magnitude');
subplot(412);
plot(dataFreq,mag,'k-');
xlabel('Frequency (Hz)');
ylabel('X(jw) magnitude');
%subplot(412);
subplot(413);
%figure(fig2);
plot(dataFreq,dataFft,'k-');
xlabel('Frequency (Hz)');
ylabel('X(jw) magnitude');
%subplot(413);
%figure(fig3);
%plot(dataFreq,dataY,'k-');
%xlabel('Frequency (Hz)');
%ylabel('Filtered H(jw) magnitude');
subplot(414);
%figure(fig4);
plot(dataTime,dataIfft,'k-');
xlabel('Frequency (Hz)');
ylabel('Filtered x(t) magnitude');
%command to draw and take in next sample by increasing counter
drawnow;
a = a + 1;
end
%data collection into csv format
%intialize array for final data set
%finalData = zeros(sampleSize,2);
%data collection for raw data only
%for i=1:(sampleSize-1)
% finalData(a,1) = dataTime(a,1);
% finalData(a,2) = dataECG(a,1);
%end
%csvwrite('data.csv', finalData);
fclose(arduino);
return;
In particular the formula that I keyed in is found in this few lines of code:
for k = 1:a
X(k,1) = 0;
for n = 1:a
X(k,1) = X(k,1)+(dataECG(n,1)*exp((-1j)*2*pi*(n-1)*(k-1)/a));
end
end
mag(a,1) = abs(X(a,1));
The results between the fft function and the formula I've input are very different, any ideas how I can modify the formula?
2 commentaires
One Dimensional DFT Function, without using for loop:
function [Xk] = dft(xn)
len = length(xn);
w = 2*pi*linspace(0,1,len);
n = 1:len;
Xk = exp(-1j*w'*n)*xn';
Angus Keatinge
le 28 Avr 2018
Modifié(e) : Angus Keatinge
le 28 Avr 2018
This is wrong, the dft is from 0 to N-1 whereas linspace includes the extremities. You won't only have a redundant value at the last index, but every frequency term will be scaled differently to the N point dft (they will be scaled to an N-1 point dft). It is quite a common error, you can correct it by changing the lines:
w = 2*pi*linspace(0,1-1/len,len);
Xk = exp(-1j*w'*(n-1))*xn';
Réponse acceptée
Plus de réponses (1)
Piotr Gregor
le 1 Juil 2022
0 votes
Here's my implementation of DFT and IDFT:
Catégories
En savoir plus sur Time-Frequency Analysis dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!