(Nov-2015) Como saber si AVANZAMOS o RETROCEDEMOS con Acelerometro MPU-6050 ????

Hola, soy de Argentina, estoy haciendo unas pruebas con el Acelerometro MPU-6050. Pero tengo un problema al procesar los datos obtenidos de las lecturas Raw del Eje X, solo del acelerometro. Lo que necesito saber es si el objeto que le instalo el acelerometro esta avanzando, retrocediendo o esta en reposo. La cuestion es que con este codigo logo que me diga si esta avanzando, retrocediendo o reposo pero no lo mantiene en el tiempo. Cuando veo que el objeto avanza me dice avanzando 1 sola vez y luego me dice que esta en reposo. ALGUIEN PODRÍA POR FAVOR AYUDARME A VER CUÁL ES EL PROBLEMA ???

Codigo:

void loop()
{

 Wire.beginTransmission(MPU);
 Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
 Wire.endTransmission(false);
 //Solicita os dados do sensor
 Wire.requestFrom(MPU,14,true);  
 //Armazena o valor dos sensores nas variaveis correspondentes
 AcX=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
 AcY=Wire.read()<<8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
 AcZ=Wire.read()<<8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
 Tmp=Wire.read()<<8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
 GyX=Wire.read()<<8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
 GyY=Wire.read()<<8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
 GyZ=Wire.read()<<8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
 
//Muestro el valor de X y X Anterior para ver los valores a medida q se avanza o retrosede o reposo.
Serial.print("Acel. X = "); Serial.print(AcX); Serial.print(" "); Serial.print(AcXAnt); Serial.print(" ");
 
if (AcX > AcXAnt+700) {
   Serial.print("ACELERANDO");
 }
 else if (AcX < AcXAnt-700) {
   Serial.print("FRENANDO");
 }
 else {
 Serial.print("REPOSO");
 }

 AcXAnt=AcX;
}

El "problema" es que el acelerómetro como su nombre lo indica mide la aceleración, por lo que una vez que dejas de acelerar y mantienes una velocidad "constante", los valores vuelven a un estado "normal", (cercanos al 0)

Una forma de solucionarlo sería no cambiar de el estado "Acelerando" hasta que detecte que se está frenando, eso lo puedes lograr con una bandera.

int acelerando = 0;

void loop()
{

  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  //Solicita os dados do sensor
  Wire.requestFrom(MPU,14,true);  
  //Armazena o valor dos sensores nas variaveis correspondentes
  AcX=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  
 //Muestro el valor de X y X Anterior para ver los valores a medida q se avanza o retrosede o reposo.
 Serial.print("Acel. X = "); Serial.print(AcX); Serial.print(" "); Serial.print(AcXAnt); Serial.print(" ");
  
 if (AcX > AcXAnt+700 || acelerando == 1) {
    Serial.print("ACELERANDO");
    acelerando = 1;
  }
  else if (AcX < AcXAnt-700) {
    Serial.print("FRENANDO");
    acelerando = 0;
  }
  else {
  Serial.print("REPOSO");
  }
 
  AcXAnt=AcX;
}

PD: edita tu comentario y agrega tu código entre las etiquetas de código, si tienes alguna duda consulta en las normas del foro.

Bueno esto es lo mejor que encontré para TU problema.
FreeIMU/MPU-6050 Drift Free AHRS and Motion Detection
Usando unos algoritmos pudieron inferir si el objeto esta o no en movimiento.

Intenta leer las normas del foro y editar ese código que has posteado sin etiquetas.
Seleccionas todo y usas </> en la barra del editor y quedará como debe.

Hola "gepd" y "surbyte", desde ya muchas gracias por su respuesta. Les cuento que ya intente esta parte del codigo acoplarla al q habia hecho y hace lo mismo. Por otro lado ya probé también con: FreeIMU/MPU-6050 Drift Free AHRS and Motion Detection, y hace lo mismo. O sea, es evidente que el Mpu6050 es espectacular como giroscopio, pero como acelerometro para saber solamente si nos desplazamos por alguno de los 3 ejes, no funciona. El único sketch que se acerca a que funcione bien (pero solo para gisroscopio) es el de "Como configurar MPU 6050 Arduino" que proporciona hasta el .pde de processing con un avioncito 3d que se mantiene de maravilla incluso en el estado de reposo sin ningún Drift. Obviamente calibrandolo antes con el .ino de calibración. Les mando un saludo y sigo buscando una forma precisa para poder usar solo el acelerometro. Muchas gracias!.

PD: YA MODIFIQUE EL ORIGINAL.

Porque no encaras el problema con otra óptica.
Ejemplo. Suponé que usas Enconders en las ruedas, sabrás entonces si avanza, retroce, o está en reposo.
Claro que es agregar algo más y tal vez tu objetivo era hacerlo con el MPU.
El problema que veo es que algo que mide aceleración X,Y,Z no tiene forma muy clara de decirte, estoy detenido, estoy avanzando, estoy retrocediendo.
Aceleración es 1era derivada de Velocidad respecto del tiempo y la 2da de la distancia respecto del tiempo.
Pretender determinar la distancia si es positiva, negativa o 0. Eso implica una doble integración en el tiempo.
Si el giroscopio te dice Ax = 0 solo te dice que la Vx es constante pero no sabes nada de la dx.
Necesitas algun dato extra creo yo para determinar lo que buscas.