Exp 2) Filtro de Média Móvel

O objetivo principal é avaliar o desempenho de um filtro de média móvel (variando de 4 à 10 passos) usado para filtrar dados de iluminação capturados usando um sensor de luz (LDR). Este algoritmo deve ser executado dentro de uma ISR à taxa de 1 à 10 Hz. O valor filtrado deve ser usado para realizar um controle de intensidade luminosa de um led.

Hardware previsto

Componentes necessários:

Conexões:

Software

A equação geral de um filtro de média móvel é dado abaixo:

Onde: saída filtrada; amostra atual; instante de amostragem; número de passos do filtro; uma amostra passada do sinal à ser filtrado.

A equação anterior pode ser modificada para:

Onde: .

Note que necessitamos amostras atrasadas do sinal de entrada .

ou generalizando:

Ou você pode rever a teoria em: Filtro de Média Móvel.

Implementação simples

Exemplo 1: Filtro de média móvel simples de 4 passos.

Neste caso, o diagrama de fluxo de sinal deste filtro fica como mostra a figura abaixo:

blocos_filtro_media_movel_4

Código exemplo:

O código anterior deve gerar uma saída como (usando "Serial Plotter" do Arduino):

filtro_media_movel_4

A linha azul representa o sinal medido (de entrada), e a linha vermelha, o sinal filtrado .

Este filtro reage mais ou menos rápido mas pode ser percebeido que neste caso, não é capaz de remover todas as oscilações. Por exemplo:

filtro_media_movel_4_exemplo

Provavelmente aumentando o número de passos, se consiga melhorar a rejeição aos picos.

Exemplo: Seja , um filtro de média móvel de 10 passos. Ou número qualquer de passos ←NUM_SAMPLES.

Este código produz a seguinte saída:

media_movel_10.gif

No gráfico anterior, a linha azul se refere aos valores brutos lidos pelo sensor e a linha vermelha representa estes dados filtrados.

Note que o LDR está tendo sua iluminação bloqueada (propositalmente) em certos instantes de tempo (motivo das perturbações).

Note que como o fitlro é de 10 passos. Porém esta quantidade pode provocar um certo atraso na resposta (no sinal filtrado).

Este filtro pode ser útil para filtrar situações como a mostrada na figura abaixo:

filtro_media_movel_10_exemplo

Apesar do sensor parecer se encontrar "estático" (sem perturbações visuais aparentes), seu sinal oscila ou apresenta certos picos, e neste caso, percebe-se que o filtro é capaz de suprimir estes picos.

Você pode tentar testar este filtro e outros usando um arquivo de dados gerado com capture_serial_data.py (detalhado em: Capturando e Analisando Dados (via porta serial)), e depois eventualmente usar a função filter do MATLAB para avaliar os resultados que poderiam ser obtidos.

Implementação usando "Buffer Circular"

Um buffer circular ou circular é uma estrutura de dados de tamanho fixo comumente usada em aplicativos de software em tempo real para armazenar um número predefinido de valores. A analogia de um anel com um número fixo de posições é bastante útil para capturar a natureza FIFO (First-In-First-Out) de tal estrutura de dados. Quando o buffer estiver cheio, o primeiro elemento que foi gravado (“In”) no buffer é o primeiro a ser substituído (“Out”) pelo próximo elemento recebido.

Os buffers circulares são particularmente úteis em situações em que os dados são continuamente amostrados e os cálculos precisam ser feitos usando um tamanho de amostra predefinido ou é necessária uma visualização contínua.

Neste caso, definimos um "anel" (vetor) do tamanho requerido para o número de amostras e simplesmente controlador um apontador para a posição da próxima amostra. Enquanto o final deste buffer não é atingido, nenhum valor é sobre-escrito, mas depois que o número máximo de amostras é ultrapassado, os novos dados passar a sobre-escrever os dados mais antigos. A tabela a seguir ilustra o funcionamento de um buffer circular para 10 amostras::

Primeiras 4 amostras10a-amostra11a-amostra
abc

Mais referências:

Exemplo 3: Um código mais aprimorado usando "buffer circular":

Código:

Explicação do Código

  1. GPTArray de Amostras: samples[NUM_SAMPLES] armazena as últimas 10 amostras.
  2. Índice Circular: sampleIndex indica a posição atual no array onde a nova amostra será armazenada.
  3. Soma das Amostras: sum é a soma das amostras no array, usada para calcular a média.
  4. Contagem de Amostras: numSamplesCollected mantém o número de amostras coletadas até que atinja 10.

Funcionamento

Essa abordagem garante que a média móvel das últimas 10 amostras é sempre atualizada de forma eficiente a cada nova leitura de amostra.

Atenção: código sugerido pelo ChatGPT.

Outros testes?

Note que você poderia aumentar a taxa de amostragem do sinal do LDR, realizar uma FFT sobre uma amostra deste sinal e descobrir os componentes ruidosos presentes neste sinal e então aplicar um filtro passa-baixas sobre o sinal do LDR. Eventualmente o resultado desta filtragem será igual ou melhor ao filtro de média móvel com a certeza de que, neste caso, você estará filtrando componentes não desejadas no sinal de entrada (ruídos).


🌊 Fernando Passold 📬 ,