  * @version 0.12 'Teste Leitura multiplos sensores'
  */
 
+// Bibliotecas ---------------------------------------------------------------------------------
+#include <math.h>
 
+// Constantes ----------------------------------------------------------------------------------
+
+// Debug
+#define LED 13
+#define TIME_BLINK 200
+
+// Configuração Pinos
 #define PIN_LM35      A0
 #define PIN_MTK01     A1
+
 #define INTERVAL      500  //ms
 #define SIZE_BUFFER   10
+#define SIZE_BUFFER_F 10   // Parâmentro Filtro Média Móvel
+#define ALPHA         0.8  // Parâmentro Filtro Média Móvel Ponderada
 
+// Variáveis Globais  --------------------------------------------------------------------------
+
+// Timer
 unsigned long lasttime = millis();
 
-int bufferLM35[SIZE_BUFFER];
-int bufferMTK01[SIZE_BUFFER];
-int k;
-int i;                        // Contador Leituras
+// Contadores
+int k;                            // Buffer
+int index;                        // Absoluto
+
+// Buffer Dados Brutos
+float bufferLM35[SIZE_BUFFER];
+float bufferMTK01[SIZE_BUFFER];
+
+// Buffer Dados Filtrados
+float bufferAvgFilter[SIZE_BUFFER];
+float bufferMvAvgFilter[SIZE_BUFFER];
+float bufferMvAvgExpFilter[SIZE_BUFFER];
+
+float pMvAvgExpFilter[4]; // Pesos Filtro Média Móvel Ponderada
+
+// Setup ---------------------------------------------------------------------------------
 
 void setup() {
+  // Prepara Led para Debug
+  pinMode(LED, OUTPUT);
+  digitalWrite(LED,LOW);
+  
   // Inicia Porta Serial
   Serial.begin(57600);
 

    lasttime = millis();
    
    // Ler o valor dos sensores
    int rawTemp1 = analogRead(PIN_LM35);
    int rawTemp2 = analogRead(PIN_MTK01);

    // Filtragem
    bufferLM35[k] = rawTemp1;
    bufferMTK01[k] = rawTemp2;

    int filteredData = filterMovingAverenge(bufferLM35,k);

    // Envia via Serial
    Serial.print(k);
    Serial.print(' ');
    Serial.print(rawTemp1);
    Serial.print(' ');
    Serial.println(filteredData);

    // Incrementa Contadores
    i = i+1;
    k = (k<(SIZE_BUFFER-1))?k+1:0;
  }
}

/**
 * Filtro de Média Móvel com tamanho definido por SIZE_BUFFER
 * 
 * @author Rafael Lima
 */
int filterMovingAverenge(int buffer[],int i){
  // Calcula Endereços
  int a1 = (i>0)?i-1:SIZE_BUFFER-1;
  int a2 = (i<(SIZE_BUFFER-1))?i+1:0; // O próximo termo é igual o i-n por ser um buffer circular

  // Aplica Filtro
  int filteredData = buffer[a1] + (buffer[i]-buffer[a2])/SIZE_BUFFER;
  
  return filteredData;
}


  pinMode(PIN_LM35,INPUT);
  pinMode(PIN_MTK01,INPUT);

  // Zera Buffers
  for(k=0;k<SIZE_BUFFER;k++){
    bufferLM35[k] = 0;
    bufferMTK01[k] = 0;
    bufferAvgFilter[k] = 0;
    bufferMvAvgFilter[k] = 0;
    bufferMvAvgExpFilter[k] = 0;
  }

  blink(4);

  // Zera Contadores
  index=1;
  k=0;

  // Calcula Pesos Filtro Média Móvel Ponderada
  pMvAvgExpFilter[0] = pow(ALPHA,3);
  pMvAvgExpFilter[1] = (1-ALPHA)*pow(ALPHA,2);
  pMvAvgExpFilter[2] = (1-ALPHA)*pow(ALPHA,1);
  pMvAvgExpFilter[0] = (1-ALPHA);
}

// Loop ----------------------------------------------------------------------------------

void loop() {
  // Loop com período fixo de Amostragem
