MPU6050 : Calibration et mise à zéro

Bonjour à tous !

Dans le cadre d'un projet j'utilise un MPU6050 pour obtenir un angle d'inclinaison sur l'axe x et y.

A l'aide de Kalman Filter j'obtiens des résultats intéressants, quand je pose le module le plus possible à l'horizontal les valeurs oscille entre -2 et +2°.

Vu que ce module sera monté dans un véhicule il ne pourra pas être fixé exactement à l'horizontal.

Pour obtenir un 0° sur les axes X et Y puis-je simplement déduire du résultat les quelques degrés de différences ?

Merci pour votre aide.

J'aurai tendance à dire que oui, calibre bien ton MPU à plat et mets le dans ta voiture. Releve ce qu'il t'affiche une fois en place garé sur une surface plane et applique les valeurs en correctif

Par contre je serai curieux d'avoir ton code, je fais mumuse en ce moment avec un MPU-6050 aussi

Jambe: Releve ce qu'il t'affiche une fois en place garé sur une surface plane et applique les valeurs en correctif

Tres bonne solution.

Merci pour vos réponses !

Le code que j'utilise est dans la librairie disponible via le lien de mon premier message.

Au lieu d'afficher les résultats dans le port série je les stocks dans des variables.

Je remonte ce post car j'ai quelques problème avec mon MPU-6050.

Je rappel qu'il est posé sur une moto.

A l'arrêt tout fonctionne très bien, mais dés que je met le moteur en marche les valeurs s'affolent et deviennent incohérentes.

Les vibrations fausses donc les résultats...

En plus du meilleure isolation entre le chassis et le module, comment puis-je les diminuer du côté de mon software ?

elriri: Je remonte ce post car j'ai quelques problème avec mon MPU-6050.

Je rappel qu'il est posé sur une moto.

A l'arrêt tout fonctionne très bien, mais dés que je met le moteur en marche les valeurs s'affolent et deviennent incohérentes.

Les vibrations fausses donc les résultats...

En plus du meilleure isolation entre le chassis et le module, comment puis-je les diminuer du côté de mon software ?

Il faut filtré le bruit générer par le mécanisme du moteur, mais le problème c'est que le filtre a implanter coté soft est numérique donc compliqué a mettre en oeuvre.

Edit : c'est liens peuvent être intéressants http://playground.arduino.cc/Main/DigitalSmooth http://playground.arduino.cc/Code/Filters

car mes données vont sur un device android, c'est peux être plus simple de filtrer mes données en java.

Edit : Je vais commencer par échantillonner une dizaine de mesures pour en faire une moyenne et voir le résultat.

Edit 2 : Si je baisse la sensibilité du MPU6050, mes valeurs devraient être plus plates non ?

BOn finalement, le MPU6050 semble équipé d'un Low Pass Filter reste à savoir comment le configurer.

Je reviens toujours avec le même problème, malgré l’activation du Low Pass Filter, mes résultats moteurs allumé sont correct mais uniquement à l’arrêt.

Dés que je commence à rouler l’angle indiqué n’est pas correct

Isolé le module avec un blindage relié à la masse, pourrait-il m’aider ?

Monter le capteur sur un pad d’absorption serait bien utile.

L'activation du low pass filter est certes utile mais elle ne servira a rien tant que la fréquence de coupure ne sera pas la bonne, essaye de jouer avec les valeurs du registre DLPF_CFG.

Une autre solution est de passer un coup de FFT lorsque les moteurs sont allumé, grace a fourier du pourra determiner la ou les frequences a éliminer facilement c'est pas dur avec un capteur analogique, mais pour du numerique.. :confused:

L'ensemble du montage est déjà installé sur une mousse type "tapis de gym", puis inséré dans un boitier en plastique, il n'y a aucune liaison mécanique (vis) entre le boitier et le module mais ce dernier ne bouge absolument pas dans le boitier.

J'ai essayé quelques valeurs du LPF je vais essayer les autres.

Pour ce qui est de déterminer les fréquences ce n'est pas envisageable, mon montage devant être compatible avec tous les types de véhicules, architecture moteur, cylindrée, etc...

En tt cas merci pour ton aide !

J’ai essayé toutes les valeurs possibles du LPF, j’ai un angle stable moteur allumé mais moto statique uniquement avec le mode 5Hz.

En dynamique, les valeurs affichées ne sont pas les bonnes mais ne s’affiche de façon incohérente, on saute pas de 0° à 68° par exemple. A vrai dire, je ne dépasse jamais les 12/15° alors qu’au minimum je devrais avoir des valeurs avoisinant les 30/40° en virage ou rond point.

J’ai l’impression que le capteur est perdu si la moto se déplace, comme si ses repères n’étaient plus les bons.

Une fois le test terminé quand je remet la moto à la même position qu’au départ j’ai une différence de +3° (dérive ?).

Juste à titre d’informations voila ma fonction qui calcul l’angle :

void getAngle(){
  /* Update all the values */
  while (i2cRead(0x3B, i2cData, 14));
  accX = ((i2cData[0] << 8) | i2cData[1]);
  accY = ((i2cData[2] << 8) | i2cData[3]);
  accZ = ((i2cData[4] << 8) | i2cData[5]);
  tempRaw = (i2cData[6] << 8) | i2cData[7];
  gyroX = (i2cData[8] << 8) | i2cData[9];
  gyroY = (i2cData[10] << 8) | i2cData[11];
  gyroZ = (i2cData[12] << 8) | i2cData[13];

  vehicule_gforce_x = accX/16384;
  vehicule_gforce_y = accY/16384;
  vehicule_gforce_z = accZ/16384;
  double dt = (double)(micros() - timer) / 1000000; // Calculate delta time
  timer = micros();

  // Source: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf eq. 25 and eq. 26
  // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
  // It is then converted from radians to degrees
#ifdef RESTRICT_PITCH // Eq. 25 and 26
  double roll  = atan2(accY, accZ) * RAD_TO_DEG;
  double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
#else // Eq. 28 and 29
  double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
  double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
#endif

  double gyroXrate = gyroX / 131.0; // Convert to deg/s
  double gyroYrate = gyroY / 131.0; // Convert to deg/s

#ifdef RESTRICT_PITCH
  // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
  if ((roll < -90 && kalAngleX > 90) || (roll > 90 && kalAngleX < -90)) {
    kalmanX.setAngle(roll);
    compAngleX = roll;
    kalAngleX = roll;
    gyroXangle = roll;
  } else
    kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter

  if (abs(kalAngleX) > 90)
    gyroYrate = -gyroYrate; // Invert rate, so it fits the restriced accelerometer reading
  kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt);
#else
  // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
  if ((pitch < -90 && kalAngleY > 90) || (pitch > 90 && kalAngleY < -90)) {
    kalmanY.setAngle(pitch);
    compAngleY = pitch;
    kalAngleY = pitch;
    gyroYangle = pitch;
  } else
    kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt); // Calculate the angle using a Kalman filter

  if (abs(kalAngleY) > 90)
    gyroXrate = -gyroXrate; // Invert rate, so it fits the restriced accelerometer reading
  kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter
#endif

  gyroXangle += gyroXrate * dt; // Calculate gyro angle without any filter
  gyroYangle += gyroYrate * dt;
  //gyroXangle += kalmanX.getRate() * dt; // Calculate gyro angle using the unbiased rate
  //gyroYangle += kalmanY.getRate() * dt;

  compAngleX = 0.93 * (compAngleX + gyroXrate * dt) + 0.07 * roll; // Calculate the angle using a Complimentary filter
  compAngleY = 0.93 * (compAngleY + gyroYrate * dt) + 0.07 * pitch;

  // Reset the gyro angle when it has drifted too much
  if (gyroXangle < -180 || gyroXangle > 180)
    gyroXangle = kalAngleX;
  if (gyroYangle < -180 || gyroYangle > 180)
    gyroYangle = kalAngleY;

  vehicule_angle_x = kalAngleX;
  vehicule_angle_y = kalAngleY;

  delay(2);
}