
Passo 1 de 8
Entenda o que entra em cada média
Identifique as amostras de uma janela cheia e calcule médias móveis em saídas consecutivas.
Trilha de aprendizado · Nível 13 · Tutorial 2
Implementar uma média móvel com memória e tempo de execução previsíveis, comparando a suavização obtida com o atraso introduzido.
Entenda o que entra em cada média
Identifique as amostras de uma janela cheia e calcule médias móveis em saídas consecutivas. 2 min
Reutilize as posições com um buffer circular
Rastreie a posição que recebe cada nova amostra e mantenha o índice dentro do vetor. 2 min
Atualize a soma sem percorrer a janela
Atualize a soma de uma janela cheia retirando a amostra antiga e incluindo a nova, sem percorrer todo o buffer. 2 min
Comece sem inventar medições de zero
Evite tratar posições ainda não preenchidas como medições reais: conte as amostras válidas e use essa contagem como divisor até completar a janela. 2 min
Proteja o acumulador e a divisão
Dimensione o acumulador pela soma máxima e preserve médias fracionárias ao converter no momento correto. 2 min
Integre e confira a implementação
Integre uma função de média móvel em C/C++ e confira seu comportamento com uma sequência sintética completa. 3 min
Relacione suavização, janela e atraso
2 min
Compare duas janelas e valide sua escolha
Validar a implementação e justificar a escolha entre duas janelas com base na suavização e no atraso permitido. 3 min

Passo 1 de 8
Identifique as amostras de uma janela cheia e calcule médias móveis em saídas consecutivas.
Uma sequência de leituras pode ser escrita como x[k], em que k indica a posição da amostra na sequência. A saída da média móvel será y[k].
Exemplo: se x[0] = 10, x[1] = 14 e x[2] = 12, esses são três valores de entrada em instantes consecutivos. Para uma janela de tamanho N, y[k] é a média das N amostras mais recentes, incluindo sempre a amostra atual x[k].
Neste step, considere somente janelas já completas.

Para calcular y[5] com N = 4, entram x[2], x[3], x[4] e x[5].
Com a janela cheia, a regra é:
y[k] = (x[k] + x[k − 1] + ... + x[k − N + 1]) / N
Se N = 4, cada saída usa exatamente quatro amostras consecutivas. Ao chegar uma nova amostra, a janela avança uma posição: o novo valor entra e o valor que ficou mais distante no passado deixa de participar. Não se somam todas as leituras recebidas desde o início.
Exemplo
Considere N = 4 e esta sequência:
x[0]=8, x[1]=10, x[2]=14, x[3]=12, x[4]=16, x[5]=18
A primeira janela cheia termina em k=3:
y[3] = (8 + 10 + 14 + 12) / 4 = 11
Na amostra seguinte, a janela é deslocada:
y[4] = (10 + 14 + 12 + 16) / 4 = 13
O 8 saiu da janela; o 16 entrou. Os três valores do meio permanecem.
Ainda com N = 4, use a sequência:
x[0]=8, x[1]=10, x[2]=14, x[3]=12, x[4]=16, x[5]=18
Complete a média da janela que termina em k=5:
y[5] = (14 + 12 + 16 + {{blank}}) / 4
Qual valor completa a expressão de y[5]?
Agora calcule o resultado numérico: y[5] = (14 + 12 + 16 + 18) / 4 = ____.
Para uma janela cheia de N amostras:
Nos próximos steps, essa mesma janela será mantida na memória sem deslocar todos os valores do vetor.
Com N = 4, quais amostras pertencem ao cálculo de y[6]?

Passo 2 de 8
Rastreie a posição que recebe cada nova amostra e mantenha o índice dentro do vetor.
Depois que a janela está cheia, não é preciso deslocar todas as amostras no vetor para abrir espaço. Um buffer circular reutiliza posições de um vetor fixo.
Considere N = 4 e uma janela, em ordem temporal, com as amostras 10, 20, 30, 40. Quando a próxima amostra, 50, chegar, a mais antiga (10) deve sair da janela. O índice de escrita aponta exatamente para a posição que contém essa amostra antiga.
Assim, basta sobrescrever uma posição e avançar o índice. Ao alcançar o fim do vetor, o índice retorna a 0.

Com a janela cheia, o índice aponta para a amostra mais antiga: ela será substituída pela próxima entrada.
A ordem física é a numeração fixa das posições do vetor: 0, 1, 2, 3. Já a ordem temporal indica quando cada valor foi recebido: do mais antigo ao mais novo.
Essas ordens coincidem apenas em alguns instantes. Depois que o índice retorna ao início, elas deixam de coincidir. Por exemplo, após substituir 10 por 50, o vetor físico fica {50, 20, 30, 40}. Mas a janela temporal passa a ser 20, 30, 40, 50.
Não interprete o vetor da posição 0 até N - 1 como uma sequência cronológica sem considerar o índice.
Escrita e avanço do índice; considere que buffer já contém N amostras válidas.
const uint8_t N = 4;
uint16_t buffer[N] = {10, 20, 30, 40};
uint8_t indice = 0;
// Chega a amostra 50.
buffer[indice] = 50;
indice++;
if (indice == N) {
indice = 0;
}
// buffer: {50, 20, 30, 40}
// indice: 1
// ordem temporal: 20, 30, 40, 50
Ao chegar ao fim, o próximo avanço volta à posição zero; nenhuma posição fora do vetor é acessada.
Coloque os estados na ordem em que ocorrem. O buffer tem N = 4, está cheio com {10, 20, 30, 40} e indice = 3. A nova amostra é 50.
Ordene os eventos do primeiro ao último.
Complete a condição que impede que a próxima escrita use a posição N.
buffer[indice] = novaAmostra;
indice++;
if () {
indice = 0;
}
Passo 3 de 8
Atualize a soma de uma janela cheia retirando a amostra antiga e incluindo a nova, sem percorrer todo o buffer.
Com a janela já cheia, mantenha soma como um estado: ela é a soma exata dos valores presentes no buffer naquele instante. A média continua sendo calculada por soma / N, sem somar todas as posições novamente a cada amostra.
Quando chega uma entrada, apenas um valor sai da janela e apenas um entra. Portanto, a soma anterior pode ser corrigida em vez de recalculada.

Ao substituir a amostra mais antiga, a soma perde o valor antigo e recebe a nova amostra.
Exemplo
Suponha N = 4, buffer em ordem física {12, 18, 20, 10}, indice = 0 e soma = 60. O índice aponta para a amostra antiga, 12. Ao chegar novo = 16:
60 − 12 = 48.{16, 18, 20, 10}.48 + 16 = 64.A conferência direta do buffer atualizado é 16 + 18 + 20 + 10 = 64. Logo, a atualização incremental e a soma direta representam a mesma janela.
Trecho para uma janela já cheia.
soma -= buffer[indice];
buffer[indice] = novo;
soma += novo;
indice++;
if (indice == N) {
indice = 0;
}Dica
A ordem importa: subtraia o valor armazenado antes de gravar novo na mesma posição. Depois da sobrescrita, a amostra antiga não está mais disponível no buffer.
Considere uma janela cheia com N = 4, buffer = {7, 11, 9, 13}, indice = 2 e soma = 40. Chega novo = 15.
Faça a troca mentalmente: a posição 2 contém 9, que sai; 15 entra nessa posição. Qual alternativa mostra tanto a nova soma incremental quanto a conferência pela soma direta do buffer resultante?
Qual verificação está correta?
Complete os termos que mantêm o acumulador coerente ao trocar a amostra apontada por indice. Considere que a janela já está cheia.
Preencha o valor que sai e o valor que entra no acumulador.
soma -= ;
buffer[indice] = novo;
soma += ;A atualização incremental usa uma quantidade fixa de ações por amostra: acessar uma posição, subtrair, gravar, adicionar e avançar o índice. Esse trabalho não cresce quando N aumenta, pois não há laço percorrendo a janela a cada atualização.
Em contrapartida, o buffer precisa de N posições reservadas previamente. Assim, a memória é proporcional a N, enquanto o trabalho de atualização permanece independente do tamanho da janela.
Dica
Um número fixo de operações torna o trabalho por amostra mais previsível para planejar a tarefa periódica. Isso não garante que cada chamada levará exatamente o mesmo tempo: interrupções e outras condições do sistema ainda podem alterar a duração observada.

Passo 4 de 8
Evite tratar posições ainda não preenchidas como medições reais: conte as amostras válidas e use essa contagem como divisor até completar a janela.
Antes da primeira amostra, inicialize o estado assim: vetor com zeros, indice = 0, soma = 0 e validas = 0.
Os zeros no vetor são apenas valores seguros para a memória ainda vazia — não são medições. Portanto, eles não podem entrar no divisor da média.
Quando chega uma amostra válida, ela entra no buffer e validas cresce. Enquanto a janela não está cheia, a saída é:
y = soma / validas
Quando validas chega a N, ela para de crescer. A partir daí, cada nova amostra substitui a mais antiga e a divisão continua usando validas, que já vale N.

Os zeros de inicialização ocupam a memória, mas somente amostras recebidas aumentam a contagem válida.
Considere N = 4 e as amostras 8, 12, 4, 16, 20. A tabela acompanha o estado depois de cada atualização. Na quinta entrada, a janela já estava cheia: o 8 é removido da soma e o 20 ocupa sua posição.
| Entrada x[k] | Amostras válidas na janela | Soma | validas | Saída y[k] |
|---|---|---|---|---|
| 8 | 8 | 8 | 1 | 8 |
| 12 | 8, 12 | 20 | 2 | 10 |
| 4 | 8, 12, 4 | 24 | 3 | 8 |
| 16 | 8, 12, 4, 16 | 40 | 4 | 10 |
| 20 | 12, 4, 16, 20 | 52 | 4 | 13 |
A atualização abaixo preserva a lógica do buffer circular já estudada. A condição sobre validas impede que a contagem ultrapasse N. A divisão ocorre depois que a nova amostra foi contabilizada; assim, a função só calcula uma média quando há ao menos uma amostra válida e nunca divide por zero.
Trecho para estudar e incorporar ao estado persistente do filtro.
const uint8_t N = 4;
uint16_t buffer[N] = {0};
uint8_t indice = 0;
uint8_t validas = 0;
uint32_t soma = 0;
float atualizaMedia(uint16_t amostra) {
soma -= buffer[indice];
buffer[indice] = amostra;
soma += amostra;
if (validas < N) {
validas++;
}
indice++;
if (indice == N) {
indice = 0;
}
return (float)soma / validas;
}Com N = 4, o buffer foi inicializado com zeros e acaba de receber a primeira amostra, de valor 8. A primeira saída da média móvel é {{blank}}.
Complete a atualização da contagem e o divisor. Considere que este cálculo ocorre após a possível atualização da contagem.
if (validas < N) {
++;
}
float media = (float)soma / ;
Passo 5 de 8
Dimensione o acumulador pela soma máxima e preserve médias fracionárias ao converter no momento correto.
A amostra do ADC do Uno pode caber em uint16_t: ela vai de 0 a 1023. Mas a variável soma guarda várias amostras ao mesmo tempo e precisa de outra verificação.
Para entradas não negativas, calcule o pior caso:
S_max = N × x_max
Aqui, N é a capacidade da janela e x_max é o maior valor possível de uma amostra. Escolha um acumulador que comporte S_max com margem compatível com seu projeto.

A faixa de cada amostra não define, sozinha, a faixa necessária para a soma.
Exemplo
Considere uma janela de 128 amostras do ADC de 10 bits. No máximo, cada amostra vale 1023:
S_max = 128 × 1023 = 130944
Esse resultado é maior que 65535, portanto não cabe em uint16_t. Em contrapartida, cabe em uint32_t, cujo máximo é muito maior. O vetor pode continuar guardando cada amostra em uint16_t; apenas o acumulador precisa ser ampliado.
Capacidades relevantes para esse caso.
| Elemento | Maior valor | Conclusão |
|---|---|---|
| Uma amostra do ADC | 1023 | `uint16_t` comporta |
| Soma para N = 128 | 130944 | `uint32_t` necessário |
| Máximo de uint16_t | 65535 | Insuficiente para a soma |
| Máximo de uint32_t | 4294967295 | Suficiente para a soma |
Uma média móvel recebe códigos entre 0 e 1023 e usa N = 80. Qual alternativa calcula corretamente a soma máxima e escolhe um acumulador adequado?
Para N = 80 e x_max = 1023, qual escolha está correta?
Faça o cálculo do limite em um tipo amplo desde o começo. Não basta declarar a variável de destino como uint32_t: se a multiplicação ocorrer antes em um tipo estreito, o resultado já pode ter transbordado.
Na média, a mesma atenção vale para a divisão. Quando os dois operandos são inteiros, a fração é descartada antes de qualquer conversão posterior.
Cálculo seguro do limite e média com parte fracionária preservada.
const uint16_t N = 128;
const uint16_t X_MAX = 1023;
// A conversão acontece antes da multiplicação.
const uint32_t somaMax = (uint32_t)N * X_MAX;
uint32_t soma = 403;
uint16_t validas = 4;
// A conversão acontece antes da divisão.
float media = (float)soma / validas; // 100.75
// Incorreto: a divisão inteira já descartou a fração.
float mediaErrada = (float)(soma / validas); // 100.0Dica
Em 403 / 4, ambos os operandos são inteiros; o resultado intermediário é 100. Convertê-lo depois produz apenas 100.0.
Já (float)soma / validas executa uma divisão em ponto flutuante e resulta em 100.75. A conversão deve ocorrer antes da operação que poderia perder informação.
Complete as expressões para calcular o limite da soma e a média fracionária corretamente.
const uint16_t N = 128;
const uint16_t X_MAX = 1023;
const uint32_t somaMax = (uint32_t) * X_MAX;
float y = (float) / validas;
Passo 6 de 8
Integre uma função de média móvel em C/C++ e confira seu comportamento com uma sequência sintética completa.
A função abaixo reúne o que você já construiu: memória fixa, índice circular, soma incremental e contagem válida. O estado fica fora da função para persistir entre chamadas. Com N = 4, cada chamada troca no máximo uma posição do vetor e faz a divisão pela quantidade de amostras válidas.
A sequência importa: retire o valor antigo da soma, grave a nova amostra, acrescente-a à soma, atualize a contagem e avance o índice. Assim, o valor removido ainda está disponível quando é necessário.

O índice aponta para a próxima posição a substituir; após a escrita, ele avança e retorna a zero quando necessário.
Trecho 1 — coloque no início de um sketch Arduino.
const uint8_t N = 4;
uint16_t buffer[N] = {0};
uint8_t indice = 0;
uint8_t validas = 0;
uint32_t soma = 0;
float atualizaMedia(uint16_t x) {
soma -= buffer[indice];
buffer[indice] = x;
soma += x;
if (validas < N) {
validas++;
}
indice++;
if (indice == N) {
indice = 0;
}
return (float)soma / validas;
}Acrescente este trecho logo depois do trecho anterior, no mesmo sketch. Ele usa dados sintéticos: não exige sensor, circuito ou biblioteca externa.
Ts_ms = 10 declara que as amostras representam espaçamento nominal de 10 ms. As linhas no monitor serial podem aparecer com outro intervalo, pois a transmissão serial não define o período de amostragem.
Trecho 2 — acrescente após o trecho 1 e envie o sketch ao seu Uno, se quiser executar localmente.
const uint16_t dados[] = {
100, 100, 100, 100,
0, 1023, 0, 1023,
10, 20, 30, 40
};
const uint8_t TOTAL = sizeof(dados) / sizeof(dados[0]);
const uint16_t Ts_ms = 10;
void setup() {
Serial.begin(9600);
for (uint8_t k = 0; k < TOTAL; k++) {
float y = atualizaMedia(dados[k]);
Serial.print("k="); Serial.print(k);
Serial.print(" x="); Serial.print(dados[k]);
Serial.print(" y="); Serial.print(y, 2);
Serial.print(" soma="); Serial.print(soma);
Serial.print(" count="); Serial.print(validas);
Serial.print(" idx="); Serial.println(indice);
}
}
void loop() {
}k=0 x=100 y=100.00 soma=100 count=1 idx=1 k=1 x=100 y=100.00 soma=200 count=2 idx=2 k=2 x=100 y=100.00 soma=300 count=3 idx=3 k=3 x=100 y=100.00 soma=400 count=4 idx=0 k=4 x=0 y=75.00 soma=300 count=4 idx=1 k=5 x=1023 y=305.75 soma=1223 count=4 idx=2 k=6 x=0 y=280.75 soma=1123 count=4 idx=3 k=7 x=1023 y=511.50 soma=2046 count=4 idx=0 k=8 x=10 y=514.00 soma=2056 count=4 idx=1 k=9 x=20 y=263.25 soma=1053 count=4 idx=2 k=10 x=30 y=270.75 soma=1083 count=4 idx=3 k=11 x=40 y=25.00 soma=100 count=4 idx=0
A saída abaixo considera as duas partes concatenadas. O número após idx é o índice já avançado, pronto para a próxima chamada.
Use estes pontos de conferência para rastrear o sketch mesmo sem Arduino. A primeira linha confirma que posições zeradas não entram como medições: a divisão é por count = 1. A linha k=4 é a primeira substituição. Em k=7 e k=11, o índice retornou ao início após completar outra volta.
Valores selecionados da sequência de teste.
| k | x[k] | soma | count | y[k] | idx |
|---|---|---|---|---|---|
| 0 | 100 | 100 | 1 | 100,00 | 1 |
| 3 | 100 | 400 | 4 | 100,00 | 0 |
| 4 | 0 | 300 | 4 | 75,00 | 1 |
| 5 | 1023 | 1223 | 4 | 305,75 | 2 |
| 7 | 1023 | 2046 | 4 | 511,50 | 0 |
| 9 | 20 | 1053 | 4 | 263,25 | 2 |
| 11 | 40 | 100 | 4 | 25,00 | 0 |
Dica
Os valores 0 e 1023 verificam extremos típicos do ADC do Uno. As saídas 305,75; 511,50 e 263,25 confirmam que a conversão para float ocorreu antes da divisão. Se a divisão fosse inteira, essas frações seriam descartadas.
Complete os três pontos que tornam a atualização coerente com o rastreamento.
float atualizaMedia(uint16_t x) {
soma -= ;
buffer[indice] = x;
soma += x;
if (validas < N) {
++;
}
indice = (indice + 1) % N;
return / validas;
}
Passo 7 de 8
Com amostras regulares, a janela de uma média móvel de tamanho N tem duração nominal:
N × T_s
Ela reúne N medições, incluindo a atual. Já o intervalo entre a amostra mais antiga e a atual é menor:
(N − 1) × T_s
Exemplo: com N = 4 e T_s = 10 ms, a janela é chamada de 40 ms, mas seus extremos estão separados por 30 ms. As duas medidas são úteis, mas não são a mesma coisa.

Para N = 8, a duração nominal cobre 8 intervalos de amostragem na convenção N × T_s; a separação temporal entre os extremos usa 7 intervalos: (N − 1) × T_s.
Com T_s = 10 ms, compare as duas janelas que serão usadas neste step.
| Janela | N × T_s | (N − 1) × T_s | Atraso aprox. |
|---|---|---|---|
| N = 4 | 40 ms | 30 ms | 15 ms |
| N = 8 | 80 ms | 70 ms | 35 ms |
Quando a janela está cheia e as amostras são regulares, uma referência prática para variações lentas é o atraso característico:
atraso ≈ (N − 1) × T_s / 2
Para N = 4 e T_s = 10 ms, o resultado é 15 ms. Para N = 8, é 35 ms.
Isso não significa que a saída fica imóvel durante esse tempo. Ao chegar uma nova amostra, ela já entra na média e a saída começa a mudar. O valor é uma forma de localizar aproximadamente a resposta média da janela no tempo.

Mantendo a mesma sequência e o mesmo T_s, N = 8 tende a reduzir mais as flutuações do que N = 4, mas introduz maior atraso característico.
Dica
Aumentar N cria um compromisso, não uma regra universal: em muitos trechos com flutuações rápidas, a janela maior reduz a variação da saída. Porém, o quanto ela reduz depende da sequência de entrada. Em troca, mudanças reais no sinal aparecem mais diluídas ao longo de mais amostras.
Exemplo
Considere um patamar em torno de 100, já depois do preenchimento das janelas. Em um trecho perturbado, a entrada varia entre 96 e 104.
Uma medida simples da flutuação é:
amplitude observada = máximo − mínimo
No exemplo, a saída de N = 4 vai de 99 a 101: amplitude 2. A saída de N = 8 vai de 99,5 a 100,5: amplitude 1. Portanto, nesse trecho específico, N = 8 deixou uma flutuação residual menor.
Os valores abaixo se referem ao mesmo trecho de patamar perturbado, com as janelas já cheias.
| Sinal | Mínimo | Máximo | Amplitude |
|---|---|---|---|
| Entrada bruta | 96 | 104 | 8 |
| Média N = 4 | 99 | 101 | 2 |
| Média N = 8 | 99,5 | 100,5 | 1 |
Se uma nova amostra de 140 chega após esse patamar, as duas médias mudam já nessa primeira atualização. A de N = 4 muda mais porque 1/4 da sua janela foi renovada; a de N = 8 também muda, mas a nova amostra representa só 1/8 da janela. A transição completa continua nas atualizações seguintes, enquanto as amostras antigas são substituídas.
Para N = 8 e T_s = 10 ms, o atraso característico aproximado é de ____ ms.
Após uma mudança de patamar na entrada, qual interpretação é correta para a janela N = 8?

Passo 8 de 8
Validar a implementação e justificar a escolha entre duas janelas com base na suavização e no atraso permitido.
Use exatamente a mesma sequência para duas execuções separadas: primeiro com N = 4, depois com N = 8. O espaçamento nominal das amostras é T_s = 10 ms.
Os 12 primeiros valores representam um patamar próximo de 500 com pequenas perturbações. Os 8 valores seguintes representam uma mudança para o patamar 700. Compare as saídas somente depois que cada janela estiver cheia.
Para que o segundo resultado não carregue amostras do primeiro, reinicialize completamente o estado antes de cada ensaio: buffer, índice, soma e contagem válida.
O sketch a seguir é completo e independente: crie um novo sketch para ele, em vez de acrescentá-lo ao sketch do step anterior. A função executarEnsaio() define a janela ativa, chama reiniciar() e processa todos os dados. Assim, os ensaios com N = 4 e N = 8 usam a mesma entrada, mas estados separados.
O buffer tem capacidade máxima de 8 posições; N seleciona quantas posições participam do ensaio atual. A soma permanece em uint32_t, e a conversão para float ocorre antes da divisão.
Sketch completo para executar localmente no Arduino Uno; não requer sensor, circuito nem biblioteca externa.
const uint8_t MAX_N = 8;
const uint16_t Ts_ms = 10;
const uint16_t dados[] = {
500, 510, 490, 505, 495, 510, 490, 500,
505, 495, 510, 490,
700, 700, 700, 700, 700, 700, 700, 700
};
const uint8_t TOTAL = sizeof(dados) / sizeof(dados[0]);
uint16_t buffer[MAX_N] = {0};
uint8_t indice = 0;
uint8_t validas = 0;
uint8_t N = 4;
uint32_t soma = 0;
void reiniciar() {
for (uint8_t i = 0; i < MAX_N; i++) {
buffer[i] = 0;
}
indice = 0;
validas = 0;
soma = 0;
}
float atualizaMedia(uint16_t x) {
soma -= buffer[indice];
buffer[indice] = x;
soma += x;
if (validas < N) {
validas++;
}
indice++;
if (indice == N) {
indice = 0;
}
return (float)soma / validas;
}
void executarEnsaio(uint8_t janela) {
N = janela;
reiniciar();
Serial.print("Ensaio N=");
Serial.print(N);
Serial.print(" Ts_ms=");
Serial.println(Ts_ms);
for (uint8_t k = 0; k < TOTAL; k++) {
float y = atualizaMedia(dados[k]);
Serial.print("k="); Serial.print(k);
Serial.print(" x="); Serial.print(dados[k]);
Serial.print(" y="); Serial.println(y, 3);
}
}
void setup() {
Serial.begin(9600);
executarEnsaio(4);
executarEnsaio(8);
}
void loop() {
}Ensaio N=4 Ts_ms=10 k=0 x=500 y=500.000 k=1 x=510 y=505.000 k=2 x=490 y=500.000 k=3 x=505 y=501.250 k=4 x=495 y=500.000 k=5 x=510 y=500.000 k=6 x=490 y=500.000 k=7 x=500 y=498.750 k=8 x=505 y=501.250 k=9 x=495 y=497.500 k=10 x=510 y=502.500 k=11 x=490 y=500.000 k=12 x=700 y=548.750 k=13 x=700 y=600.000 k=14 x=700 y=647.500 k=15 x=700 y=700.000 k=16 x=700 y=700.000 k=17 x=700 y=700.000 k=18 x=700 y=700.000 k=19 x=700 y=700.000 Ensaio N=8 Ts_ms=10 k=0 x=500 y=500.000 k=1 x=510 y=505.000 k=2 x=490 y=500.000 k=3 x=505 y=501.250 k=4 x=495 y=500.000 k=5 x=510 y=501.667 k=6 x=490 y=500.000 k=7 x=500 y=500.000 k=8 x=505 y=500.625 k=9 x=495 y=498.750 k=10 x=510 y=501.250 k=11 x=490 y=499.375 k=12 x=700 y=525.000 k=13 x=700 y=548.750 k=14 x=700 y=575.000 k=15 x=700 y=600.000 k=16 x=700 y=624.375 k=17 x=700 y=650.000 k=18 x=700 y=673.750 k=19 x=700 y=700.000
A saída abaixo é a sequência completa esperada no monitor serial a 9600 baud. `Ts_ms` descreve o espaçamento nominal dos dados, não o tempo entre linhas seriais.

A janela maior reduz mais a oscilação neste ensaio, mas dilui a mudança de patamar por mais atualizações.
A tabela confronta a entrada com as duas saídas calculadas pela sequência do ensaio. Entre k = 8 e k = 11, ambas as janelas já estão cheias e o patamar ainda está perturbado. Em k = 12, entra a primeira amostra de 700: as duas saídas sobem imediatamente, mas em quantidades diferentes.
Valores calculados diretamente da sequência apresentada.
| k | x[k] | y com N = 4 | y com N = 8 |
|---|---|---|---|
| 3 | 505 | 501,250 | 501,250 |
| 7 | 500 | 498,750 | 500,000 |
| 8 | 505 | 501,250 | 500,625 |
| 9 | 495 | 497,500 | 498,750 |
| 10 | 510 | 502,500 | 501,250 |
| 11 | 490 | 500,000 | 499,375 |
| 12 | 700 | 548,750 | 525,000 |
| 13 | 700 | 600,000 | 548,750 |
| 14 | 700 | 647,500 | 575,000 |
| 15 | 700 | 700,000 | 600,000 |
| 19 | 700 | 700,000 | 700,000 |
Dica
No trecho cheio de k = 8 a k = 11:
Logo, N = 8 suavizou mais esta sequência. Porém, os atrasos característicos estimados continuam sendo cerca de 15 ms para N = 4 e 35 ms para N = 8. A melhor janela depende também do atraso permitido.
Complete a revisão do núcleo da atualização. Considere que N é positivo e que o buffer, a soma, o índice e a contagem foram inicializados antes do ensaio.
soma -= ;
buffer[indice] = x;
soma += ;
if (validas < N) {
validas++;
}
indice = (indice + 1) % N;
return (float)soma / ;Um sistema aceita atraso característico de até 20 ms e precisa reduzir as flutuações no patamar. Com base na tabela, qual janela você escolheria? Justifique citando o atraso e a flutuação observada.
Escreva pelo menos 60 caracteres (0/60).
Resumo
Parabéns! Você concluiu: Média móvel com buffer circular
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