quarta-feira, 29 de abril de 2015

Projetando filtros FIR - versão 2

Janela principal - entrada de parâmetros. Janela criada com o uso do "guimaker".
Janela de ajuda do programa.
Em uma postagem anterior (ver aqui) escrevermos um programa Scilab para o projeto de filtros FIR onde a ordem do filtro desejado era um parâmetro de entrada. Entretanto, em geral, o projetista tem um dado gabarito a ser "obedecido" e a ordem do filtro fica em função desse gabarito (e de outros parâmetros).

O código abaixo utiliza o pacote guimaker (create a graphical user interface with a minimum of programming). Esse pacote pode ser instalado no Scilab usando o gerenciador de módulos ATOMS. Com esse pacote fica muito fácil criar a interface gráfica do programa. Exemplo de filtro calculado:


Código Scilab (quase sem comentários):

close; close;
clc;

msg = ['Este programa calcula filtros FIR para um dado gabarito.'; 
       'Os parâmetros do gabarito são: ganho na banda de passagem';
       '(g1), ganho na banda de rejeição (g2), frequências f1, f2,';
       'f3, f4. Para um filtro PB ou PA as frequências f1 e f2 são';
       'usadas. Para um filtro PF e RF todas as frequências são usadas.';
       'As janelas possíveis são retangular, triangular, Hamming e Hanning.';
       ' ';
       'Obs: a ordem mínima para o filtro projetado é 10; o filtro FIR';
       'é calculado numericamente usando a função wfir() do Scilab.'
       ' ';
       'Prof. Francisco J. A. de Aquino - IFCE (29/04/2015).';
       ' '];
       
msgboxtitle = 'Ajuda/informação sobre o programa';
msgboxicon = 'info';
buttons = 'Ok';
modo = 'modal';
//messagebox(msg, msgboxtitle, msgboxicon, buttons, modo);

// Exemplo "básico" de http://wiki.scilab.org/howto/guicontrol
page=list();
page($+1)=list(list([1 9],'frame','Dados para o filtro FIR:'));
page($+1)=list(list('text','f1 (f1 > 0) .......:'),list('edit','0.12'));
page($+1)=list(list('text','f2 (f2 > f1) ......:'),list('edit','0.20'));
page($+1)=list(list('text','f3 (f3 > f2) ......:'),list('edit','0.30'));
page($+1)=list(list('text','f4 (f4 < 0.5) .....:'),list('edit','0.40'));
page($+1)=list(list('text','g1 ................:'),list('edit','0.707'));
page($+1)=list(list('text','g2 ................:'),list('edit','0.025'));
page($+1)=list(list('text','Tipo de filtro ....:'),list('listbox','PB | PA | PF | RF'));
page($+1)=list(list('text','Tipo de janela ....:'),list('listbox','retang. | triang. | Hamming | Hanning'));
page($+1)=list(list(2),list('pushbutton','Calcular','callback','OK=%t'),list(1),...
 list('pushbutton','Ajuda','callback','messagebox(msg, msgboxtitle, msgboxicon, buttons, modo);'));
[ff1,ff2,ff3,ff4,gg1,gg2,tipf,tipj]=guimaker(page,list('Parâmetros de projeto:'));

source_code = guimaker(page,list('objfigure1',220),[],1);

tjan = 're';
if tipj == 2 then tjan = 'tr'; end;
if tipj == 3 then tjan = 'hm'; end;
if tipj == 4 then tjan = 'hn'; end;

if tipf == 1 then
fc1 = ff1;
fc2 = ff2;
[h,hm,fr]=wfir("lp",9,[fc1 0],"re",[0 0]);
w1 = [0 fc1 fc1]; g1 = [gg1 gg1 0];
w2 = [0 fc2 fc2 0.5]; g2 = [1 1 gg2 gg2];
nn = 10;
[aa,pos] = min(abs(fr-fc1));
[aa,pos2] = min(abs(fr-fc2));
fora = 1;
dfc = fc1/50;
while fora > 0 
     if hm(pos)<g1(1) then fc1 = fc1 + dfc; end;
     if max(hm(pos2:$))>g2(3) then nn = nn + 1; end;
     [h,hm,fr]=wfir("lp",nn,[fc1 0],tjan,[0 0]);
     if (hm(pos)>g1(1))&(max(hm(pos2:$))<g2(3)) then fora = 0; end
     if nn>100 then fora = 0; end
end
disp(nn);
end;
/////////////////////////

if tipf == 2 then

fc2 = ff2;
fc1 = ff3;
[h,hm,fr]=wfir("hp",13,[fc1 0],"re",[0 0]);
w1 = [fc1 fc1 0.5]; g1 = [0 gg1 gg1];
w2 = [0 fc2 fc2 0.5]; g2 = [gg2 gg2 1 1];
fora = 1;
nn = 13;
[aa,pos2] = min(abs(fr-fc2));
[aa,pos] = min(abs(fr-fc1));
dfc = fc1/50; kk=0;
while fora > 0 
     if hm(pos)<g1(2) then fc1 = fc1 - dfc; end;
     if max(hm(1:pos2))>g2(1) then nn = nn + 2; end;
     [h,hm,fr]=wfir("hp",nn,[fc1 0],tjan,[0 0]);
     if (hm(pos)>g1(2))&(max(hm(1:pos2))<g2(1)) then fora = 0; end
     if nn>100 then fora = 0; end
     kk = kk + 1;
     if kk > 50 then fora = 0; end
end
[h,hm,fr]=wfir("hp",nn,[fc1 0],tjan,[0 0]);
end;

//////
if tipf == 3 then
fc1 = ff2; fc2 = ff3;
fc3 = ff1; fc4 = ff4;
[h,hm,fr]=wfir("bp",15,[fc1 fc2],tjan,[0 0]);
w1 = [fc1 fc1 fc2 fc2]; g1 = [0 gg1 gg1 0];
w2 = [0 fc3 fc3 fc4 fc4 0.5]; g2 = [gg2 gg2 1 1 gg2 gg2];
[aa,p1] = min(abs(fr-fc1));
[aa,p2] = min(abs(fr-fc2));
[aa,p3] = min(abs(fr-fc3));
[aa,p4] = min(abs(fr-fc4));

nn = 11;

fora = 1; np1 = 0;
dfc = fc1/100; kk=0;
while fora > 0 
     if  np1<10 then
     if hm(p1)<g1(2) then fc1 = fc1 - dfc; np1 = np1 + 1; end;
     if hm(p2)<g1(3) then fc2 = fc2 + dfc; end;
     end;
     if (max(hm(1:p3))>g2(1))|(max(hm(p4:$))>g2($)) then nn = nn + 1; end;
     [h,hm,fr]=wfir("bp",nn,[fc1 fc2],tjan,[0 0]);
     if (hm(p1)<g1(2))&(max(hm(1:p3))<g2(1)) then fora = 0; end
     if nn>100 then fora = 0; end
     kk = kk + 1;
     if kk > 50 then fora = 0; end
end
[h,hm,fr]=wfir("bp",nn,[fc1 fc2],tjan,[0 0]);
end;

/////////////////
if tipf == 4 then
fc1 = ff2; fc2 = ff3;
fc3 = ff1; fc4 = ff4;

//fc1 = 0.20; fc2 = 0.35;
//fc3 = 0.15; fc4 = 0.40;
[h,hm,fr]=wfir("sb",15,[fc1 fc2],tjan,[0 0]);
w1 = [0 fc3 fc3 fc4 fc4 0.5]; g1 = [gg1 gg1 0 0 gg1 gg1];
w2 = [0 fc1 fc1 fc2 fc2 0.5]; g2 = [1 1 gg2 gg2 1 1];
[aa,p1] = min(abs(fr-fc1));
[aa,p2] = min(abs(fr-fc2));
[aa,p3] = min(abs(fr-fc3));
[aa,p4] = min(abs(fr-fc4));

nn = 11;
fora = 1; np1 = 0;
dfc = fc1/75; kk=0;
while fora > 0 
     if  np1<20 then
     if hm(p3)>g2(3) then fc1 = fc1 - dfc; np1 = np1 + 1; end;
     if hm(p4)>g2(4) then fc2 = fc2 + dfc; end;
     if hm(p3)<g1(2) then fc1 = fc1 + dfc; end;
     if hm(p4)<g1($) then fc2 = fc2 - dfc; end;
     end;
     if (max(hm(p1:p2))>g2(3)) then nn = nn + 2; end;
     [h,hm,fr]=wfir("sb",nn,[fc1 fc2],tjan,[0 0]);
     if (hm(p3)<g2(3))&(max(hm(p1:p2))<g2(3)) then fora = 0; end
     if nn>100 then fora = 0; end
     kk = kk + 1;
     if kk > 60 then fora = 0; end
end
[h,hm,fr]=wfir("sb",nn,[fc1 fc2],tjan,[0 0]);
end;

figure;
subplot(1,2,1) ;plot(fr,hm,w1,g1,w2,g2); 
title(['Ordem do filtro: ', string(nn)]); xgrid;
subplot(1,2,2); bar(h,0.1); title('Resposta ao impulso');
 

Um comentário: