why 50hz can't be removed compeletely?

1 Ansicht (letzte 30 Tage)
Xiaolong wu
Xiaolong wu am 23 Nov. 2020
Beantwortet: Mathieu NOE am 24 Nov. 2020
Dear, I am try to remove the 50 hz. It works very well if I plot the result using amplitude. However when when I plot the result using 10*log10(amp), the 50hz will be still there with large amplitude.
%% build filter
N = 20; % Order
F3dB1 = 49; % First
F3dB2 = 51; % Second
Fs = 1000; % Sampling Frequency
d = designfilt('bandstopiir','FilterOrder',2, ...
'HalfPowerFrequency1',49,'HalfPowerFrequency2',51, ...
'DesignMethod','butter','SampleRate',Fs);
%% test data
fs = 1000;
t = 0:1/fs:5-1/fs;
x = cos(2*pi*50*t)+cos(2*pi*100*t);
%plot(t,x)
%plotChannelSpectral(x);
[psd,f] = pwelch(x,500,200,500,1000);
plot(f,10*log10(psd));
plot(f,(psd));
fdata=filtfilt(d,double(x));
[psd2,f2] = pwelch(fdata,500,200,500,1000);
figure;
plot(f2,psd2); % 50hz almost gone in this plot
plot(f,10*log10(psd2)); % however I still can see large 50hz in this plot, even I re-run the filtfilt 20 times, I still can see relative large amplitude around 50hz, though there is a groove at 50hz.
Does it means that I should be satisfied as long as I can't see the 50hz in amplitude? And there is no way to totally eliminate the large value under 10*log10(amplitude)?
Thanks in advance.

Akzeptierte Antwort

Mathieu NOE
Mathieu NOE am 24 Nov. 2020
hello again
I like simple solutions - see demo code below adapted to your case
I hope 200 dB attenuation can be considered as "complete washed out" !!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FFT parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
NFFT = 1024*4; %
NOVERLAP = round(0.75*NFFT);
w = hanning(NFFT); % Hanning window / Use the HANN function to get a Hanning window which has the first and last zero-weighted samples.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% test data
Fs = 1000;
t = 0:1/Fs:10-1/Fs;
signal = cos(2*pi*50*t)+cos(2*pi*100*t);
%% notch filter section %%%%%%
% H(s) = (s^2 + 1) / (s^2 + s/Q + 1)
fc = 50; % notch freq
wc = 2*pi*fc;
Q = 2; % adjust Q factor for wider (low Q) / narrower (high Q) notch
% at f = fc the filter has gain = 0
w0 = 2*pi*fc/Fs;
alpha = sin(w0)/(2*Q);
b0 = 1;
b1 = -2*cos(w0);
b2 = 1;
a0 = 1 + alpha;
a1 = -2*cos(w0);
a2 = 1 - alpha;
% analog notch (for info)
num1=[1/wc^2 0 1];
den1=[1/wc^2 1/(wc*Q) 1];
% digital notch (for info)
num1z=[b0 b1 b2];
den1z=[a0 a1 a2];
freq = linspace(fc-1,fc+1,200);
[g1,p1] = bode(num1,den1,2*pi*freq);
g1db = 20*log10(g1);
[gd1,pd1] = dbode(num1z,den1z,1/Fs,2*pi*freq);
gd1db = 20*log10(gd1);
figure(1);
plot(freq,g1db,'b',freq,gd1db,'+r');
title(' Notch: H(s) = (s^2 + 1) / (s^2 + s/Q + 1)');
legend('analog','digital');
xlabel('Fréquence (Hz)');
ylabel(' dB')
% now let's filter the signal
signal_filtered = filtfilt(num1z,den1z,signal);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display : averaged FFT spectrum before / after notch filter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[sensor_spectrum, freq] = pwelch(signal,w,NOVERLAP,NFFT,Fs);
sensor_spectrum_dB = 20*log10(sensor_spectrum);% convert to dB scale (ref = 1)
[sensor_spectrum_filtered, freq] = pwelch(signal_filtered,w,NOVERLAP,NFFT,Fs);
sensor_spectrum_filtered_dB = 20*log10(sensor_spectrum_filtered);% convert to dB scale (ref = 1)
figure(2),semilogx(freq,sensor_spectrum_dB,'b',freq,sensor_spectrum_filtered_dB,'r');grid
title(['Averaged FFT Spectrum / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(freq(2)-freq(1)) ' Hz ']);
legend('before notch filter','after notch filter');
xlabel('Frequency (Hz)');ylabel(' dB')

Weitere Antworten (1)

Mathieu NOE
Mathieu NOE am 23 Nov. 2020
hello
2 gifts for you in the same day (you lucky ! )
  • a code for spectral analysis and time / frequency analysis
  • a the end , some code for a better notch filter digital implementation ; your notch is not effective enough
hope it helps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FFT parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
NFFT = 1024; %
NOVERLAP = round(0.75*NFFT);
w = hanning(NFFT); % Hanning window / Use the HANN function to get a Hanning window which has the first and last zero-weighted samples.
% spectrogram dB scale
spectrogram_dB_scale = 80; % dB range scale (means , the lowest displayed level is XX dB below the max level)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% options
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% if you are dealing with acoustics, you may wish to have A weighted
% spectrums
% option_w = 0 : linear spectrum (no weighting dB (L) )
% option_w = 1 : A weighted spectrum (dB (A) )
option_w = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%[data,Fs]=wavread('Approach_Gear_Drop_Aft Ctr.wav '); %(older matlab)
% or
[data,Fs]=audioread('myWAVaudiofile.wav'); %(newer matlab)
channel = 1;
signal = data(:,channel);
samples = length(signal);
dt = 1/Fs;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 1 : averaged FFT spectrum
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[sensor_spectrum, freq] = pwelch(signal,w,NOVERLAP,NFFT,Fs);
% convert to dB scale (ref = 1)
sensor_spectrum_dB = 20*log10(sensor_spectrum);
% apply A weigthing if needed
if option_w == 1
pondA_dB = pondA_function(freq);
sensor_spectrum_dB = sensor_spectrum_dB+pondA_dB;
my_ylabel = ('Amplitude (dB (A))');
else
my_ylabel = ('Amplitude (dB (L))');
end
figure(1),semilogx(freq,sensor_spectrum_dB);grid
title(['Averaged FFT Spectrum / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(freq(2)-freq(1)) ' Hz ']);
xlabel('Frequency (Hz)');ylabel(my_ylabel);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 2 : time / frequency analysis : spectrogram demo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[sg,fsg,tsg] = specgram(signal,NFFT,Fs,w,NOVERLAP);
% FFT normalisation and conversion amplitude from linear to dB (peak)
sg_dBpeak = 20*log10(abs(sg))+20*log10(2/length(fsg)); % NB : X=fft(x.*hanning(N))*4/N; % hanning only
% apply A weigthing if needed
if option_w == 1
pondA_dB = pondA_function(fsg);
sg_dBpeak = sg_dBpeak+(pondA_dB*ones(1,size(sg_dBpeak,2)));
my_title = ('Spectrogram (dB (A))');
else
my_title = ('Spectrogram (dB (L))');
end
% saturation of the dB range :
% saturation_dB = 60; % dB range scale (means , the lowest displayed level is XX dB below the max level)
min_disp_dB = round(max(max(sg_dBpeak))) - spectrogram_dB_scale;
sg_dBpeak(sg_dBpeak<min_disp_dB) = min_disp_dB;
% plots spectrogram
figure(2);
imagesc(tsg,fsg,sg_dBpeak);colormap('jet');
axis('xy');colorbar('vert');grid
title([my_title ' / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(fsg(2)-fsg(1)) ' Hz ']);
xlabel('Time (s)');ylabel('Frequency (Hz)');
function pondA_dB = pondA_function(f)
% dB (A) weighting curve
n = ((12200^2*f.^4)./((f.^2+20.6^2).*(f.^2+12200^2).*sqrt(f.^2+107.7^2).*sqrt(f.^2+737.9^2)));
r = ((12200^2*1000.^4)./((1000.^2+20.6^2).*(1000.^2+12200^2).*sqrt(1000.^2+107.7^2).*sqrt(1000.^2+737.9^2))) * ones(size(f));
pondA = n./r;
pondA_dB = 20*log10(pondA(:));
end
% %%%%%%%%%%% other infos %%%%%%%%%%%%%%%%%%%%%%%%
%
%
% %% notch filter section %%%%%%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % notch : H(s) = (s^2 + 1) / (s^2 + s/Q + 1)
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% fc = 50; % notch freq
%
% Q = 100; % the higher the Q factor, the deeper the notch
%
% %%%%%%
% w0 = 2*pi*fc;
%
% alpha = sin(w0)/(2*Q);
%
%
% b0 = 1;
% b1 = -2*cos(w0);
% b2 = 1;
% a0 = 1 + alpha;
% a1 = -2*cos(w0);
% a2 = 1 - alpha;
% %
% num1z=[b0 b1 b2];
% den1z=[a0 a1 a2];
%
% % now let's filter the signal
% signal_filtered = filter(num1z,den1z,signal);
  1 Kommentar
Xiaolong wu
Xiaolong wu am 23 Nov. 2020
I think so as well, my filter just not powerful enough. I am not sure how to design a powerful notch filter with designfilt.

Melden Sie sich an, um zu kommentieren.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by