I designed a discrete Butterworth filter using the DSP package. How can I create a Bode plot of the transfer function?
using DSP
function create_filter(cut_off_freq; order=4, type=:Butter, dt)
if type == :Butter
return Filters.digitalfilter(Filters.Lowpass(cut_off_freq; fs=1/dt), Filters.Butterworth(order))
elseif type == :Cheby1
return Filters.digitalfilter(Filters.Lowpass(cut_off_freq; fs=1/dt), Filters.Chebyshev1(order, 0.01))
end
end
dt = 0.05
cut_off_freq = 2.0 # Hz
butter = create_filter(cut_off_freq; order=4, dt)
using ControlSystemsBase, Plots
bodeplot(tf(butter))
3 Likes
Using only DSP.jl, you could do:
using DSP, Plots; gr()
default(fontfamily="Computer Modern", framestyle=:box, dpi=600)
w = range(1e-9, pi, 1024)
h = freqz(butter, w)
ws = (w/pi)*(0.5/dt)
p1 = plot(ws, 20*log10.(abs.(h)), xlims=(1e-2, 10), ylims=(-60, 6), xscale=:log10, xlabel="", ylabel="Magnitude (db)", label=false, title="2Hz Lowpass 4th-order Butterworth", lw=2, c=:blue, minorgrid=true)
p2 = plot(ws, 180/pi*unwrap(angle.(h)), xlims=(1e-2, 10), ylims=(-360, 6), xscale=:log10, xlabel="Frequency (Hz)",ylabel="Phase (deg)", label=false, lw=2, c=:red, minorgrid=true)
plot(p1, p2, layout=(2,1), size=(800, 800))
which produces:
3 Likes
Thanks! But there is a small mistake in your code,it must be:
tf(butter, dt)
with dt
being the sampling time, otherwise the result is wrong.
I used this script to create this plot:
Thanks! Always good to have less package dependencies.
1 Like
Added minorgrid=true
, which was an important omission for this type of logarithmic scale plots.