Pessoal, estou fazendo a média de leituras de um sensor mas queria fazer uma média diferente. 

A média que faço atualmente, ele pega x leituras e faz a média e depois mais x leituras e faz outra média... fazendo medidas em blocos de x leituras.

Como eu poderia fazer médias gradativas e não em blocos, ou seja, faço X leituras e tiro a média, depois eu adiciono 1 leitura nova e retiro uma leitura velha e tiro mais uma média.... Entendeu?

Exemplificando:

Atualmente leio de 1 a 10 e tiro a média, depois de 11 a 20 e tiro outra média( blocos de médias)

Eu quero ler de 1 a 10 e tirar a média, depois de 2 a 11 e outra média, depois de 3 a 12 e mais uma média.

Acredito que tenha como, mas como?

Obrigado.

Exibições: 655

Responder esta

Respostas a este tópico

Vc poderia ter um array de resultados e um contador que diga qual valor vai ser sobrescrito.

Cada vez que vem um novo valor vc escreve na posicao indicada por ele e incrementa. Se ele for 10 vc zera.

Assim escreve nas posicoes de 0 a 9.

Soma tudo e divide por 10 depois eh a media obtida a cada novo ciclo e nao a cada 10 ciclos.

Gente organizada iria querer fazer um "for" pra puxar os resultados e colocar o novo no final, mas para um simples calculo de media nao faz diferença alguma, no ciclo sempre o desprezado vai ser o mais velho automaticamente, isso que importa.

Você poderia fazer uma coisa super simples

(Média * K + Valor Atual)/(K+1) = Média

Mas se você realmente quiser fazer isso o que você escreveu, basta ter um vetor e um índice i que guarda a posição a ser sobrescrita, depois fazer o somatórios de todos os valores do vetor e dividir pelo numero de valores, igual ao que o Eduardo explicou.

float aValor[5];
int amostrasValor = 0;
int tAmostras = 5;

float calculaMedia(float Valor)
{
if (amostrasValor < tAmostras)
{
aValor[amostrasValor] = Valor;
amostrasValor++;
return Valor;
}
else
{
float media = aValor[0];
for (int i = 1; i < tAmostras; i++)
{
media = media + aValor[i];
aValor[i - 1] = aValor[i];
}
aValor[tAmostras - 1] = Valor;
media = media / tAmostras;
return media;
}
}

Você pode modificar, para ele calcular a média, antes de completar o array, é só modificar na função, eu retorno o valor lido, até completar e começar a fazer a média.

Opa!!! Valeu pessoal. Agradeço a TODOS pela ajuda.

Chegando em casa vou botar para funcionar.

OBRIGADO

Funcionou?

Pelo que entendi o teu problema é manter uma média das últimas n leituras. Pra isso vc precisa ter essas leituras armazenadas em alguma estrutura e para este caso, a estrutura mais eficiente seria o buffer circular. Isso te permitiria usar um array para as medidas e nunca precisar percorrer o array seja pra adicionar ou retirar medidas ou mesmo pra calcular a média atual. Com o algoritmo certo, seria só uma questão de retirar a medida mais antiga da média e acrescentar a mais recente.

Um buffer circular é bem simples de operar e é muito eficiente. Abaixo to postando o código básico de um buffert circular para armazenar 10 valores inteiros. Eu faria isso usando uma classe, mas usando funções "soltas" acho que é mais facil de entender.

Note que em nenhum momento o array precisa ser percorrido. Esse detalhe pode não fazer tanta diferença com um buffer de 10 posições, mas quando o buffer tem milhares de itens isso faz muita diferença no desempenho do programa.

// Tamanho do buffer circular
#define buffSize 10

// buffer circular
int cBuf[buffSize];

// variáveis de controle
int firstItem = 0;  // indice do primeiro item (o mais antigo)
int nextPos = 0;    // índice da próxima posição livre (onde será colocado o próximo item)
int items = 0;      // quantidade atual de itens no buffer
int itemsSum = 0;   // soma de todos os itens

// zera o buffer
void clearBuff()
{
  firstItem = 0;  
  nextPos = 0;    
  items = 0;      
  itemsSum = 0;   
}

// Retira o primeiro item do buffer e da soma
// retorna o item retirado
int getFirst()
{

  if(!items) return 0;  // Se o buffer está vazio retorna sem fazer nada

  // recupera o item mais antigo
  int item = cBuf[firstItem];
  // retira ele da soma geral
  itemsSum-= item;            
  // atualiza o índice do primeiro item usando incremento circular
  firstItem= (firstItem+1) % buffSize;
  // atualiza o contador de itens;
  items--;
  // retorna o dito cujo
  return item;                
}

// adiciona um item no final do buffer e na soma geral
void addItem(int item)
{
  if(items>=buffSize) // se o buffer está cheio
  {
     getFirst(); // remove o item mais antigo
  }
  // armazena o novo item no buffer
  cBuf[nextPos]= item;
  // atualiza a proxima posição livre
  nextPos= (nextPos+1) % buffSize; // incremento circular: volta a zero qdo chega a 9
  // acrescenta o item na soma geral
  itemsSum+= item; //
  // atualiza o contador de itens;
  items++;
}

// retorna a média atual
float bufMedia()
{
  if(!items)  // nenhum item no buffer
    return 0;
  else
    return (float)itemsSum/items; // média
}

Eu preciso de algo semelhante:

       Faço a primeira leitura do sensor e após a segunda leitura, ele calcula a média entre as duas. Após a terceira leitura, ele calcula a média entre a terceira leitura e a média anterior... isso até um determinado horário (possuo RTC), depois ele zera as médias e começa tudo de novo a partir da próxima leitura. Isso é possível???

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço