You are on page 1of 10

Exemplo de projeto de filtro passa-banda

In [1]: using Plots, DSP, LinearAlgebra, LaTeXStrings


gr();

Especificações: fa = 4MHz
fp1 = 900kHz

fp2 = 1100kHz

fr1 = 800kHz
fr2 = 1200kHz
δp = 0.01

δr = 10−50/20 = 0.001√10 = 0.00316

In [2]: ωp1 = 900*2π/4000


ωp2 = 1100*2π/4000
ωr1 = 800*2π/4000
ωr2 = 1200*2π/4000
ωc1 = (ωp1+ωr1)/2
ωc2 = (ωp2+ωr2)/2
Δω1 = (ωp1-ωr1)
Δω2 = (ωr2-ωp2)
Δω = min(Δω1, Δω2)
δp = 0.01
δr = 10^(-50/20)
hpbd = n -> (ωc2/π) * sinc((ωc2/π)*n) - (ωc1/π) * sinc((ωc1/π)*n)

Out[2]: #1 (generic function with 1 method)

Filtro com método dos mínimos quadrados: janela


retangular
In [3]: Nr = 101 # Escolhido apenas como exemplo
Lr = (Nr-1)/2
nr = 0:Nr-1
hdr = hpbd.(nr .- Lr)
plot(nr, hdr, line = :stem, marker = (:circle, 3), xlabel = L"n",
label = L"h_{d, ret}[n]")
Out[3]:

In [4]: ω = range(0, π, length = 1500)


hrf = PolynomialRatio(hdr, [1])
Hr = freqresp(hrf, ω)
plot(ω/π, 20log10.(abs.(Hr)), label = L"|H_r(e^{j\omega})|",
xlabel = L"\omega/\pi")
plot!([ωp1,ωp2]/π, 20log10(1-δp)*[1,1], lw = 2, label = "")
plot!([ωp1,ωp2]/π, 20log10(1+δp)*[1,1], lw = 2, label = "")
plot!([ωr2/π,1.0], 20log10(δr)*[1,1], lw = 2, label = "")
plot!([0, ωr1/π], 20log10(δr)*[1,1], lw = 2, label = "")

Out[4]:
In [5]: plot(ω/π, unwrap(angle.(Hr)), label = "fase", xlabel = L"\omega/\pi")

Out[5]:

Projeto com janelas cossenoidais


In [6]: AtJanelas = Dict(:Retangular=>10^(-20.9/20),
:Hann=>10^(-43.9/20),
:Hamming=>10^(-54.5/20),
:Blackman=>10^(-75.3/20),
:Flattop=>10^(-89/20))

Out[6]: Dict{Symbol, Float64} with 5 entries:


:Retangular => 0.0901571
:Blackman => 0.000171791
:Flattop => 3.54813e-5
:Hann => 0.00638263
:Hamming => 0.00188365

In [7]: CoefJanelas = Dict(:Retangular=>[1.0],


:Hann=>[0.5, 0.5],
:Hamming=>[0.54, 0.46],
:Blackman=>[0.42, 0.5, 0.08],
:Flattop=>[0.24726, 0.46071, 0.25078, 0.04125])

Out[7]: Dict{Symbol, Vector{Float64}} with 5 entries:


:Retangular => [1.0]
:Blackman => [0.42, 0.5, 0.08]
:Flattop => [0.24726, 0.46071, 0.25078, 0.04125]
:Hann => [0.5, 0.5]
:Hamming => [0.54, 0.46]
O dicionário abaixo contém funções que calculam o número de pontos mínimo para
uma dada largura da faixa de transição, para cada janela.

In [8]: TranJanelas = Dict(:Retangular=>Δω->4π/Δω,


:Hann=>Δω->8π/Δω,
:Hamming=>Δω->8π/Δω,
:Blackman=>Δω->12π/Δω,
:Flattop=>Δω->16π/Δω)

Out[8]: Dict{Symbol, Function} with 5 entries:


:Retangular => #3
:Blackman => #6
:Flattop => #7
:Hann => #4
:Hamming => #5

In [9]: function flattop(N)


n = 0:N-1
jan = fill(CoefJanelas[:Flattop][1], N)
for k = 2:4
jan .+= CoefJanelas[:Flattop][k] * cos.(2π*(k-1)*(n .- L)/(N-1))
end
return jan
end
CriaJanela = Dict(:Retangular => ones,
:Hann => hanning,
:Hamming => hamming,
:Blackman => blackman,
:Flattop => flattop)

Out[9]: Dict{Symbol, Function} with 5 entries:


:Retangular => ones
:Blackman => blackman
:Flattop => flattop
:Hann => hanning
:Hamming => hamming

Escolhe a melhor janela


O código a seguir escolhe a janela com a maior oscilação menor do que δ.

In [10]: δ = min(δp, δr)


atmin = 0
Janela = ""
for (jan, at) in AtJanelas
if δ ≥ at > atmin
atmin = at
Janela = jan
end
end
(Janela, atmin)

Out[10]: (:Hamming, 0.0018836490894898002)


Determina o número de pontos
In [11]: Nj = ceil(Int, TranJanelas[Janela](Δω)) # - 3

Out[11]: 160

In [12]: # Chama a função adequada para cada janela.


jan = CriaJanela[Janela](Nj) #eval(Meta.parse(lowercase(string(Janela))* "($N)"

nj = 0:Nj-1
plot(nj, jan, line = :stem, marker = (:circle, 3), xlabel = "n", label =

Out[12]:

In [13]: Lj = (Nj-1)/2
hdj = hpbd.(nj .- Lj)
hj = hdj .* jan
plot(nj, hj, line = :stem, marker = (:circle, 3), xlabel = L"n",
label = L"h_{\text{jan}}[n]")
Out[13]:

In [14]: hjf = PolynomialRatio(hj, [1])


Hj = freqresp(hjf, ω)
plot(ω/π, 20log10.(abs.(Hj)), label = L"|H_{\text{jan}}(e^{j\omega})|",
xlabel = L"\omega/\pi")
plot!([ωp1,ωp2]/π, 20log10(1-δp)*[1,1], lw = 2, label = "")
plot!([ωp1,ωp2]/π, 20log10(1+δp)*[1,1], lw = 2, label = "")
plot!([ωr2/π,1.0], 20log10(δr)*[1,1], lw = 2, label = "")
plot!([0, ωr1/π], 20log10(δr)*[1,1], lw = 2, label = "")
ylims!(-120, 2)

Out[14]:
Projeto com janela de Kaiser
In [15]: """
filtrokaiser(ωp, ωr, δp, δr)
Projeta filtro FIR com janela de Kaiser.
Se `ωp > ωr`, o filtro projetado é passa-altas tipo I.
"""
function kaiserlength(Δω, δp, δr)
A = -20log10(min(δp, δr))
N = ceil(Int, (A-8)/(2.285*Δω) +1)
if A < 21
β = 0
elseif A <= 50
β = 0.5842(A-21)^0.4 + 0.07886(A-21)
else
β = 0.1102(A-8.7)
end
return β,N
end

Out[15]: kaiserlength

In [16]: (β, Nk) = kaiserlength(Δω, δp, δr)

Out[16]: (4.533514120981248, 119)

In [17]: nk = 0:Nk-1
wk = kaiser(Nk, β/π)
plot(nk, wk, line = :stem, marker = (:circle, 3), xlabel = "n", label = "Janela

Out[17]:
In [18]: Lk = (Nk - 1) / 2
hk = hpbd.(nk .- Lk) .* wk
plot(nk, hk, line = :stem, marker = (:circle, 3), xlabel = "n", label = "hk[n]"

Out[18]:

In [19]: hkf = PolynomialRatio(hk, [1])


Hk = freqresp(hkf, ω)
plot(ω/π, 20log10.(abs.(Hk)), label = "|Hk(e^{jω})|",
xlabel = "ω/π")
plot!([ωp1,ωp2]/π, 20log10(1-δp)*[1,1], lw = 2, label = "")
plot!([ωp1,ωp2]/π, 20log10(1+δp)*[1,1], lw = 2, label = "")
plot!([ωr2/π,1.0], 20log10(δr)*[1,1], lw = 2, label = "")
plot!([0, ωr1/π], 20log10(δr)*[1,1], lw = 2, label = "")
ylims!(-120, 10)
Out[19]:

Projeto min-max
In [20]: Nmm = ceil(Int, (-10log10(δp*δr)-13) / (2.324*Δω)) + 13 # Ajuste para atender à

Out[20]: 101

In [21]: hmm = remez(Nmm-1, [(0, ωr1/π) => (0, δp/δr), (ωp1/π, ωp2/π) => (1, 1),
(ωr2/π, 1) => (0, δp/δr)]; Hz = 2)
hpbmmf = PolynomialRatio(hmm, [1])
Hpbmm = freqresp(hpbmmf, ω)

#plot(ω/π, amp2db.(abs.(Hpbk)), label = "Kaiser", xlabel = L"\omega/\pi",


# lw = 2, color = :blue, xlims = (0, 1/2))
plot(ω/π, amp2db.(abs.(Hpbmm)), label = "min-max",
xlabel = "ω/π", ylims = (-100, 10),
lw = 2, color = :black)
plot!([ωp1, ωp2]/π, amp2db(1-δp)*[1,1], color = :magenta, label = "")
plot!([ωp1, ωp2]/π, amp2db(1+δp)*[1,1], color = :magenta, label = "")
plot!([ωr2/π, 1], amp2db(δr)*[1,1], color = :magenta, label = "")#,
#xlims = (0, 0.3), ylims = (-0.5, 0.5))
plot!([0, ωr1/π], amp2db(δr)*[1,1], color = :magenta, label = "")
plot!(ω/π, amp2db.(abs.(Hpbmm)), label = "",
lw = 2, color = :black, xlims = (ωp1/π, ωp2/π), ylims = (-0.5, 0.5),
inset=bbox(0.15,0.05,0.25,0.25),subplot=2)
plot!([ωp1/π, ωp2/π], amp2db(1-δp)*[1,1], color = :magenta,
label = "", subplot = 2)
plot!([ωp1/π, ωp2/π], amp2db(1+δp)*[1,1], color = :magenta,
label = "", subplot = 2,
title = "Banda passante")
Out[21]:

In [ ]:

In [ ]:

You might also like