FILTRO PASSA BAIXOS por SOFTWARE
Existem diversas técnicas, já usei muitas.
Para facilitar o software é interessante sempre optar por uma quantidade de amostragens que seja equivalente a 2^n, a fim de facilitar a divisão, que será feita usando só a instrução “shift-right”.
Uma técnica que eu vinha usando por anos era a do “buffer rotativo”, ou seja, eram alocados 32 bytes na memória, para 16 leituras (2 bytes cada), e um ponteiro que ficava rodando nesse buffer a cada nova leitura, substituindo a leitura mais antiga pela mais nova, então todos os 2×16 bytes eram somados e o total era dividido por 16, a fim de obter a média das ultimas mais recentes 16 leituras.
A técnica que apresentarei aqui hoje, a “MDM”, não é a média de 2^n leituras, mas é a média das médias infinitas, o que apresenta uma estabilidade muito maior, e na prática quase que independe de acumular 4, 8, ou 64 leituras, a média das médias será praticamente a mesma, o que mudará com mais ou menos leituras é a resolução do ultimo bit do valor a mostrar.
A idea é diluir a medida atual num balde de “n” medidas anteriores, de forma a obter a média simples das leituras, mas sempre manter a média de “n” leituras anteriores.
Atenção ao detalhe, estarei mantendo A MÉDIA de “n” leituras anteriores, e não as “n” leituras anteriores.
No caso de um microcontrolador que possui um ADC de 10 bits, precisarei de dois bytes para armazenar o valor lido (VL) e a média das leituras (ML) , e também precisarei de outra variável que caiba a soma de “n” leituras (SL) de valor máximo do ADC, no caso de 10 bits, é 1024.
Portanto, precisarei de duas variável de 16 bits, e uma terceira de também 16 bits, para conter o valor máximo somado de 16 x 1024 = 16384.
Inicialmente carrego SL com a metade do valor máximo de 16 leituras, que é 8191 (0x1FFF). Pode ser qualquer valor, até 1 ou 16383, só não pode ser 0×0000 ou 0×8000, senão dá problemas na rotina.
Em seguida leio o ADC em VL, digamos que foi lido 0x13A. Subtraio ML de SL e somo VL.
Aproximadamente após 100 leituras e rodadas acima, o valor ML será a média simples das leituras do ADC, com grande estabilidade.
Uma centena de leituras parece muito, mas se a fizer a cada 5ms, significa 500ms para estabilizar a leitura. A partir dai, as mudanças no sinal lido serão menores e poucas rodadas estabilizam.
Note que essa técnica funciona melhor quando o ADC roda continuamente, alimentando a rotina das médias. A qualquer instante, para saber o valor da média das leituras, basta ler o valor de ML.
A teoria da rotina é que ao retirar a média das médias do valor de 16x médias, essa soma passa a ser 15x medias, e então soma-se o valor lido do ADC, e divide-se por 16, que seria o mesmo que subtrair 1/16 da média obtida e somar 1/16 do valor lido. O problema é que fazendo dessa maneira, perde-se-ia quatro bits de baixa ordem do valor lido, e na prática seria como se eliminando os 4 bits de baixa ordem, obtendo estabilidade por força com 6 bits do ADC.
Com a técnica acima, obtem-se a mesma estabilidade dos 6 bits da alta ordem nos 10 bits do ADC, o que é muito interessante.
Na tabela abaixo, feita no Excel, temos SL (que inicia com 0x1FFF), VL (um valor randômico entre 251 e 258) e ML (a média das médias). Note que após aproximadamente 80 rodadas, ML já está estabilizando em torno de 256/255.
O gráfico abaixo da “perseguição” de “ML” com base em “VL”, mostra a aproximação sucessiva e a centralização em 254/255.