
Passo 1 de 8
Entenda o estado e a correção recursiva
Reconheça o estado que o filtro preserva e a correção que transforma esse estado a cada nova amostra.
Trilha de aprendizado · Nível 13 · Tutorial 3
Implementar um filtro recursivo de primeira ordem e escolher seu coeficiente a partir do período de atualização e da rapidez de resposta desejada.
Entenda o estado e a correção recursiva
Reconheça o estado que o filtro preserva e a correção que transforma esse estado a cada nova amostra. 2 min
Rastreie a saída e interprete α
Calcule atualizações sucessivas e relacione o coeficiente α ao compromisso entre rapidez e suavização. 2 min
Calcule α pela constante de tempo
Conecte o coeficiente α ao período de atualização e à constante de tempo desejada para configurar a resposta temporal do filtro. 3 min
Implemente e inicialize o filtro
Implemente uma função de filtro que conserva seu estado entre chamadas e começa pela primeira medição válida. 3 min
Preserve as pequenas correções
Evite que o filtro pare antes de alcançar a entrada por causa de conversões inteiras. 2 min
Trate amostras inválidas e interrupções
2 min
Compare com a média móvel
Compare o filtro recursivo de primeira ordem e a média móvel sob as mesmas condições de entrada, distinguindo memória, flutuação residual e resposta a mudanças. 3 min
Configure e valide um caso completo
Conclua a configuração, a implementação e a validação de um filtro recursivo de primeira ordem em um caso sintético completo. 3 min

Passo 1 de 8
Reconheça o estado que o filtro preserva e a correção que transforma esse estado a cada nova amostra.
Um filtro recursivo calcula a nova saída usando a entrada atual e a saída que havia sido calculada antes. Por isso, ele mantém um estado entre atualizações.
Nesta etapa, considere a saída anterior y[k − 1] como esse estado guardado. Quando chega x[k], o filtro a compara com o estado e produz a nova saída y[k]. Em seguida, y[k] fica disponível como estado para a próxima atualização.

A saída recém-calculada é armazenada e passa a ser o estado da atualização seguinte.
A atualização do filtro é:
y[k] = y[k − 1] + α × (x[k] − y[k − 1])
Leia-a em três partes:
y[k − 1].x[k] − y[k − 1].α × (x[k] − y[k − 1]).Essa parcela é a correção. Assim, a nova saída não é calculada do zero: ela ajusta o valor que o filtro já mantinha.
Exemplo
Suponha que o estado anterior seja 10, a entrada atual seja 18 e que α = 0,25.
18 − 10 = 80,25 × 8 = 210 + 2 = 12Portanto, y[k] vale 12. O filtro percebe que a entrada está acima do estado anterior e o move parcialmente nessa direção.
O valor de α será interpretado e escolhido nos próximos passos; por enquanto, observe seu papel: ele multiplica a diferença antes que ela seja somada ao estado.
Associe cada elemento ao seu papel em uma atualização do filtro.
Faça as associações.
Toque em um item e depois no par correspondente.
Em cada atualização, o filtro segue esta ideia:
estado anterior → diferença até a entrada → correção parcial → novo estado
A recursão está no reaproveitamento da saída anterior. Na próxima tela, você rastreará esse estado ao longo de várias amostras e verá como diferentes valores de α alteram a resposta.
| Elemento | Função |
|---|---|
| x[k] | Entrada que acabou de chegar |
| y[k − 1] | Estado guardado da atualização anterior |
| α × (x[k] − y[k − 1]) | Correção parcial |
| y[k] | Novo estado e saída atual |

Passo 2 de 8
Calcule atualizações sucessivas e relacione o coeficiente α ao compromisso entre rapidez e suavização.
O coeficiente α define quanto da diferença entre a entrada atual e o estado anterior será corrigido em cada atualização:
y[k] = y[k − 1] + α × (x[k] − y[k − 1])
Neste tutorial, adotamos 0 < α ≤ 1. Nessa faixa, diante de uma mudança de patamar, a saída avança em direção à entrada sem alternar para os dois lados do novo valor.

Quanto menor o valor de α, menor é a correção em cada atualização e mais lenta é a aproximação ao novo patamar.
Exemplo
Rastreie a sequência sempre na mesma ordem: use o estado anterior, calcule a diferença até a entrada, aplique a fração α e some ao estado.
Considere o estado inicial fornecido y[0] = 0, α = 0,5 e as duas entradas seguintes iguais a 10.
Na primeira atualização:
x[1] = 10
y[1] = 0 + 0,5 × (10 − 0) = 5
Na atualização seguinte, o estado anterior não é mais zero: é y[1] = 5.
x[2] = 10
y[2] = 5 + 0,5 × (10 − 5) = 7,5
Mesmo com a entrada mantida em 10, a correção diminui: primeiro foi 5; depois, 2,5. A saída se aproxima do patamar sem alcançá-lo de uma só vez.
Evolução do exemplo com entrada constante em 10.
| k | x[k] | y[k − 1] | y[k] |
|---|---|---|---|
| 0 | — | — | 0 |
| 1 | 10 | 0 | 5 |
| 2 | 10 | 5 | 7,5 |
Use α = 0,5, estado inicial y[0] = 4 e entrada x[1] = 10.
Complete a saída após essa atualização:
y[1] = 4 + 0,5 × (10 − 4) = {{lacuna}}
y[1] =
A mesma sequência recebe duas configurações, ambas com y[0] = 0. A entrada muda de 0 para 10 e permanece em 10.
Observe que α = 0,8 chega mais perto da entrada logo na primeira atualização do que α = 0,2. Isso significa resposta mais rápida, mas também menor suavização das variações de amostra para amostra.
Mesma entrada, estados iniciais e número de atualizações.
| Atualização | Entrada x | Saída, α = 0,2 | Saída, α = 0,8 |
|---|---|---|---|
| Inicial | 0 | 0 | 0 |
| 1 | 10 | 2 | 8 |
| 2 | 10 | 3,6 | 9,6 |
| 3 | 10 | 4,88 | 9,92 |
Qual escolha acompanha exatamente cada nova amostra de entrada, sem suavização?

Passo 3 de 8
Conecte o coeficiente α ao período de atualização e à constante de tempo desejada para configurar a resposta temporal do filtro.
Quando a entrada fica em um patamar constante, a saída se aproxima dela. A cada atualização, a diferença que ainda falta é multiplicada por 1 − α.
Se faltavam 10 unidades e α = 0,2, depois da atualização faltam 8: o filtro corrigiu 20% da diferença. Na próxima, corrigirá 20% do que restou. Portanto, α define o decaimento por amostra — mas, para definir a rapidez no tempo, também precisamos de T_s.

Após cada atualização, a diferença restante é multiplicada por 1 − α.
Para associar o filtro a uma constante de tempo desejada, use:
α = 1 − exp(−T_s / τ_f)
exp(z) é a função exponencial da calculadora ou da linguagem de programação. Não é preciso calcular derivadas.
Quanto menor for T_s em relação a τ_f, menor será α: cada atualização fará uma correção pequena, mas haverá mais atualizações no mesmo intervalo de tempo.
Exemplo
Suponha T_s = 20 ms e τ_f = 100 ms.
20 ms / 100 ms = 0,2.α = 1 − exp(−0,2).exp(−0,2) ≈ 0,8187:α ≈ 1 − 0,8187 = 0,1813
Use esse valor nas atualizações até que T_s ou τ_f seja alterado.
A razão T_s/τ_f não tem unidade. Por isso, milissegundos e segundos funcionam igualmente bem, desde que sejam usados de modo consistente.
Valores aproximados obtidos por α = 1 − exp(−T_s/τ_f).
| T_s | τ_f | T_s / τ_f | α |
|---|---|---|---|
| 10 ms | 100 ms | 0,10 | 0,0952 |
| 20 ms | 100 ms | 0,20 | 0,1813 |
| 50 ms | 100 ms | 0,50 | 0,3935 |
| 0,02 s | 0,10 s | 0,20 | 0,1813 |
Calcule α para T_s = 25 ms e τ_f = 100 ms. Arredonde para quatro casas decimais.
Se o período mudar, o mesmo α mantém o mesmo comportamento por atualização, mas não necessariamente por segundo.
Um filtro configurado com T_s = 20 ms e τ_f = 100 ms usa α ≈ 0,1813. Se T_s passar para 40 ms e α for mantido, as correções ocorrerão com metade da frequência. O filtro ficará mais lento no tempo.
Para preservar τ_f = 100 ms, recalcule: α = 1 − exp(−40/100) ≈ 0,3297.
Calcule a exponencial na configuração inicial ou quando T_s ou τ_f mudar. Nas atualizações normais, use apenas o α já calculado; não é necessário chamar exp() a cada amostra.
Um filtro usa α = 0,1813, calculado para T_s = 20 ms. Se o período passa a 40 ms e α não muda, a constante de tempo temporal continua sendo aproximadamente 100 ms.

Passo 4 de 8
Implemente uma função de filtro que conserva seu estado entre chamadas e começa pela primeira medição válida.
A função do filtro recebe uma amostra válida e devolve a saída filtrada. Para funcionar entre chamadas, ela precisa guardar dois dados fora da função: o último valor filtrado (estado) e se já existe uma primeira amostra (inicializado).
Na primeira chamada, ainda não há saída anterior para aplicar à equação. Portanto, copie a medição para o estado e retorne-a. Nas chamadas seguintes, atualize o mesmo estado com o coeficiente alpha já calculado.

O estado não é recriado a cada chamada: ele transporta a saída filtrada para a próxima atualização.
Declare o estado uma vez, em um escopo que continue existindo enquanto o programa roda. O indicador booleano separa o caso inicial das atualizações normais.
A função abaixo pressupõe que alpha está entre 0 e 1 e que amostra já foi considerada válida por quem a chama.
Código para estudar e usar em seu projeto local.
float estado = 0.0f;
bool inicializado = false;
float atualizaFiltro(float amostra, float alpha) {
if (!inicializado) {
estado = amostra;
inicializado = true;
return estado;
}
estado = estado + alpha * (amostra - estado);
return estado;
}Exemplo
Se a primeira amostra for 42.0f, a primeira chamada devolve exatamente 42.0f, independentemente de alpha. Com isso, o filtro começa no valor realmente medido, não em um zero arbitrário.
Na chamada seguinte, a variável estado já contém 42 e pode receber a correção parcial prevista pela equação.
Considere alpha = 0,25 e uma primeira medição igual a 80. Qual sequência descreve corretamente o processamento da primeira chamada e das chamadas posteriores?
Escreva pelo menos 80 caracteres (0/80).
Ordene as ações de uma chamada válida, colocando primeiro o tratamento da primeira amostra e depois a atualização normal.
Complete os trechos que fazem a primeira amostra definir o estado e que aplicam a atualização recursiva nas chamadas seguintes.
Preencha a lógica central da função.
float atualizaFiltro(float amostra, float alpha) {
if () {
estado = ;
inicializado = ;
return estado;
}
estado = + * (amostra - estado);
return estado;
}
Passo 5 de 8
Evite que o filtro pare antes de alcançar a entrada por causa de conversões inteiras.
Uma atualização do filtro tem uma correção: α × (entrada − estado). Se essa correção for fracionária, mas o resultado for guardado em uma variável inteira, a parte decimal é descartada.
Exemplo: com estado 100, entrada 101 e α = 0,2, a correção é 0,2. O novo valor matemático seria 100,2; em um int, ele volta a ser 100. Na próxima atualização, a mesma correção pode desaparecer de novo. Assim, o filtro fica parado apesar de ainda existir diferença até a entrada.

O armazenamento inteiro pode eliminar uma correção menor que uma unidade.
O problema não é a fórmula do filtro, e sim o local onde seu resultado é armazenado. Mantenha em ponto flutuante:
alpha;Converta para inteiro apenas na interface que realmente exigir isso, por exemplo ao enviar um valor para um hardware ou uma API que aceite somente inteiros. O estado interno não deve ser convertido a cada amostra.
Considere estado = 100, entrada = 101 e alpha = 0,2.
| Atualização | Estado em int | Estado em float |
|---|---|---|
| Inicial | 100 | 100,0 |
| 1ª | 100 | 100,2 |
| 2ª | 100 | 100,36 |
| 3ª | 100 | 100,488 |
Compare as duas versões. A primeira perde a parte fracionária toda vez que atribui o resultado ao estado inteiro.
// Incorreto: cada atribuição converte o resultado para inteiro.
int estado = 100;
float alpha = 0.2f;
int entrada = 101;
estado = estado + alpha * (entrada - estado);
// estado continua 100
// Correto: o estado preserva a fração.
float estadoFiltrado = 100.0f;
float entradaFloat = 101.0f;
estadoFiltrado = estadoFiltrado + alpha * (entradaFloat - estadoFiltrado);
// estadoFiltrado vale 100.2fDica
float também tem precisão finita. Em escalas muito grandes, uma correção muito pequena pode não alterar o valor armazenado. Portanto, teste o filtro com a faixa numérica real do seu sinal: confirme que uma correção esperada ainda muda o estado.
Isso não exige precisão ilimitada; exige que a resolução numérica seja adequada à medição e ao efeito que você quer preservar.
Complete os tipos que preservam as correções fracionárias no estado do filtro.
struct Filtro {
estado;
bool inicializado;
};
float atualizar(Filtro &f, float entrada) {
const alpha = 0.2f;
if (!f.inicializado) {
f.estado = entrada;
f.inicializado = true;
} else {
f.estado = f.estado + alpha * (entrada - f.estado);
}
return f.estado;
}
Passo 6 de 8
A relação entre α, período de atualização e constante de tempo pressupõe duas condições: cada entrada usada é válida e as atualizações ocorrem regularmente. Se uma leitura falha ou chega depois de uma lacuna, ela não representa simplesmente “mais uma amostra” na mesma sequência temporal.

A saída pode permanecer disponível, mas a lacuna impede assumir automaticamente a dinâmica temporal nominal.
Atenção
Não substitua uma leitura inválida por zero nem repita uma leitura antiga como se fosse nova. Ambas as ações criam uma entrada artificial e fazem o estado do filtro mudar por um dado que não foi medido.
Uma política simples separa o valor armazenado do status dele. Em uma falha curta, não execute a atualização recursiva: preserve y anterior e informe que a saída está desatualizada. Assim, quem usa a saída sabe que ela não representa uma medição recente.
Exemplo
Exemplo: o filtro tem y = 24,6. A próxima aquisição é inválida. A saída publicada pode continuar em 24,6 com status “desatualizada”; não calcule uma nova correção. Quando houver uma nova amostra válida, a atualização pode voltar a ocorrer conforme a política de interrupção definida.
Defina um limiar de interrupção longa, adequado à aplicação: por exemplo, uma quantidade de períodos perdidos ou um tempo sem amostra válida. Ao ultrapassá-lo, marque o filtro como “precisa reinicializar”. Na próxima amostra válida, use-a para inicializar o estado, em vez de aplicar a equação sobre um estado antigo.
Atenção
A reinicialização pode causar uma descontinuidade na saída: o valor antigo deixa de representar a situação atual. Isso é mais transparente do que fingir continuidade temporal durante uma lacuna longa.
Ordene as ações de uma política para uma interrupção que ultrapassa o limiar declarado, desde a primeira amostra inválida até a retomada.
O filtro recebe amostras a cada 100 ms. Uma leitura é inválida e, depois, ficam 2 s sem leituras válidas — acima do limiar definido. Qual política é coerente?

Passo 7 de 8
Compare o filtro recursivo de primeira ordem e a média móvel sob as mesmas condições de entrada, distinguindo memória, flutuação residual e resposta a mudanças.
Para comparar de forma justa, aplique aos dois filtros o mesmo período de atualização T_s e a mesma sequência de entrada. Antes de uma mudança de patamar, deixe ambos estabelecidos no valor inicial: assim, a diferença observada vem do filtro, e não de condições iniciais diferentes.
Observe dois aspectos separadamente:
O filtro recursivo usa a saída anterior e α. A média móvel usa a janela das últimas N amostras. Nenhum é universalmente “melhor”: a escolha depende da prioridade do sistema.

Compare a variação que sobra antes do degrau e o caminho de cada curva depois dele.
Neste exemplo, ambos os filtros já estavam em 100 antes da tabela. A média móvel tem N = 4 e o recursivo usa α = 0,25. Os valores estão arredondados.
As pequenas perturbações alternadas mostram a flutuação residual. A partir de k = 5, a entrada passa a 120: compare o atraso de cada saída sem chamar nenhuma delas de atraso puro.
Sequência comum aplicada aos dois filtros.
| k | Entrada x[k] | Recursivo α=0,25 | Média móvel N=4 |
|---|---|---|---|
| 0 | 100 | 100,00 | 100,00 |
| 1 | 104 | 101,00 | 101,00 |
| 2 | 96 | 99,75 | 100,00 |
| 3 | 104 | 100,81 | 101,00 |
| 4 | 96 | 99,61 | 100,00 |
| 5 | 120 | 104,71 | 104,00 |
| 6 | 120 | 108,53 | 110,00 |
| 7 | 120 | 111,40 | 114,00 |
| 8 | 120 | 113,55 | 120,00 |
Exemplo
Nesta configuração específica, a média móvel elimina a influência das amostras antigas após quatro atualizações no novo patamar; por isso chega a 120 em k = 8. O recursivo continua se aproximando gradualmente.
Isso não cria uma equivalência geral entre α = 0,25 e N = 4. Outras escolhas de α, N e sequências produzem outros compromissos de ruído e rapidez.
Associe cada aspecto à interpretação correta nesta comparação.
Toque em um item e depois no par correspondente.
Imagine que seu sistema tem pouca memória disponível, mas também não pode aceitar muita lentidão quando o sinal muda. Com base na comparação, qual filtro e quais parâmetros você investigaria primeiro? Justifique usando memória, flutuação residual e resposta à mudança. Não há uma única resposta correta.
Escreva pelo menos 100 caracteres (0/100).

Passo 8 de 8
Conclua a configuração, a implementação e a validação de um filtro recursivo de primeira ordem em um caso sintético completo.
Neste caso integrado, o filtro recebe uma amostra a cada T_s = 100 ms e deve ter τ_f = 500 ms. A sequência sintética é: 20, 20, 30, duas amostras inválidas, 30 e 20.
Use a política definida: uma amostra inválida mantém a última saída, identificada como desatualizada. Após duas posições consecutivas inválidas, o estado é reinicializado; a próxima amostra válida passa a ser a nova saída inicial.
O coeficiente é calculado uma vez na configuração:
α = 1 − exp(−T_s / τ_f)
Com T_s = 0,1 s e τ_f = 0,5 s, α ≈ 0,181269. Assim, uma mudança de 20 para 30 é corrigida parcialmente: a saída vai para aproximadamente 21,812692, não diretamente para 30.

A interrupção não cria medições artificiais: a saída é mantida como desatualizada e o estado é reinicializado depois do limiar declarado.
Calcule o coeficiente do caso. Arredonde para quatro casas decimais:
α = 1 − exp(−0,1 / 0,5) = __
Complete a função. Ela deve inicializar o estado uma única vez e preservar correções fracionárias.
float updateFilter(float sample) {
if (!) {
y = ;
initialized = true;
return y;
}
y += * (sample - y);
return y;
}Copie este programa inteiro para um único sketch, se quiser executá-lo na sua IDE ou em um Arduino Uno próprio. Ele não exige sensor nem circuito externo: as amostras são sintéticas.
#include <math.h>
const float TS_S = 0.1f;
const float TAU_F_S = 0.5f;
float alpha, y = 0.0f;
bool initialized = false;
struct Sample { float value; bool valid; };
Sample data[] = {{20,true},{20,true},{30,true},
{0,false},{0,false},{30,true},{20,true}};
float updateFilter(float sample) {
if (!initialized) {
y = sample;
initialized = true;
return y;
}
y += alpha * (sample - y);
return y;
}
void setup() {
Serial.begin(9600);
alpha = 1.0f - exp(-TS_S / TAU_F_S);
Serial.print("alpha="); Serial.println(alpha, 6);
byte invalidCount = 0;
for (byte k = 0; k < 7; k++) {
if (!data[k].valid) {
invalidCount++;
Serial.print(k); Serial.print(" invalid, y=");
Serial.println(y, 6);
if (invalidCount >= 2) initialized = false;
continue;
}
invalidCount = 0;
float out = updateFilter(data[k].value);
Serial.print(k); Serial.print(" valid, y=");
Serial.println(out, 6);
}
}
void loop() {}alpha=0.181269 0 valid, y=20.000000 1 valid, y=20.000000 2 valid, y=21.812693 3 invalid, y=21.812693 4 invalid, y=21.812693 5 valid, y=30.000000 6 valid, y=28.187307
A formatação decimal pode variar levemente entre versões da IDE, mas os valores e os estados devem ser equivalentes.
Analise o registro de referência do sketch e responda em poucas frases:
Escreva pelo menos 100 caracteres (0/100).
Resumo
Parabéns! Você concluiu: Filtro digital recursivo de primeira ordem
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks