Pfff je suis perdu, malgré tous les forums que j'ai pu lire en anglais où on y parle beaucoup d'adresse I2C 0x69 et 0x68.
Pour fixer l'adresse I2C du composant en 0x68 ou 0x69 ça dépend de comment vous câblez la broche AD0 sur votre module. Cette broche pilote le bit de poids faible de l'adresse du module:
- si la broche AD0 est LOW, l'adresse est
0b0110100[color=blue]0[/color]
(bin) soit 0x68
(hex)
- si la broche AD0 est HIGH, l'adresse est
0b0110100[color=red]1[/color]
(bin) soit 0x69
(hex)
--> Si vous laissez la broche en l'air on est à l'adresse par défaut en 0x68 et les librairies utilisent cette adresse donc il n'y a rien de particulier à faire.
cette adresse est à utiliser pour les discussions en I2C avec le module.
Généralement on passe par des librairies pour parler au PMU6050 et une des plus aboutie est la bibliothèqueI2Cdev de Jeff Rowberg (qui contient un module MPU6050.h).
Vous téléchargez son zip, et vous copiez dans le répertoire des libraries standard le sous répertoire i2cdevlib/Arduino/I2Cdev
ainsi que i2cdevlib/Arduino/MPU6050
Cette librairie permet d'utiliser la puce de "fusion matérielle" (DMP = Digital Motion Processor ) des données de l'accéléromètre et du gyroscope pour compenser des dérives, ce qui permet d'obtenir de bons angles d'Euler ou de roulis, tangage, lacet - (YPR en anglais pour Yaw, Pitch, Roll)
Ce code (un peu ceinture brettelle, issus de diverses interactions de code pris sur internet, principalement adapté des exemples de Jeff avec des modifications pour ne pas saturer la pile FIFO) permet de vous afficher les angles de roulis, tangage, lacet.
#include "Wire.h"
#include "I2Cdev.h" //copier https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/I2Cdev dans le répertoire des librairies
#include "MPU6050_6Axis_MotionApps20.h" //copier https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 dans le répertoire des librairies
MPU6050 mpu; // <-- si vous avez connecté AD0 sur LOW ou si la broche n'est pas connectée (valeur par défaut 0x68)
// MPU6050 mpu(0x69); // <-- si vous avez connecté AD0 sur HIGH
const float RADIANS_TO_DEGREES = 180.0 / M_PI;
// MPU control/status vars
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer, doit être plus grand que packetSize
// variables d'orientation/mouvement
Quaternion q;
VectorFloat gravity;
float ypr[3];
float euler[3];
float lastYaw;
float lastPitch;
float lastRoll;
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
mpuInterrupt = true;
}
void setup() {
uint8_t dmpStatus;
Wire.begin();
Serial.begin(115200);
mpu.initialize();
if (!mpu.testConnection()) {
Serial.println(F("pas de MPU"));
while (true);
}
if (dmpStatus = mpu.dmpInitialize()) {
Serial.print(F("Erreur DMP #"));
Serial.println(dmpStatus);
while (true);
}
mpu.setDMPEnabled(true);
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
packetSize = mpu.dmpGetFIFOPacketSize(); // 42
}
void loop()
{
if (mpuInterrupt || fifoCount >= packetSize) { // on a des données
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
fifoCount = mpu.getFIFOCount();
if ((mpuIntStatus & 0x10) || fifoCount == 1024) { // test si overflow (ne devrait pas arriver si on dépile vite la FIFO)
mpu.resetFIFO(); // reset
} else if (mpuIntStatus & 0x02) { // verifie si on a le "DMP data ready interrupt" (this should happen frequently)
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); // on s'assure que le buffer est suffisant, ça devrait être le cas
mpu.getFIFOBytes(fifoBuffer, packetSize); // read a packet from FIFO fifoBuffer
fifoCount -= packetSize;
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
float currentYaw = ypr[0] * RADIANS_TO_DEGREES; // yaw: (about Z axis)
float currentPitch = -ypr[1] * RADIANS_TO_DEGREES; // pitch: (nose up/down, about Y axis)
float currentRoll = ypr[2] * RADIANS_TO_DEGREES; // roll: (tilt left/right, about X axis)
if ((abs(currentYaw - lastYaw) > 1) || (abs(currentPitch - lastPitch) > 1) || (abs(currentRoll - lastRoll) > 1)) {
Serial.print(F("YPR\t"));
Serial.print(currentYaw, 0);
Serial.write("\t");
Serial.print(currentPitch, 0);
Serial.write("\t");
Serial.println(currentRoll, 0);
lastYaw = currentYaw;
lastPitch = currentPitch;
lastRoll = currentRoll;
}
}
}
}
Il faut éviter tout ce qui génère bcp d'interruptions (donc print) car ça peut mettre un peu le bazar sur la façon dont leur FIFO fonctionne et ensuite avoir des conséquences sur le bus I2C qui font que la librairie Wire se bloque...
Vous aurez à tenir compte du bug reporté dans cette file => rajoutez un 'L' après le 16384 dans le fichier MPU6050/MPU6050_6Axis_MotionApps20.h en ligne 522
data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1]
- (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (2 * 16384L); // corrected 16384L to not overflow
il y aura pas mal de warning à la compilation que vous pourrez ignorer.