MPU6050 Arduino : accéléromètre, gyroscope et angle d'inclinaison
MPU6050 avec Arduino : câblage, adresse I2C, valeurs brutes, calibration, inclinaison avec atan2 et filtre complémentaire, bibliothèque Adafruit, ESP32 et Pico.
Le MPU6050 réunit dans une seule petite puce un accéléromètre 3 axes et un gyroscope 3 axes ; c'est le capteur de mouvement le plus utilisé dans les projets Arduino. Il mesure de combien la carte est inclinée, dans quel sens et à quelle vitesse elle tourne, et si elle est secouée ou en train de tomber. Robots auto-équilibrés, drones, stabilisateurs de caméra (gimbals), podomètres et jeux pilotés par le mouvement sont construits avec ce capteur. Le MPU6050 se branche sur l'Arduino avec seulement quatre fils, en I2C.
Dans cet article, tu vas apprendre pas à pas comment fonctionne le MPU6050, ses axes et ses valeurs brutes, le câblage I2C, la lecture avec et sans bibliothèque, la calibration, le calcul de l'angle d'inclinaison avec atan2 et le filtre complémentaire, qui combine les points forts des deux capteurs. Ensuite, nous construirons avec un ESP32 une alarme qui détecte les chutes et écrirons du code MicroPython pour le Raspberry Pi Pico.

Qu'est-ce que le MPU6050 et comment fonctionne-t-il ?
Le MPU6050, fabriqué par InvenSense (aujourd'hui TDK), est une IMU, c'est-à-dire une centrale inertielle. À l'intérieur se trouvent de minuscules structures mécaniques en silicium (MEMS). L'accéléromètre mesure le déplacement d'une petite masse suspendue à des ressorts sous l'effet d'une accélération ; comme il perçoit la gravité même au repos, un capteur posé à plat sur la table indique environ 1 g (9,81 m/s²) sur l'axe Z, ce qui te permet de calculer son inclinaison par rapport au sol. Le gyroscope mesure la vitesse angulaire, autrement dit de combien de degrés par seconde le capteur tourne, grâce à la force de Coriolis qui agit sur des structures vibrantes. Les mesures sont converties en nombres par des ADC 16 bits intégrés à la puce et lues en I2C. La puce contient aussi un capteur de température et un processeur de mouvement numérique (DMP) capable de prendre en charge les calculs d'orientation.
| Caractéristique | Valeur |
|---|---|
| Capteurs | Accéléromètre 3 axes + gyroscope 3 axes + température |
| Plage de l'accéléromètre | ±2, ±4, ±8, ±16 g |
| Plage du gyroscope | ±250, ±500, ±1000, ±2000 °/s |
| Résolution | 16 bits (de -32768 à 32767 par axe) |
| Communication | I2C, jusqu'à 400 kHz |
| Adresse I2C | 0x68 (AD0 à GND) ou 0x69 (AD0 à 3,3 V) |
| Tension de la puce | 2,375–3,46 V (la carte GY-521 accepte 3,3–5 V) |
| Consommation | Environ 3,9 mA (5 µA en veille) |
| Bonus | DMP, FIFO de 1024 octets, interruption de mouvement, I2C auxiliaire pour un capteur externe |
Axes, valeurs brutes et sensibilité
Les flèches sur la carte indiquent les axes X et Y ; l'axe Z est perpendiculaire à la carte et pointe vers le haut. Le capteur fournit pour chaque axe un nombre signé sur 16 bits. Pour convertir cette valeur brute en unité physique, tu la divises par la sensibilité de la plage choisie. Par exemple, dans la plage par défaut de ±2 g, une valeur brute de 16384 correspond à 1 g ; avec le capteur posé sur la table, tu liras az ≈ 16384 et ax, ay ≈ 0. Pour le gyroscope, dans la plage de ±250 °/s, une valeur brute de 131 correspond à une rotation de 1 degré par seconde. Une plage plus large mesure des mouvements plus brusques mais affiche les petites variations plus grossièrement : choisis donc la plage la plus étroite qui suffit à ton projet.
| Réglage | Plage de l'accéléromètre | LSB/g | Plage du gyroscope | LSB/(°/s) |
|---|---|---|---|---|
| 0 | ±2 g | 16384 | ±250 °/s | 131 |
| 1 | ±4 g | 8192 | ±500 °/s | 65,5 |
| 2 | ±8 g | 4096 | ±1000 °/s | 32,8 |
| 3 | ±16 g | 2048 | ±2000 °/s | 16,4 |
La puce mesure aussi la température : °C = valeur brute / 340 + 36,53. Cette valeur reflète davantage la température de la puce elle-même que celle de la pièce, mais comme le zéro du gyroscope varie avec la température, elle sert aux corrections avancées.
Câblage du MPU6050 : Arduino Uno, ESP32 et Pico
| Broche du MPU6050 | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 3V3 | 3V3(OUT) |
| GND | GND | GND | GND |
| SCL | A5 | GPIO 22 | GP5 |
| SDA | A4 | GPIO 21 | GP4 |
| AD0 | Non connectée (adresse 0x68) | Non connectée (adresse 0x68) | Non connectée (adresse 0x68) |
| INT | D2 (facultatif) | N'importe quel GPIO (facultatif) | N'importe quelle broche GP (facultatif) |
| XDA, XCL | Non branchées | Non branchées | Non branchées |
Comme la carte GY-521 possède un régulateur 3,3 V, tu peux relier VCC à la broche 5V de l'Uno. La broche AD0 est tirée à GND sur la carte par une résistance de 4,7 kΩ : l'adresse est donc 0x68 si tu la laisses libre ; pour utiliser deux MPU6050 sur le même bus, relie l'AD0 de l'un d'eux à 3,3 V afin de passer son adresse à 0x69. La broche INT signale qu'une nouvelle donnée est prête ou qu'un mouvement a été détecté ; pour des projets simples, inutile de la brancher. Après le câblage, prends l'habitude de vérifier avec un scanner I2C que le capteur est bien détecté ; tu verras comment dans Écran LCD I2C.
Démarrage rapide avec une bibliothèque : Adafruit MPU6050
- Ouvre le Gestionnaire de bibliothèques de l'Arduino IDE et cherche Adafruit MPU6050.
- Quand l'installation te demande les dépendances, choisis Install all : Adafruit Unified Sensor et Adafruit BusIO seront installées aussi.
- Branche le capteur comme dans le tableau, téléverse le code ci-dessous et ouvre le Moniteur série à 115200 bauds.
- Ouvre le Traceur série depuis le menu Outils pour suivre les six axes en graphiques en direct ; les courbes d'accélération changent quand tu inclines la carte, celles du gyroscope quand tu la fais tourner.
1#include <Wire.h>
2#include <Adafruit_MPU6050.h>
3#include <Adafruit_Sensor.h>
4
5Adafruit_MPU6050 mpu;
6
7void setup() {
8 Serial.begin(115200);
9 if (!mpu.begin()) { // varsayılan adres 0x68 / default address 0x68
10 Serial.println("MPU6050 bulunamadi / not found");
11 while (true) delay(10);
12 }
13 mpu.setAccelerometerRange(MPU6050_RANGE_4_G); // ±4 g
14 mpu.setGyroRange(MPU6050_RANGE_500_DEG); // ±500 °/s
15 mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); // titreşimi süz / filter out vibration
16}
17
18void loop() {
19 sensors_event_t a, g, t;
20 mpu.getEvent(&a, &g, &t);
21 Serial.print("ax:"); Serial.print(a.acceleration.x); // m/s²
22 Serial.print(" ay:"); Serial.print(a.acceleration.y);
23 Serial.print(" az:"); Serial.print(a.acceleration.z);
24 Serial.print(" gx:"); Serial.print(g.gyro.x); // rad/s
25 Serial.print(" gy:"); Serial.print(g.gyro.y);
26 Serial.print(" gz:"); Serial.print(g.gyro.z);
27 Serial.print(" T:"); Serial.println(t.temperature); // °C
28 delay(100);
29}La bibliothèque Adafruit fournit directement les résultats en unités physiques : accélération en m/s², vitesse angulaire en rad/s et température en °C. Pour convertir une valeur du gyroscope en degrés par seconde, il suffit de la multiplier par 57,3. Le filtre passe-bas interne choisi avec setFilterBandwidth réduit le bruit des vibrations : 21 Hz est un bon point de départ pour des mouvements de la main, et pour capter des chocs brefs, choisis 94 ou 260 Hz. Au démarrage, la bibliothèque lit le registre d'identité de la puce (WHO_AM_I) et begin() renvoie false s'il ne vaut pas 0x68.
Lecture sans bibliothèque, calibration et angle d'inclinaison
Les bibliothèques simplifient la vie, mais lire directement les registres est très formateur pour comprendre ce qui se passe dans le capteur. Le MPU6050 démarre en mode veille : il faut d'abord le réveiller en écrivant 0 dans le registre 0x6B (PWR_MGMT_1). Tu lis ensuite 14 octets à partir de l'adresse 0x3B : 6 octets d'accélération, 2 de température et 6 de gyroscope. Chaque valeur tient sur deux octets, l'octet de poids fort en premier. Voici les principaux registres utilisés dans le code et à connaître :
| Registre | Adresse | Rôle |
|---|---|---|
| SMPLRT_DIV | 0x19 | Diviseur de la fréquence d'échantillonnage |
| CONFIG | 0x1A | Filtre passe-bas interne (DLPF) |
| GYRO_CONFIG | 0x1B | Plage du gyroscope (±250 … ±2000 °/s) |
| ACCEL_CONFIG | 0x1C | Plage de l'accéléromètre (±2 … ±16 g) |
| ACCEL_XOUT_H | 0x3B | Adresse de début des mesures (14 octets) |
| PWR_MGMT_1 | 0x6B | Veille et source d'horloge ; écrire 0 le réveille |
| WHO_AM_I | 0x75 | Identité ; un vrai MPU6050 renvoie 0x68 |
Sur un capteur immobile, la seule force que voit l'accéléromètre est la gravité. En regardant comment elle se répartit sur les axes, tu obtiens deux angles : le roulis autour de l'axe X, roll = atan2(ay, az), et le tangage autour de l'axe Y, pitch = atan2(−ax, √(ay² + az²)). Contrairement à l'arc tangente classique, atan2 donne le bon signe dans les quatre quadrants et ne divise pas par zéro quand az tend vers zéro. Par exemple, si tu lis ay = 8192 et az = 14189, roll = atan2(8192, 14189) ≈ 30°. La rotation autour de l'axe Z (lacet, ou yaw) reste en revanche invisible pour l'accéléromètre, car elle ne change pas la répartition de la gravité sur les axes.
Les deux capteurs ont un point faible. L'accéléromètre est juste sur le long terme mais très bruité pendant les mouvements et les vibrations, car il mesure en plus de la gravité l'accélération propre du mouvement. Le gyroscope est lisse à court terme, mais pour obtenir un angle tu additionnes la vitesse angulaire dans le temps (angle += vitesse × dt), et même un petit décalage s'accumule et fait dériver lentement l'angle. Le filtre complémentaire combine les deux : angle = 0,98 × (angle + gyro × dt) + 0,02 × angle de l'accéléromètre. Il fait confiance au gyroscope à court terme et à l'accéléromètre à long terme. À 100 Hz (dt = 0,01 s), ces coefficients donnent une constante de temps d'environ une demi-seconde : τ = 0,98 × 0,01 / 0,02 = 0,49 s.
La calibration compte au moins autant que le filtre. Même un gyroscope parfaitement immobile peut afficher un décalage constant (offset) de quelques °/s ; si tu ne le corriges pas, l'angle calculé dérive de dizaines de degrés en quelques secondes. Le code ci-dessous fait la moyenne de 500 lectures au démarrage, capteur immobile, puis la soustrait de chaque lecture suivante. Pendant la calibration, pose la carte sur une surface plane et n'y touche pas ; observe ensuite les courbes roll, pitch et yaw dans le Traceur série.
1#include <Wire.h>
2
3const int MPU_ADDR = 0x68; // AD0 GND'de ya da boşta / AD0 to GND or floating
4const float GYRO_LSB = 131.0; // ±250 °/s aralığında 1 °/s / 1 °/s at the ±250 °/s range
5const float ALPHA = 0.98; // tamamlayıcı filtre katsayısı / complementary filter weight
6
7int16_t ax, ay, az, tempRaw, gx, gy, gz;
8float gxOff = 0, gyOff = 0, gzOff = 0; // jiroskop sapmaları / gyro offsets
9float roll = 0, pitch = 0, yaw = 0;
10unsigned long lastMicros;
11
12void writeReg(uint8_t reg, uint8_t val) {
13 Wire.beginTransmission(MPU_ADDR);
14 Wire.write(reg);
15 Wire.write(val);
16 Wire.endTransmission();
17}
18
19int16_t read16() {
20 uint8_t hi = Wire.read(); // önce yüksek bayt / high byte first
21 uint8_t lo = Wire.read();
22 return (int16_t)(((uint16_t)hi << 8) | lo);
23}
24
25void readMPU() {
26 Wire.beginTransmission(MPU_ADDR);
27 Wire.write(0x3B); // ACCEL_XOUT_H
28 Wire.endTransmission(false); // hattı bırakma, tekrar başlat / repeated start
29 Wire.requestFrom(MPU_ADDR, 14); // ivme 6 + sıcaklık 2 + jiroskop 6 bayt / accel 6 + temp 2 + gyro 6 bytes
30 ax = read16(); ay = read16(); az = read16();
31 tempRaw = read16();
32 gx = read16(); gy = read16(); gz = read16();
33}
34
35void calibrateGyro() {
36 const int N = 500;
37 long sx = 0, sy = 0, sz = 0;
38 for (int i = 0; i < N; i++) {
39 readMPU();
40 sx += gx; sy += gy; sz += gz;
41 delay(3);
42 }
43 gxOff = sx / (float)N;
44 gyOff = sy / (float)N;
45 gzOff = sz / (float)N;
46}
47
48void setup() {
49 Serial.begin(115200);
50 Wire.begin();
51 Wire.setClock(400000); // 400 kHz hızlı mod / 400 kHz fast mode
52 writeReg(0x6B, 0x00); // PWR_MGMT_1: uykudan uyandır / wake up
53 writeReg(0x1A, 0x03); // CONFIG: alçak geçiren filtre ~44 Hz / low-pass ~44 Hz
54 writeReg(0x1B, 0x00); // GYRO_CONFIG: ±250 °/s
55 writeReg(0x1C, 0x00); // ACCEL_CONFIG: ±2 g
56 delay(100);
57 Serial.println("Kalibrasyon: sensoru oynatma / calibrating: keep still");
58 calibrateGyro();
59 readMPU();
60 roll = atan2(ay, az) * RAD_TO_DEG; // başlangıç açıları / initial angles
61 pitch = atan2(-ax, sqrt((float)ay * ay + (float)az * az)) * RAD_TO_DEG;
62 lastMicros = micros();
63}
64
65void loop() {
66 readMPU();
67 unsigned long now = micros();
68 float dt = (now - lastMicros) / 1000000.0; // saniye / seconds
69 lastMicros = now;
70
71 float accRoll = atan2(ay, az) * RAD_TO_DEG; // ivmeölçerden açı / angle from accelerometer
72 float accPitch = atan2(-ax, sqrt((float)ay * ay + (float)az * az)) * RAD_TO_DEG;
73 float gxRate = (gx - gxOff) / GYRO_LSB; // °/s
74 float gyRate = (gy - gyOff) / GYRO_LSB;
75 float gzRate = (gz - gzOff) / GYRO_LSB;
76
77 roll = ALPHA * (roll + gxRate * dt) + (1 - ALPHA) * accRoll; // tamamlayıcı filtre / complementary filter
78 pitch = ALPHA * (pitch + gyRate * dt) + (1 - ALPHA) * accPitch;
79 yaw += gzRate * dt; // yalnız jiroskop: zamanla kayar / gyro only: drifts over time
80
81 Serial.print("roll:"); Serial.print(roll, 1);
82 Serial.print(" pitch:"); Serial.print(pitch, 1);
83 Serial.print(" yaw:"); Serial.println(yaw, 1);
84 delay(10); // yaklaşık 100 Hz / about 100 Hz
85}| Ligne de code | Ce qu'elle fait |
|---|---|
| writeReg(0x6B, 0x00) | Sort le capteur du mode veille |
| writeReg(0x1A, 0x03) | Active le filtre interne d'environ 44 Hz |
| Wire.requestFrom(MPU_ADDR, 14) | Lit d'un coup l'accélération, la température et le gyroscope |
| calibrateGyro() | Calcule le décalage du gyroscope en moyennant 500 lectures |
| atan2(ay, az) * RAD_TO_DEG | Calcule l'angle roll en degrés à partir de l'accéléromètre |
| ALPHA * (...) + (1 - ALPHA) * ... | Filtre complémentaire : combine gyroscope et accéléromètre |
| yaw += gzRate * dt | Calcule le yaw avec le seul gyroscope ; tu le vois dériver avec le temps |
MPU6050 avec l'ESP32 : une alarme de détection de chute
Sur l'ESP32, le câblage est le même que sur l'Uno ; seules les broches I2C changent, GPIO 21 (SDA) et GPIO 22 (SCL), et le module est alimenté en 3V3. Tous les codes précédents fonctionnent tels quels sur l'ESP32 ; si tu veux, tu peux fixer les broches explicitement avec Wire.begin(21, 22). L'exemple ci-dessous est un détecteur de chute. Sur un objet en chute libre, l'accéléromètre lit presque 0 g, car le boîtier du capteur et la masse intérieure tombent ensemble ; l'impact qui suit produit un pic de plusieurs g. Si le code voit une chute libre d'au moins 100 ms suivie, dans la demi-seconde, d'un choc de plus de 2,5 g, il fait sonner pendant une seconde un buzzer actif relié à GPIO 25. Une chute libre de 100 ms correspond à une chute d'environ 5 cm (h = ½ × g × t²).
1#include <Wire.h>
2#include <Adafruit_MPU6050.h>
3#include <Adafruit_Sensor.h>
4
5Adafruit_MPU6050 mpu;
6const int BUZZER_PIN = 25; // aktif buzzer / active buzzer
7const float FREE_FALL_G = 0.4; // serbest düşüş eşiği / free-fall threshold
8const float IMPACT_G = 2.5; // darbe eşiği / impact threshold
9unsigned long fallStart = 0, fallEnd = 0;
10
11void setup() {
12 Serial.begin(115200);
13 pinMode(BUZZER_PIN, OUTPUT);
14 Wire.begin(21, 22); // SDA, SCL
15 if (!mpu.begin(0x68, &Wire)) {
16 Serial.println("MPU6050 bulunamadi / not found");
17 while (true) delay(10);
18 }
19 mpu.setAccelerometerRange(MPU6050_RANGE_8_G); // darbeler için geniş aralık / wide range for impacts
20 mpu.setFilterBandwidth(MPU6050_BAND_94_HZ); // kısa darbeleri kaçırma / keep short peaks
21}
22
23void loop() {
24 sensors_event_t a, g, t;
25 mpu.getEvent(&a, &g, &t);
26 float x = a.acceleration.x, y = a.acceleration.y, z = a.acceleration.z;
27 float total = sqrt(x * x + y * y + z * z) / SENSORS_GRAVITY_STANDARD; // toplam ivme, g / total acceleration in g
28 unsigned long now = millis();
29
30 if (total < FREE_FALL_G) {
31 if (fallStart == 0) fallStart = now; // düşüş başladı / fall started
32 } else if (fallStart != 0) {
33 if (now - fallStart > 100) fallEnd = now; // en az 100 ms süren düşüş / fall of at least 100 ms
34 fallStart = 0;
35 }
36
37 if (fallEnd != 0 && now - fallEnd < 500 && total > IMPACT_G) { // düşüşten sonra 0,5 s içinde darbe / impact within 0.5 s
38 Serial.println("DUSME ALGILANDI / FALL DETECTED");
39 digitalWrite(BUZZER_PIN, HIGH);
40 delay(1000);
41 digitalWrite(BUZZER_PIN, LOW);
42 fallEnd = 0;
43 }
44 if (fallEnd != 0 && now - fallEnd >= 500) fallEnd = 0; // darbe gelmedi, sıfırla / no impact, reset
45 delay(5);
46}Sur cette base, tu peux ajouter le Wi-Fi de l'ESP32 pour, par exemple, envoyer une notification Telegram sur ton téléphone si un proche âgé tombe, ou afficher les angles en direct sur une page web. Règle les seuils d'après tes propres essais : une boîte qui tombe d'une table et un capteur porté au poignet ne donnent pas les mêmes pics. Pour choisir et câbler le buzzer, consulte Qu'est-ce qu'un buzzer ?.
MPU6050 avec le Raspberry Pi Pico (MicroPython)
Sur le Pico, aucune bibliothèque supplémentaire n'est nécessaire : la classe I2C intégrée à MicroPython lit directement les registres. Relie le capteur au bus I2C0, SDA sur GP4 et SCL sur GP5. Avec struct.unpack, on transforme les 14 octets en sept nombres signés sur 16 bits ; « > » signifie big-endian (octet de poids fort en premier) et « h » entier signé sur 16 bits. Le code affiche d'abord les adresses I2C trouvées ; si 0x68 n'apparaît pas dans la liste, vérifie le câblage. Pour rester simple, nous n'avons pas ajouté de calibration ; si besoin, applique exactement la même méthode de moyenne que dans le code Arduino.
1from machine import Pin, I2C
2import math, struct, time
3
4MPU = 0x68
5i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
6print("Bulunan adresler / found addresses:", [hex(a) for a in i2c.scan()])
7
8i2c.writeto_mem(MPU, 0x6B, b"\x00") # uykudan uyandır / wake up
9i2c.writeto_mem(MPU, 0x1A, b"\x03") # alçak geçiren filtre ~44 Hz / low-pass ~44 Hz
10i2c.writeto_mem(MPU, 0x1B, b"\x00") # jiroskop ±250 °/s / gyro ±250 °/s
11i2c.writeto_mem(MPU, 0x1C, b"\x00") # ivmeölçer ±2 g / accelerometer ±2 g
12roll = pitch = 0.0
13last = time.ticks_us()
14
15while True:
16 data = i2c.readfrom_mem(MPU, 0x3B, 14)
17 ax, ay, az, t, gx, gy, gz = struct.unpack(">hhhhhhh", data) # büyük endian, işaretli / big-endian, signed
18 now = time.ticks_us()
19 dt = time.ticks_diff(now, last) / 1000000
20 last = now
21 acc_roll = math.degrees(math.atan2(ay, az))
22 acc_pitch = math.degrees(math.atan2(-ax, math.sqrt(ay * ay + az * az)))
23 roll = 0.98 * (roll + gx / 131 * dt) + 0.02 * acc_roll # tamamlayıcı filtre / complementary filter
24 pitch = 0.98 * (pitch + gy / 131 * dt) + 0.02 * acc_pitch
25 temp = t / 340 + 36.53 # °C
26 print("roll {:.1f} pitch {:.1f} T {:.1f}".format(roll, pitch, temp))
27 time.sleep_ms(10)Idées de projets avec le MPU6050
- Niveau à bulle numérique : affiche les angles roll et pitch sur un écran OLED avec une bulle qui se déplace.
- Servo piloté par le mouvement : quand tu inclines le capteur dans ta main, un servomoteur prend le même angle ; idéal pour un bras robotisé ou une tête de caméra.
- Jeu à l'inclinaison : joue à Pong ou à un labyrinthe en inclinant la carte au lieu d'utiliser un joystick.
- Robot auto-équilibré : traite l'angle pitch avec un PID et garde le robot debout grâce à des moteurs à courant continu pilotés par un L298N.
- Podomètre : mesure la marche en comptant les pics réguliers de l'accélération totale.
- Enregistreur de vibrations : mesure les secousses d'une machine ou d'un lave-linge et déclenche une alerte quand un seuil est dépassé.
Erreurs fréquentes et solutions
| Symptôme | Cause probable | Solution |
|---|---|---|
| begin() renvoie false (« MPU6050 not found ») | Erreur de câblage, mauvaise adresse ou puce clone | Trouve l'adresse avec un scanner I2C ; si WHO_AM_I n'est pas 0x68 (par exemple 0x70), utilise le code sans bibliothèque |
| Toutes les valeurs valent 0 | Le capteur est en veille | Écris 0 dans le registre 0x6B |
| Valeurs à -1 ou figées | Fil mal branché, bus I2C trop long | Raccourcis les fils, soude les broches |
| L'angle dérive à l'arrêt | Décalage du gyroscope non corrigé | Calibre au démarrage, capteur immobile |
| L'angle saute pendant les mouvements | Seul l'accéléromètre est utilisé | Ajoute un filtre complémentaire |
| Le yaw dérive sans arrêt | Le MPU6050 n'a pas de boussole | Ajoute un magnétomètre comme le QMC5883L ou utilise un capteur 9 axes |
| Le roll déraille quand le pitch approche ±90° | Singularité des angles d'Euler | Évite cette zone ou utilise la sortie en quaternions du DMP |
Malgré son petit prix, le MPU6050 ouvre la porte à la mesure du mouvement : découvre d'abord les valeurs brutes, calcule ensuite les angles et lisse-les enfin avec un filtre. Pour découvrir d'autres capteurs I2C et leurs usages, jette un œil au Guide des capteurs Arduino. Dans l'application BlueGrays, tu trouveras des projets de commande de servo, d'écrans I2C, de joystick et de robots, avec schéma et code pas à pas, à combiner avec le MPU6050.
Questions fréquentes
À quoi sert le MPU6050 ?
Le MPU6050 mesure l'inclinaison, la vitesse de rotation et l'accélération d'un objet. On l'utilise dans les robots auto-équilibrés, les drones et gimbals, les podomètres, la détection de chutes et de chocs, et les jeux pilotés par le mouvement.
L'adresse du MPU6050 est-elle 0x68 ou 0x69 ?
L'adresse est 0x68 quand la broche AD0 est libre ou reliée à GND, et 0x69 quand elle est reliée à 3,3 V. Sur la carte GY-521, AD0 est tirée à GND par une résistance, l'adresse par défaut est donc 0x68. Pour en être sûr, lance un scanner I2C.
Le MPU6050 fonctionne-t-il en 5 V ?
La puce MPU6050 elle-même supporte au plus 3,46 V, mais grâce au régulateur de la carte GY-521, la broche VCC peut être alimentée en 5 V. Les lignes I2C restent au niveau 3,3 V, que l'Arduino Uno lit sans problème. Il ne faut pas appliquer 5 V aux cartes nues sans régulateur.
Comment calculer un angle avec le MPU6050 ?
Capteur immobile, les angles se calculent à partir de l'accéléromètre avec roll = atan2(ay, az) et pitch = atan2(−ax, √(ay² + az²)). Pour des résultats justes en mouvement, on intègre dans le temps la vitesse angulaire du gyroscope et on la combine avec l'angle de l'accéléromètre grâce à un filtre complémentaire ou de Kalman.
Le MPU6050 peut-il mesurer le lacet (yaw) ?
Sur de courtes durées, oui : on calcule le yaw en intégrant la vitesse angulaire de l'axe Z. Mais comme le MPU6050 n'a pas de magnétomètre, le yaw dérive avec le temps et ne connaît pas le cap absolu (le nord). Pour un cap stable, il faut une boussole comme le QMC5883L ou une IMU 9 axes.
Quelle différence entre le MPU6050 et le MPU9250 ?
Le MPU6050 est un capteur 6 axes avec accéléromètre et gyroscope. Le MPU9250 ajoute un magnétomètre 3 axes, ce qui en fait un capteur 9 axes capable de mesurer le yaw sans dérive ; il gère aussi le SPI. Le MPU9250 n'étant plus fabriqué, on lui préfère des successeurs comme l'ICM-20948 pour les nouveaux projets.
Projets à réaliser après cet article
Voir tous les projets
Utilisation du servomoteur
Projet d'utilisation de base qui positionne le servomoteur à des angles de 0°, 90° et 180° dans l'ordre. Enseigne la bibliothèque des servos et la logique de contrôle des angles.

SG90 Servo Angle Control with Pot
Contrôle d'un servomoteur (SG90) à l'aide d'un potentiomètre L'objectif principal de ce projet est de contrôler précisément la position angulaire d'un servomoteur en temps réel en utilisant une unité d'entrée analogique, le potentiomètre. Le projet est un exemple d'ingénierie de base pour comprendre la logique de la conversion analogique-numérique (ADC) et la cartographie des signaux. Logique de fonctionnement : Lecture des données analogiques : Lorsque l'utilisateur tourne le potentiomètre, un

Servocommande avec joystick
Projet d'inclinaison panoramique qui contrôle indépendamment deux servomoteurs sur les axes X et Y à l'aide d'un module joystick. Enseigne la logique de l'intégration joystick-servo et le suivi de pos

Servomoteur ESP32 (commande par potentiomètre)
Dans ce projet, nous contrôlons un servomoteur SG90 à l'aide d'un potentiomètre. Nous réglons l'angle du servomoteur en mappant la valeur analogique lue par le potentiomètre sur une plage de 0 à 180 degrés. Grâce à la bibliothèque ESP32Servo, n'importe quel GPIO de l'ESP32 peut générer un signal PWM. Il s'agit d'une méthode de contrôle fondamentale pour les bras robotiques, les cardans de caméra et les mécanismes de portes automatiques.

Jeu de pong - SSD1306
Le jeu Pong classique construit à l'aide d'Arduino et d'un écran OLED SSD1306, équipé d'une intelligence artificielle (CPU) autonome qui suit instantanément les mouvements de la balle et réagit en fon

Utilisation de l'écran LCD avec I2C
Grâce au module I2C, le projet qui imprime des messages en contrôlant l'écran LCD avec seulement 2 câbles (SDA, SCL). Il enseigne comment économiser des pins avec le protocole I2C.

Écran LCD I2C ESP32 (16x2)
Dans ce projet, nous affichons du texte en connectant un écran LCD 16x2 à l'ESP32 via le protocole I2C. Grâce à l'I2C, nous pouvons contrôler l'écran avec seulement 2 broches de données (SDA et SCL) ; cela évite le gaspillage de 6 broches ou plus inhérent à la connexion parallèle classique. Le code affiche un message fixe sur la première ligne et un compteur qui augmente chaque seconde sur la deuxième ligne. De plus, au démarrage, nous lançons un scanner I2C pour afficher l'adresse de l'écran su

Robot évitant les obstacles
Que diriez-vous de construire un véhicule intelligent qui trouve son propre chemin ? Le Robot Évitant les Obstacles scrute en permanence son environnement grâce au capteur ultrasonique situé devant lu
Autres articles
Apprends à brancher l'accéléromètre et gyroscope MPU6050 sur Arduino, à lire les valeurs brutes, à calibrer le capteur, à calculer l'angle d'inclinaison et à le lisser avec un filtre complémentaire, avec en prime une alarme de chute ESP32 et du code pour le Pico.

