I have question about filtering.
Currently I am working on pedestrian step detection using an inertial measuring unit (accelerometer/acceleration data). I need to filter my signal at preprocessing level. Could anyone suggest which one will be the best filtration algorithm to get good accuracy?
For now I used digital lowpass fir filter with order=2, window size=1.2sec,sampling frequecy=200hz but seems not working. I want to use a lower cutoff frequency. I used 0.03hz and 3hz of cutoff frequecny but I am getting the same result for both cutoff frequencies. I need your guidance or help that how can I proceed. Below, I am attaching the images of filtration result as link at 3hz and 0.03hz respectively and also code that I tried.
Could some one suggest me or provide any good filter in matlab and/or how can I work on that?
fir result at 3hz cutoff fir result at 0.03hz cutoff
Fs = 200;
Hd = designfilt('lowpassfir','FilterOrder',2,'CutoffFrequency',0.03, ...
'DesignMethod','window','Window',{#kaiser,1.2},'SampleRate',Fs);
y1 = filter(Hd,norm);
plot(Time,norm,'b', Time, y1,'red')
xlabel('Time (s)')
ylabel('Amplitude')
legend('norm','Filtered Data')
I am adding another answer in reply to your followup questions. A rectangular window (or boxcar window) of width T, when used as moving average filter, is a lowpass filter with transfer function magnitude
|H(f)|=(sin(pifT))/(pifT) (1)
as you can verify by doing the Fourier transform. Therefore H(f)=0.707 when fco=0.44/T, and H(f)=0 when f=1/T. So a lowpass filter with cutoff fco can be implemented with a rectangular window with width on the order of 1/fco (specifically .44/fco). When fco=0.03 Hz, width is on the order of 30 s (specifically 15 s). See plot of transfer function of a 30 s-wide window.
How to find the necessary order:
>> Fs=200; Fc=.03;
>> Hd003=designfilt('lowpassfir','CutoffFrequency',Fc,'SampleRate',Fs);
Hd003 = designfilt('lowpassfir', 'PassbandFrequency', .03, 'StopbandFrequency', .1, 'PassbandRipple', 3, 'StopbandAttenuation', 20, 'SampleRate', 200, 'DesignMethod', 'kaiserwin');
>> disp(length(Hd003.Coefficients));
2400
The command Hd003=designfilt(...) above causes the Filter Design Assistant to launch, because designfilt() does not have enough info. In the FDA, specify Order mode = Minimum, Passband freq=0.03, Stopband freq=0.1, passband ripple=3 dB, stopband atten.=20 db, design method=Kaiser window. I chose those frequencies and dB values because a 2nd order Butterworth does equally well. (See figure.) Then click "OK", and control returns to the Matlab command window, which runs 'designfilt' with the specified parameters. Then check the length of the coefficient vector: it is 2400! I.e. the FIR filter order=2399, and the filter is 12 seconds long. This is not practical, and it is totally un-usable on signals as short as your 1.6 second long example.
This equation for |H(f)| is for continuous time. It is accurate for discrete time also, as long as the sampling rate Fs>=10/T.
You tried to make a 2nd order FIR filter. That order is far to low for your sampling rate (200 Hz) and desired cutoff frequency (3 or 0.03 Hz). The required order in a FIR filter is very different from the order of an IIR filter. An Nth order FIR filter does a moving average of N+1 data points. Hd=designfilt(...) computes the coefficients, or weights, for the moving average. I made the 3 Hz and 0.03 Hz cutoff filters, using your code fragment, and called them Hd300 and Hd003. Then I viewed the coefficients for the two filters:
>> disp(Hd003.Coefficients);
0.2947 0.4107 0.2947
>> disp(Hd300.Coefficients);
0.2945 0.4110 0.2945
As you can see, they are practically identical - which is why the output filtered signals look the same. The coefficients are very similar because order=2 is far, far too low to make an effective FIR filter of 3 or 0.03 Hz cutoff, when the sampling rate is 200 Hz.
The 0.03 cutoff frequency which you tried corresponds to a time constant of about 30 (=1/.03) seconds. It does not make sense to use such a low cutoff on data which is only 1.6 seconds long. Even if you had hundreds of seconds of data, it would not make sense, because you would be smoothing the data with about a 30 second wide window, which would make it very hard to detect each step.
A better approach: a simple 2nd order Butterworth lowpass, cutoff frequency=1 to 10 Hz. See code below and see figure. I used filtfilt() in my code rather than filter(), because filtfilt() handles the startup transient better. Replace filtfilt() with filter() and you will see what I mean.
%pedometerAccelFilter.m WCR 20210117
% Question on stack exchange
% The code provided on stack exchange assumes vector "norm"
% contains 1.6 seconds of acceleration data sampled at 200 Hz.
% I digitized the data from the figure on stack exchange and
% saved it in file pedometerInterpData.txt (2 columns, 329 rows).
%Load the data
data=load('pedometerInterpData.txt');
Time=data(:,1); norm=data(:,2);
%Compute the filter coefficients
Fs=200; %sampling frequency (Hz)
order=2;
Fc1=5; %filter 1 cutoff frequency (Hz)
Wn1=Fc1*2/Fs; %filter 1 normalized cutoff frequency
[b1,a1]=butter(order,Wn1); %filter 1 coefficients
Fc2=2; %filter 2 cutoff frequency (Hz)
Wn2=Fc2*2/Fs; %filter 2 normalized cutoff frequency
[b2,a2]=butter(order,Wn2); %filter 2 coefficients
%Filter the data
y1=filtfilt(b1,a1,norm); %filtfilt() could be replaced with filter()
y2=filtfilt(b2,a2,norm);
%Plot the data
plot(Time,norm,'r.-',Time,y1,'gx-',Time,y2,'bo-');
xlabel('Time (s)'); ylabel('Amplitude');
legend('Raw Data','Filter 1','Filter 2');
Figure created by code above.
I have a second order sigma delta modulator in simulink matlab. it's working fine i applied a sinusoidal waveform to the input with Vp - p = 1V and i have the same waveform(with a little delay), after low-pass filtering in the output :
I get this for fft :
fft
sampling freq=256 MHz
input freq= 4MHz
Period of sample and hold clock is 1/256MHZ
And also sample time for adc_out block seen in the pic is 1/256MHz
And i didn't touch anything else.
And i calculated the input freq based on this formula :
fin=(prime/N)* sampling freq
Prime is prime number, i chose 257
N is number of fft points, i chose 16384
sampling freq is 256MHz
therefore i got 4MHz as the best input freq and these considerations, after fft, were supposed to give me a nice impulse at 4MHz and the shaped noise in the higher frequencies
as you can see i don't have my desired imupulse at 4MHz!
and i just don't know why!!
Just peeking at the image, I'd say it's a windowing issue. In particular, since you don't use an explicit window, you are using a block function. The FFT of a block is sin(x)/x, which is convoluted with your real response.
I want to take a wav. file and plot it in Time Domain and Frequency Domain on MATLAB.
I have this code thus far;
[y,fs]=wavread('FireAlarm');
%wavread=the function that is going to read the wav.file
%y=samples
%fs=sampling frequency
%'FireAlarm'=wav file
t=linespace(0,length(y)/fs,length(y));
%linespace=the function that is going to create the time vector
%0=start time
%length(y)/fs=ending time
%length(y)= number of samples in y
plot(t,y)
Nfft=1024;
%Nfft=the length of fft
f=linespace(0,fs,Nfft);
%f= frequency vector
%0=first frequency
%fs=ending frequency
%nfft=length of the frequency vector
G=abs(fft(y,Nfft));
%G= the fft of the samples y in 1024 points
figure;plot(f(1:Nfft/2),G(1:Nfft/2)
Before I can even finish typing the first section, MATLAB tells there is an undefined function or variable 'wavread'.
Anyone know why this may be?
This is my first question on this site, so I'm sorry if I do something wrong...
What I want is to convert a signal (which I recorded with aSpectrum Analyzer from Texas Instruments) from frequency domain to time domain.
The problem is that the software for the Analyzer can be configured just to show frequency domain, so I can't see signals in time domain. I recorded my signal and I exported it to an Excel file. In that file I have a column with frequencies and another column with powers. How can I create a signal using these 2 vectors in Matlab / Simulink and then convert it in time domain?
The spectrum analyser has gotten you each of the wave frequencies in the original frequency. (To a certain accuracy)
Firstly you will need to convert the dBV power of the signal to V. A formula for this can be found on google. ---logarithmic formulae are tricky formula to type out---
Lets say you have a peak at 5Hz with an amplitude of 3V and one at 7Hz with a amplitude of 2V. (You can have as many waves as you like)
1 rad = 1/(2*pi) Hz
That means: 5Hz = 10*pi rad and 7Hz = 14*pi rad
Now that you you have the frequency in radians you can make the wave. By a summation of cosines.
x(t) = A.cos(wt + [phase shift])
w = wave frequency (rad)
A = wave amplitude (V)
t = time
So your wave is:
x(t) = 3.cos(10*pi*t) + 2.cos(14*pi*t)
x(t) is now your output wave. The units are in V but can be converted back to dBV if you'd like. You can specify how long the wave should be, or how many intervals the wave has by assigning a row vector to t. e.g. (t = [0:0.005:1] will give you five periods of the 5Hz wave and seven of the 7Hz wave.)
Unfortunately there is no way to recover the phase shift data from the original signal with only the spectral data. However, the human ear cannot hear a phase difference in waves so perhaps this is suitable for your application.
If you'd like to learn more about he reconstruction of the wave you should look into how the Fourier Series is constructed.
I have taken a 32Gbps NRZ signal measurement using a real time oscilloscope. I have the time and values in 2 different columns (time domain data). I have imported the 2 values to two different arrays in Matlab (NRZ_time, NRZ_values).
Now, I want to compute the FFT of the signal. I know it can be done like this.
NRZ_fft = fft(NRZ_values);
Then, I want to plot the magnitude and phase response which I am doing with
figure;
plot(abs(NRZ_fft));
figure;
plot(angle(NRZ_fft));
I am sure the magnitude response is correct but the phase response is wrong according to me. Can someone confirm, I am doing it right or not?
Also I want to find the sampling frequency from this data. There are 65521 samples. The first value in the time column is -0.0000000166801500 and the last value is 0.0000000345073500. So, the length of the signal is:
0.0000000345073500 - (-0.0000000166801500) = 5.1187e-008.
How do I calculate the sampling frequency from this data?