Muitas vezes,
para eliminar ou diminuir algum ruído indesejável em um sinal, é necessário
filtrá-lo. Isso é comum quando se trabalha com sinais provenientes do ADC. Essa
filtragem é, então, feita através da programação. O problema é que a teoria
sobre filtros digitais é complexa e o programador a evita sempre que possível.
Todavia, pode-se utilizar um filtro bem simples, chamado de média móvel, que
pode resolver o problema do ruído.
O filtro de média móvel é obtido
calculando-se a média de um conjunto de valores, sempre se adicionando um novo
valor ao conjunto e se descartando o mais velho. Não é apenas uma média de um
conjunto isolado de valores. O filtro de média móvel é representado por:
onde
n é o tempo
atual (é o índice dos vetores utilizados), N +1 é o número
de amostras utilizadas para a filtragem, y[n] é o sinal filtrado e x[n-k]
representa o conjunto dos valores a serem somados. A equação acima pode ser
representada pelo diagrama da figura 1, com os valores de b0,b1...bN iguais a
1/(N+1).
Fig.
1 - Diagrama de um filtro digital não recursivo.
O diagrama da fig. 1 representa um filtro
chamado não recursivo, pois o sinal de saída y[n] depende somente do sinal de
entrada x[n]. Caso o sinal de saída dependesse de valores passados da saída, o
filtro seria chamada recursivo. No projeto de um filtro digital, determinam-se
os coeficientes de multiplicação para as amostras, no caso b0,
b1, ... bN para o diagrama citado. Esses coeficientes podem ser
determinados com o uso de alguma ferramenta computacional como o MATLAB®
ou MATCAD®, e o programador apenas necessita realizar as somas e
multiplicações nas amostras certas. A qualidade do filtro e o tipo de filtro
(passa baixa, passa alta, passa faixa) vai depender do número de coeficientes
utilizados (quantidade de amostras) e dos seus valores.
Ao utilizar coeficientes fixos, o filtro
de média móvel produz um filtro passa baixa suave, reduzindo os sinais de alta
frequência. Caso se deseje outro tipo de filtragem, será necessário a
multiplicação com valores fracionários, o que exigirá o uso de ponto flutuante
no programa. Isso pode ser um problema para microcontroladores de 8 bits pelo
consumo maior de memória e da limitada capacidade de processamento da CPU.
Na fig. 2, é apresentada a resposta em
frequência de um filtro de média móvel para 16 amostras. O eixo horizontal é a
frequência em Hertz, o número 1 representa a frequência de amostragem do sinal
dividida por 2. Desta forma, supondo uma frequência de amostragem 20 kHz,
cada linha vertical do gráfico corresponderia a 1 kHz.
Fig.
2 – Resposta em frequência de um filtro de média móvel de 16 amostras.
A resposta apresentada na fig. 2 mostra
que o desempenho de um filtro de média móvel é razoável, estando a atenuação
dos sinais indesejados na faixa de
aproximadamente -20 dB (90 %).
A seguir, é apresentado um exemplo para a
programação de um filtro de média móvel de 16 amostras para os valores
convertidos pelo ADC do ATmega (deve-se observar o tamanho das variáveis
declaradas para não ocorrer estouro na contagem).
Obs.: havia um erro no algoritmo abaixo, faltava inicializar com zero o valor media antes do somatório das amostras, o que aumentava um pouco a média.
//---------------------------------------------------------------------
// Filtro de média móvel com 16 amostras para o sinal do ADC
//---------------------------------------------------------------------
unsigned int filtro[16], media,
unsigned char k=0;
. . .
ISR(ADC_vect)
{
unsigned char j;
filtro[k] = ADC; //valor do ADC entra no filtro, na amostra
mais antiga
k++; if(k==16) k=0;
media = 0;
for(j=0; j<16; j++)
media += filtro[j]; //somatório das amostras
media /=16; //média dos valores
}
//----------------------------------------------------------------------
Obs.: Este material faz parte do capítulo 19 do livro AVR e Arduino:
Técnicas de Projeto. O
programa é diferente no livro, aconselho comparação.