Algoritmos DSP com a STM32F4Discovery – Parte III

STM32F4Discovery
Este post faz parte da série Algoritmos DSP com a placa STM32F4Discovery. Leia também os outros posts da série:

Boas caros leitores, nos artigos anteriores apresentamtos a placa STM32F4Discovery e demos inicio a série tomando como primeiro assunto filtragem digital usando algoritmos simples, baseados nos algoritmos de média móvel e média móvel exponencial. Apesar dos filtros apresentados cobrirem uma gama grande de aplicações, eles possuem limitações já citadas nos artigos anteriores. Filtros digitais são um assunto amplo, podendo ganhar uma ordem de complexidade a nível de discussões entre doutores em processamento de sinais. Porém existem casos em que o leitor precisa de filtro digital simples, mas com alguns parâmetros conhecidos e bem definidos, como, por exemplo, quando o desejo é separar um sinal de áudio em várias componentes, para efetuar um processamento de equalização digital, precisa-se de filtros passa-faixas com frequências de corte bem determinadas.  É quando se faz necessário o uso de um filtro IIR ou FIR com coeficientes devidamente calculados para prover tal frequência de corte de atenuação. Relembrando a seguir temos as equações para filtros FIR e IIR:

daum equation 1412154606973
Equação 1 : Filtro FIR
daum equation 1412154822924
Equação 2 : Filtro IIR

Observando as equações 1 e 2, como ja explicado em artigos anteriores, a grande diferença entre filtros FIR e IIR, além da teoria em que filtros IIR podem responder a impulsos de múltiplas fontes (daí seu nome de filtro de resposta infinita), é que no primeiro filtro os valores computados de saída, dependem apenas dos valores corrente e “m – 1” valores anteriores computados, ou seja é um filtro sem recursão. No caso do segundo tipo de filtro, o IIR, além da saída depender da mesma ordem de valores de entrada, também são necessários calcular “m – 2” valores de amostras de saída anteriormente calculadas. Assim temos um elemento recursivo nesse segundo filtro. Suas estruturas trazem suas vantagens e alguns pontos que precisam de melhorias (ou projetos mais sofisticados), mas podemos resumir as vantagens e pontos de melhoria das duas estruturas básicas de filtragem:

Vantagens do filtro FIR:

  • Inerentemente estável, sob qualquer condição (função de transferência não possui pólos);
  • Coeficientes podem ser calculados usando a transformada de Fourier;
  • Fácil implementação.

Desvantagens do filtro FIR:

  • Filtros com resposta agressiva e precisam de muitos coeficientes;
  • Grande esforço computacional, uso de memória pouco eficiente;
  • Para cálculo em ponto fixo, exige um acumulador com uma largura de dados grande.

Vantagens dos filtros IIR:

  • Eficiente no uso de memória;
  • Precisa geralmente de muito menos coeficientes para uma resposta similar a um filtro FIR;
  • Pode ser modelado a partir de filtros analógicos cuja função de transferência é conhecida.

Desvantagens do filtro IIR:

  • Dependendo da estrutura basica adotada, a implementação é mais trabalhosa se comparado a um filtro FIR;
  • É marginalmente estável, ou seja, a sua estabilidade ocorre sob determinadas condições (possui pólos na função de transferência).

No artigo anterior, exploramos dois dos respectivos filtros, o média móvel e o média móvel exponencial, onde nesse ultimo tivemos resultados interessantes além de uma flexibilidade maior de projeto. Os filtros apresentados anteriormente são indicados a um bom número de aplicações onde o interesse maior fica por conta de suprimir ruídos de alta frequência que contaminam a banda do sinal adquirido, em sistemas embarcados irão existir aplicações onde um determinado filtro digital, com parâmetros além da frequência de corte, devem bem definidos, assim os coeficientes “h” ou “a/b” deverão ser calculados para que tal bloco cumpra esses requerimentos.

Eis então que somos confrontados com a dúvida de como calcular esses coeficientes. Para filtros FIR, pode-se utilizar métodos baseados na série de Fourier em conjunto com uma técnica chamada janelamento onde, a partir do sinal amostrado, analisa-se uma área de interesse desse e decompõe-se usando a série de Fourier, de forma que os coeficientes para as frequências indesejadas sejam impostos em nulo. Essa técnica básica é conhecida por janelamento retangular. Além dessa, existem diversas formas de janelamento que podem ser buscados nas referências.

Para filtros IIR, o método é um pouco mais intuitivo e prático, de forma que podemos partir de um modelo matemático discreto, e gerar diretamente a função de transferência, ou como já citado anteriormente, usando  o protótipo de algum modelo analógico e mapeando seus pólos e zeros para uma função de transferência digital, usando transformadas. Dentre aas utilizadas, uma bem conhecida chamada de transformada bilinear ou método de Tustin, essa simpática expressão mostrada na equação 3, e ja usada aqui no Embarcados na série PID digital. Para refrescar:

bilinear
Equação 3 : Transformada bilinear

Como se usa? É bem intuitivo, como o leitor mais detalhista reparou. Basta tomar o prototipo analógico e substituir o operador “s” da função de transferência, pela equivalência contendo operadores “z” e simplificar a expressão ao máximo possível. Nesse ponto ter-se-á uma ótima aproximação (a transformada bilinear é uma aproximação de segunda ordem, mas que pode ser expandida para ordem superiores, vide em [2]) do modelo de circuito analógico. Para quem leu a parte II da série PID digital, viu que mesmo uma função simples de segunda ordem, pode dar um trabalho jogando sinal pra lá, pra cá, além do fator erro humano (esse que vos escreve particularmente adora errar um sinal na primeira vez que resolve alguma conta no papel).

Ferramentas auxiliares para projeto de filtros

Se na sessão anterior ficamos apenas limitados a transformadas e receitas nada práticas para o projeto de um simples filtro digital, daqui em diante iremos usufruir de ferramentas de cálculo que foram desenvolvidas para auxiliar o projetista na hora de prover pelo menos um modelo matemático para projeto de filtros. Podemos citar logo de inicio uma ferramenta de cálculo numérico muito conhecida pelos leitores, principalmente de sua época de graduação. O Matlab da Mathworks é uma das ferramentas de cálculo computacional mais completas disponíveis, possui um sem número de ferramentas para projeto de sistemas, incluindo blocos para DSP podendo prover o modelo em diversas formas (função de transferência, funções complexas, modelos baseados em estados de espaço), além de oferecer em conjunto com o plugin embedded coder a possibilidade de gerar um projeto completo para download e avaliação num microcontrolador. Seriam apenas maravilhas para falar dessa ferramenta, se não fosse tão cara ou se pelo menos existisse uma versão sem custo para para comunidade ou estudantes. Ainda falando de ferramentas proprietárias, temos o LabView provido pela National Instruments. O grande diferencial aqui (além dos vários blocos para projetos de sistemas) é o fato de ser uma ferramenta gráfica simples de se programar, além disso o usuário que tiver um dos sem números de placas de aquisição pode testar os exemplos na hora rodando em tempo real. Em contrapartida essa também é uma ferramenta paga como já citado, e ainda tem o fator que a licença estudantil tem muito pouco a oferecer baseado em blocos para cálculo computacional. Nas andanças desse que vos escreve (mesmo possuindo uma licença do Matlab), deparei-me com um interessante projeto, que é o SciLab, essa ferramenta, apesar de não oferecer tantos blocos como o Matlab e tampouco ser gráfica como um LabView, possui um bom equilibrio com blocos de cálculo computacional, além de sintaxe quase totalmente compatível com seu colega pago, porém tudo isso de graça. Nos exemplos desenvolvidos usando as ferramentas como veremos em seguida, o filtro gerado pelo Scilab, não deve em nada para o gerado pelo Matlab em termos de desempenho.

Está fora do escopo dessa série, um tutorial sobre o uso dessas ferramentas, o propósito é demonstrar sua utilidade na hora de facilitar a vida do projetista, então vamos nos limitar a apenas fornecer os scripts utilizados para simular o projeto de nosso filtro de teste.

A aplicação

Para a aplicação dessa parte da série, iremos projetar um simpático, porém bem definido, filtro IIR do tipo passa-baixas. Optou-se pelo IIR justamente por partir do principio que, se ele for compreendido, uma estrutura desse tipo é análoga de se projetar. Para nosso código exemplo, vamos construir um simples filtro passa baixas digital do tipo butterworth de segunda ordem, onde o mesmo irá dar conta de processar em tempo real um sinal senoidal que será capturado pelo conversor A/D do microcontrolador, e será colocado na saída usando o conversor D/A. Assim, utilizaremos a mesma base de código anterior já desenvolvida. O objetivo também é demonstrar a capacidade de DSP em tempo real do micro colocado na discovery, no qual filtramos amostra a amostra, sem buffer e para o leitor mais atento, sim, a estrutura IIR usada nesse exemplo pode ser usada para construir um PID usando o algoritmo “2p2z” apenas ajustando os coeficientes.

Nosso filtro IIR então:

  • Passa-baixas;
  • Segunda ordem;
  • Frequência de corte 1000Hz ( amostragem a 10000Hz);
  • Ripple na região de stopband de 1dB.

O primeiro passo para isso, é fazer a instalação do Scilab (é multiplataforma) e abrir uma novo documento no scinotes, o usuário nesse momento deverá ter a seguinte tela:

Screen Shot 2014 10 01 at 7.32.15 PM
Figura 1 : Tela do scinotes

Sim, um editor de programação, o Scilab possui uma sintaxe própria de forma similar ao Matlab. Nesse ponto iremos primeiro simular o nosso filtro. Para isso, leitor, coloque o script abaixo no editor, salve e execute:

Sobre o trecho do script não há muito o que dizer, apenas devemos notar o respeito ao teorema de Nyquist ao projetar o filtro, o primeiro passo é selecionar a frequência de amostragem, na variável “fs”. A partir desse valor iremos normalizar a frequência de corte do nosso filtro dentro de um valor situado entre 0 e metade da frequência de amostragem, assim o valor normalizado da frequência de corte será 1000Hz, dividido pela frequência de amostragem 10000Hz, ou seja, 0.1 . Ao executar esse script teremos o plot da resposta em frequência do filtro.

Screen Shot 2014 10 01 at 7.44.35 PM
Figura 2 : Plotagem da resposta em frequência do filtro desejado

Fizemos o script, foi simulado, verificamos a resposta esperada, mas…e quando colocamos isso no processador? Bem, o script tem por primeira função checar se os parametros escolhidos ofereceram o desempenho desejado. O Scilab fornece como ja dito anteriormente diversas formas de saída ao chamar uma função para projeto de filtros, no nosso caso o tipo de saída mais interessante está em receber a função de transferência do filtro. Para tal selecione a linha 18 do script e volte ao console do scilab, cole essa linha e substitua “fcut” e “fs” pelos seus valores numéricos, e tecle enter, o console irá prover os coeficientes da função de transferência, conforme a imagem abaixo:

Screen Shot 2014 10 01 at 8.02.42 PM
Figura 3 : Console do Scilab

Agora temos a função de transferência, mas ainda não podemos colocar isso em um processador. Até agora usamos poucos cálculos, num processo bem intuitivo, mas não vai ter jeito, vamos precisar fazer umas continhas para tomar a transformada inversa z, obtendo assim a equação de diferenças. Vamos ilustrar o processo com algumas passagens simples. 

IIR Tf
Equação 4 : Função de transferência gerada pelo Scilab

Ao novo leitor da série, gosto sempre de lembrar para não se assustar com a expressão a primeira vista, e que o termo “z” da função de transferência vai assustar ainda menos se o tratarmos como operador de deslocamento de amostras num sistema discreto e não como uma incógnita (afinal em grande parte dos casos não se resolver uma função de transferência desse tipo para “z”). Então, sabendo desses dois “conselhos”, vamos começar a trabalhar nossa função de transferência. Em primeiro lugar em um sistema digital é muito mais fácil trabalhar com amostras memorizadas (passadas) do que prever valores futuros das próximas amostras, sejam de entrada ou saída. Logo se o operador “z” representa o deslocamento de amosras no tempo de acordo com o sinal do expoente, então podemos modificar a equação 4 para ela trabalhar com amostras passadas ou com a corrente, logo temos:

IIR Tf1
Equação 5 : Função de transferência modificada

E agora, vamos colocar em função do sinal de saída:

IIR Tf2
Equação 6 : Filtro em função do sinal de saída

A última passagem feita, sem denominadores, está ideal para tomar a transformada inversa Z. Assim vamos obter a equação de diferenças final. Uma amostra de saída é calculada como:

IIR_tf_final
Equação 7 : Equação de diferenças IIR final

Ufa! Nada muito difícil, porém um pouquinho trabalhoso de fazer no editor de equações. Mas num rascunho ou mesmo de forma intuitiva a medida que se pega prática de fazer. Sim, a última linha é tudo que precisamos para implementar o filtro digital que tem a resposta simulada na figura 2, e sim caro leitor, não é coicidência, mas a equação 7 é exatamente a mesma equação 2 so que para um filtro IIR genérico. Repare que poderíamos reordenar os termos e escrever em forma de somatórios para provar isso, mas vou deixar essa tarefa por conta do leitor mais desconfiado. Agora pergunto: essa expressão pode ser embarcada no código de um microcontrolador? Sim! A resposta é tão óbvia quanto a pergunta.

No projeto hospedado no github o usuário terá acesso ao código fonte feito especialmente para implementação de filtros. Em termos de implementação de filtros IIR, existem alguns métodos já consolidados, como os Direct Form I e II, ilustrados nas figuras 4.

iir
Figura 4 : IIR direct form I

No direct form I, o que temos é basicamente a operação da equação 2, onde a amostra de entrada denotada por “x” é multiplicada pelo seu coeficiente, bem como as amostras de entrada atrasadas por 1 e 2 periodos de amostragem respectivamente. O mesmo é feito com as amostras de saída atrasadas. Elas são multiplicadas pelos seus coeficientes e em seguida todos esses resultados são combinados em uma única soma algébrica. Por fim, a amostra de saída desejada é escalada e aparece na saída (denotada por “y”) e o ciclo se completa, atualizado todas as amostras envolvidas no processo por 1 ciclo, onde a amostra mais antiga em todos eles é descartada.

400px Biquad filter DF II.svg
Figura 5 : IIR firect form II

No algoritmo direct form II (também chamado de biquad) as linhas de atraso e os coeficientes foram ordenados. A grande vantagem desse tipo de implementação é a economia de memória, uma vez que precisamos de apenas uma linha de atraso para preservar as amostras anteriores, ante a duas da forma anterior. Nessa implementação a amostra de entrada é imediatamente somada com o resultado das amostras anteriores multiplicados por um do set de coeficientes do filtro. Em seguida, esse estagio intermediário é somado com o a mesma linha de atraso, só que agora multiplicada pelo segundo set de coeficientes, sendo escalado e colocado na saída. Vale reparar que o que é colocado na linha de atraso não são amostras anteriores de entrada ou saída mas sim os estados dos estágios intermediários.

Em nossa aplicação vamos optar pela implementação usando o direct form I. Se por um lado temos um uso maior de memória, por outro lado ganhamos na simplicidade de implementação e do fato do filtro possuir um ganho unitário, caracteristica não existente nos biquads, em que o sinal de saída recebe um segundo ganho vindo da própria implementação do filtro. Esse efeito, entretanto, pode ser bem desejável em implementações ponto flutuante o que não é nosso caso. Na pasta filtros, temos os arquivos embarcados IIR.c e .h contendo as definições e implementação do filtro. O código foi comentado afim de possibilitar expansões por parte do usuário. As linhas de atraso, diferentes do filtros de média móvel, foram construídas em cima de buffers circulares, ante ao método de atualização de histórico, tornando o filtro bem mais eficiente em termos de velocidade. O comprimento desses buffers deve ser preferencialmente potência de 2, pois apesar do núcleo ARM Cortex M4/M4F possuir um set básico de instruções DSP, ele peca por não possuir uma unidade geradora de endereços AGU, assim um buffer circular nessa arquitetura se mostra pouco eficiente de modo que, em alguns casos, ele fique ainda mais lento que o uso de atualização de histórico para operar a linha de atraso, com um uma potência de 2 isso é facilmente contornado, pois para apontar para fazer o incremento circular basta apenas adicionar a unidade ao ponto de leitura ou escrita seguida de uma operação e para mascarar todos os bits de ordem superior ao comprimento do buffer. Como apenas precisamos preservar três estados em nossa linha de atraso, optamos por um buffer de 4 posições. Os resultados foram bons! E por falar neles, vejam uma amostra do que obtive em bancada com a Discovery em operação:

Screen Shot 2014 10 03 at 12.14.03 AM
Figura 5 : Sinal de 100Hz

Temos um sinal de 100Hz na entrada analógica da placa Discovery. Infelizmente o sinal de saída acaba contaminado pelo fato de estar sem o filtro anti-alias na entrada analógica. Observem a análise no domínio da frequência (a FFT abaixo) a atenuação é exatamente de 0 dB ou seja, estamos com ganho unitário.

Screen Shot 2014 10 03 at 12.04.41 AM
Figura 6 : Sinal acima de 1000Hz

Aqui temos um sinal bem na frequência de corte de 1000Hz do filtro. Vejam que quase não temos sinal, e ainda na FFT tem-se uma atenuação inferior a -30dB, tal desvio do valor desejado pode ser explicado devida a quantização em ponto fixo de 16bits realizada com filtro, uma sugestão que deixo ao caro leitor que utilize a FPU do Cortex M4 para efetuar uma versão em ponto flutuante.

Conclusão

Mais uma vez espero que o certo misticismo que ronda a ciência de processamento digital de sinais, esteja sendo desfeita a você caro leitor. Vimos um pouco sobre como modelar um filtro IIR usando uma ferramenta inclusive open source, experiência que  pode ser levado para outros tipos de filtros. Ainda o Scilab por exemplo, oferece as mesmas ferramentas para fornecer a função de transferência de filtros passa-altas, passa-faixas e filtros passa-todas para deslocamento de fase. E para a próxima parte da série vamos entrar em novo assunto,  a transformada discreta de Fourier. Então é isso, até a próxima.

Referências

OPPENHEIM, Alan V. – Signals & Systems – 1983

OPPENHEIM, Alan V. – Digital Signal Processing – 1999

SMITH, Steven W. – The Scientist & Engineer’s Guide to Digital Signal Processing – 1999

Materiais de apoio

Repositório no GitHub com código pronto para gravar na StmDiscovery 

Outros artigos da série

<< Algoritmos DSP com a placa STM32F4Discovery – Parte II
Website | Veja + conteúdo

Engenheiro de sistemas embarcados apaixonado pelo que faz, tendo experiencia, nos últimos 15 anos, em áreas de alta tecnologia como: Defesa, Automotiva, Agricultura, Robótica e Semicondutores. Possui paixão por compartilhar e desmistificar tópicos de engenharia tidos como complexos ou misteriosos demais. Atualmente trabalha na Espressif Systems levando seus chips para projetos Open-Source. No tempo livre constroi e programa seus próprios robôs e controladores de motor.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Comentários:
Notificações
Notificar
guest
3 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Alexandre
Alexandre
22/11/2017 00:04

Pq parou?? Parou pq?? Eu aqui como Barrichello lendo artigo de 2014 em 2017 e querendo saber porque não seguiu para a FFT :/ Me meti à besta ao propor um TCC de graduação envolvendo FFT em sinal de áudio rodando em microcontrolador e microfone digital (protocolo i2s) e claro… Acabei completamente perdido. É a vida… Sempre me propondo desafios maiores que minha corrente capacidade de resolve-los. Sei nada de bibliotecas. Já ví que existem algumas i2s no github mas não sei se são de comer ou passar no cabelo. Pensei que conseguiria usar um Arduino mas só alguns tem… Leia mais »

Haroldo Amaral
Haroldo Amaral
14/10/2014 02:01

Ótimo artigo Felipe Neves. Como tive processamento de sinais bem simples na faculdade, esta sendo bastante interessante. O trecho explicando como converter a função de transferência nos coeficientes ficou muito didática. Parabéns.

Você indicaria algum material ou site falando sobre o toolbox do Scilab para filtros digitais e a obtenção dos coeficientes?

Obrigado, abraço!

Felipe Neves
Felipe Neves
Reply to  Haroldo Amaral
14/10/2014 17:25

Haroldo, obrigado pela leitura.

Que bom que ficou didático.

Respondendo a sua pergunta, o Scilab possui muita documentação interessante no próprio site do projeto, pro DSP toolbox, eu segui a didática de alguns artigos, incluindo esse do link:
http://www.academia.edu/4761013/SCILAB_Tutorial_for_DSP

Foi o que mais gostei pois cobriu bastante coisa sobre o scilab e XCos (o equivalente ao simulink).

Se tiver mais alguma coisa em que eu possa ajudar, fique a vontade.

Abs.

Felipe

Talvez você goste:

Séries



Outros da Série

Menu