Lowpass filter not making any difference
62 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Nick Li
el 5 de Abr. de 2023
Editada: Cris LaPierre
el 9 de Oct. de 2024
I'm new to filtering, trying to use a low-pass filter to filter a sine wave with another high frequency sine wave on top of it. Using highpass(valArray, .03) I can effectively isolate the higher frrequency. But lowpass(valArray, .03) just appears to return the original signal (or something close to it).
It's possible my setup is incomplete. I'm simply using the lowpass() and highpass() commands. But seems odd that the highpass filter works fine while the lowpass filter fails.
lowpass(valArray, .03);

highpass(valArray, .03)

4 comentarios
Cris LaPierre
el 6 de Abr. de 2023
So your data is something like this.
millis = linspace(1,33850,17000);
valArray = 3600 * sin(mod(millis,3600)/3600 * 6.28) + 200 * sin(mod(millis,100)/100 * 6.28);
figure
lowpass(valArray, .03);
figure
highpass(valArray, .03);
Respuesta aceptada
Cris LaPierre
el 6 de Abr. de 2023
Editada: Cris LaPierre
el 6 de Abr. de 2023
The reason your lowpass filter is not working is because your filter settings are not aggressive enough to both pass your low frequency signal and block your high frequency signal (they are very close together for a filter to separate them). It took a little investigation to be able to explain why.
Normalized frequency can make it a bit harder to undestand the cutoff frequencies, so I started by figuring out your approximate sample frequency (~500 Hz).
You can then convert normalized frequency back to Hz by multiplying it by fs/2. You are using a wpass of 0.03.
fs = 500;
wpass = 0.03;
fpass = wpass*fs/2
As you can see, your corner frequency (fpass) is around 7.5 Hz. Next we need to determine the frequencies of your two sine waves. Inspecting the signals confirmed that they are approximately 1/3.6 Hz and 1/0.1 Hz.
LF = 1/3.6 % low frequency wave, Hz
HF = 1/.1 % high frequency wave, Hz

The first thing to notice is that the frequency does not just shut off after your corner frequency is reached. Instead, there is a transition period until you reach the specified StopbandAttenuation (60 dB by default). The steepness of this transition is set by the Steepness parameter (85% by default).
Since you are using all the default settings for lowpass,
, and W is 15% of
:
, and W is 15% of
:fstop = fpass + 0.15*(fs/2 - fpass)
As you can see, your high frequency signal is well within this window. To exclude it, you can lower fpass, but that alone won't do it, as you can only reduce by around 7 Hz. You need to adjust Steepness so that
is below 10 Hz. Playing around with this equation, you can see that, if you keep fpass the same, your Steepness will need to be 99% or higher, and even then, it's not perfect.
is below 10 Hz. Playing around with this equation, you can see that, if you keep fpass the same, your Steepness will need to be 99% or higher, and even then, it's not perfect.fstop = fpass + 0.01*(fs/2 - fpass)
millis = linspace(1,33850,17000);
valArray = 3600 * sin(mod(millis,3600)/3600 * 6.28) + 200 * sin(mod(millis,100)/100 * 6.28);
figure
lowpass(valArray, wpass,"Steepness",0.99);
Fortunately, though, this approach does mean you do not have to modify your highpass function code, as wpass stayed the same.
You can go through the same exercise with high pass filters by using the corresponding info found here.
7 comentarios
Cris LaPierre
el 3 de Oct. de 2024
Editada: Cris LaPierre
el 9 de Oct. de 2024
Trial and error. I knew the approximate number of samples (17000), and from the arduino code could assume millis was milliseconds. Since the user shared the expression for the waveform, I just had to find a value for milliseconds that duplicated the waveform.
So, for example, if the plot contained 10 seconds of data, this is what it would look like:
start = 1; % milliseconds
stop = 10000; % millisecons
millis = linspace(start,stop,17000);
valArray = 3600 * sin(mod(millis,3600)/3600 * 6.28) + 200 * sin(mod(millis,100)/100 * 6.28);
plot(valArray)
xlim([0,17000])
This does not contain the same number of cycles, so I need to increase the stop time. This contains about 2.75 cycles. The original signal contains about 9.35 cycles, so I need to increase by a factor of 9.35/2.75
stop = stop*9.35/2.75
millis = linspace(start,stop,17000);
valArray = 3600 * sin(mod(millis,3600)/3600 * 6.28) + 200 * sin(mod(millis,100)/100 * 6.28);
plot(valArray)
xlim([0,17000])
That's a little too much, but hopeefully you see the process. Once I have the correct stop time, I can figure out the sample frequency by inverting the time step.
dt = (millis(2)-millis(1))/1000 % convert to seconds
fs = 1/dt
Hope that helps.
Jing
el 8 de Oct. de 2024
Thanks so much for this detailed explanation! It really helps me to understand this process. Thanks for your time and your patience!
Más respuestas (0)
Ver también
Categorías
Más información sobre Statistics and Linear Algebra en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




