Note

Bonjour, bienvenue dans la communauté SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts sur Facebook ! Plongez dans le monde de Raspberry Pi, Arduino et ESP32 avec des passionnés.

Pourquoi nous rejoindre ?

  • Support expert : Résolvez vos problèmes après-vente et défis techniques avec l’aide de notre communauté et de notre équipe.

  • Apprendre & partager : Échangez des astuces et des tutoriels pour perfectionner vos compétences.

  • Aperçus exclusifs : Accédez en avant-première aux nouvelles annonces de produits et aux avant-goûts.

  • Réductions spéciales : Profitez de réductions exclusives sur nos nouveaux produits.

  • Promotions festives et concours : Participez à des concours et à des promotions spéciales pendant les fêtes.

👉 Prêt à explorer et à créer avec nous ? Cliquez sur [Ici] et rejoignez-nous dès aujourd’hui !

2.2.6 Module MPU6050

Introduction

Le MPU-6050 est le premier et unique dispositif de suivi de mouvement 6 axes (3 axes de gyroscope et 3 axes d’accéléromètre) conçu pour les smartphones, tablettes et capteurs portables, offrant une faible consommation, un faible coût et des performances élevées.

Dans cette expérience, nous utiliserons l’I2C pour obtenir les valeurs de l’accéléromètre à trois axes et du gyroscope à trois axes du MPU6050 et les afficher à l’écran.

Composants

_images/list_2.2.6.png

Principe

MPU6050

Le MPU-6050 est un dispositif de suivi de mouvement à 6 axes (3 axes de gyroscope, 3 axes d’accéléromètre).

Ses trois systèmes de coordonnées sont définis comme suit :

Placez le MPU6050 à plat sur la table, assurez-vous que la face avec l’étiquette est orientée vers le haut et qu’un point sur cette surface se trouve dans le coin supérieur gauche. Ensuite, la direction verticale vers le haut correspond à l’axe Z de la puce. La direction de gauche à droite est l’axe X, et la direction de l’arrière vers l’avant est l’axe Y.

_images/image223.png

Accéléromètre 3 axes

L’accéléromètre fonctionne selon le principe de l’effet piézoélectrique, la capacité de certains matériaux à générer une charge électrique en réponse à une contrainte mécanique appliquée.

Imaginez ici une boîte cuboïde avec une petite balle à l’intérieur, comme sur l’image ci-dessus. Les parois de cette boîte sont faites de cristaux piézoélectriques. Chaque fois que vous inclinez la boîte, la balle se déplace dans la direction de l’inclinaison en raison de la gravité. La paroi avec laquelle la balle entre en collision crée de petits courants piézoélectriques. Il y a au total trois paires de parois opposées dans le cuboïde. Chaque paire correspond à un axe dans l’espace 3D : les axes X, Y et Z. En fonction du courant produit par les parois piézoélectriques, nous pouvons déterminer la direction et l’amplitude de l’inclinaison.

_images/image224.png

Nous pouvons utiliser le MPU6050 pour détecter son accélération sur chaque axe de coordonnées (dans un état stationnaire, l’accélération de l’axe Z est de 1 unité de gravité, et les axes X et Y sont à 0). S’il est incliné ou dans une condition de sur/sous-poids, la lecture correspondante changera.

Quatre plages de mesure peuvent être sélectionnées par programmation :

+/-2g, +/-4g, +/-8g et +/-16g (2g par défaut), correspondant à chaque précision. Les valeurs vont de -32768 à 32767.

La lecture de l’accéléromètre est convertie en valeur d’accélération en mappant la lecture sur la plage de mesure.

Accélération = (Données brutes de l’accéléromètre / 65536 * plage d’accélération totale) g

Prenons l’exemple de l’axe X, lorsque les données brutes de l’accéléromètre de l’axe X sont de 16384 et que la plage sélectionnée est +/-2g :

Accélération le long de l’axe X = (16384 / 65536 * 4) g =1g

Gyroscope 3 axes

Les gyroscopes fonctionnent sur le principe de l’accélération de Coriolis. Imaginez une structure en forme de fourche qui effectue un mouvement constant d’avant en arrière, maintenue en place par des cristaux piézoélectriques. Lorsque vous inclinez cet agencement, les cristaux subissent une force dans la direction de l’inclinaison, générée par l’inertie de la fourche en mouvement. Les cristaux produisent ainsi un courant conforme à l’effet piézoélectrique, qui est ensuite amplifié.

_images/image225.png
Le gyroscope dispose également de quatre plages de mesure :

+/-250, +/-500, +/-1000 et +/-2000. La méthode de calcul est essentiellement la même que celle de l’accélération.

La formule pour convertir la lecture en vitesse angulaire est la suivante :

Vitesse angulaire = (Données brutes de l’axe du gyroscope / 65536 * plage du gyroscope) °/s

Prenons l’exemple de l’axe X : si les données brutes du gyroscope pour l’axe X sont de 16384 et que la plage est de +/- 250°/s :

Vitesse angulaire le long de l’axe X = (16384 / 65536 * 500)°/s =125°/s

Schéma

Le MPU6050 communique avec le microcontrôleur via l’interface de bus I2C. Les broches SDA1 et SCL1 doivent être connectées à la broche correspondante.

_images/image330.png

Procédures expérimentales

Étape 1 : Construisez le circuit.

_images/image227.png

Étape 2 : Configurez l’I2C (voir l’annexe. Si vous avez déjà configuré l’I2C, passez cette étape.) Pour les utilisateurs du langage C ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Étape 3 : Accédez au dossier du code.

cd ~/davinci-kit-for-raspberry-pi/c/2.2.6/

Étape 4 : Compilez le code.

gcc 2.2.6_mpu6050.c -lwiringPi -lm

Étape 5 : Exécutez le fichier exécutable.

sudo ./a.out

Une fois le code exécuté, les angles de déviation des axes X et Y, ainsi que l’accélération et la vitesse angulaire sur chaque axe, seront calculés et affichés sur l’écran à partir des données lues par le MPU6050.

Note

Si cela ne fonctionne pas après l’exécution, ou si un message d’erreur tel que « wiringPi.h: No such file or directory » apparaît, veuillez vous référer à C code is not working?.

Code

#include  <wiringPiI2C.h>
#include <wiringPi.h>
#include  <stdio.h>
#include  <math.h>
int fd;
int acclX, acclY, acclZ;
int gyroX, gyroY, gyroZ;
double acclX_scaled, acclY_scaled, acclZ_scaled;
double gyroX_scaled, gyroY_scaled, gyroZ_scaled;

int read_word_2c(int addr)
{
    int val;
    val = wiringPiI2CReadReg8(fd, addr);
    val = val << 8;
    val += wiringPiI2CReadReg8(fd, addr+1);
    if (val >= 0x8000)
        val = -(65536 - val);
    return val;
}

double dist(double a, double b)
{
    return sqrt((a*a) + (b*b));
}

double get_y_rotation(double x, double y, double z)
{
    double radians;
    radians = atan2(x, dist(y, z));
    return -(radians * (180.0 / M_PI));
}

double get_x_rotation(double x, double y, double z)
{
    double radians;
    radians = atan2(y, dist(x, z));
    return (radians * (180.0 / M_PI));
}

int main()
{
    fd = wiringPiI2CSetup (0x68);
    wiringPiI2CWriteReg8 (fd,0x6B,0x00); // désactivation du mode veille
    printf("set 0x6B=%X\n",wiringPiI2CReadReg8 (fd,0x6B));

    while(1) {

        gyroX = read_word_2c(0x43);
        gyroY = read_word_2c(0x45);
        gyroZ = read_word_2c(0x47);

        gyroX_scaled = gyroX / 131.0;
        gyroY_scaled = gyroY / 131.0;
        gyroZ_scaled = gyroZ / 131.0;

    //Print values for the X, Y, and Z axes of the gyroscope sensor.
    printf("My gyroX_scaled: %f\n", gyroY X_scaled);
        delay(100);
    printf("My gyroY_scaled: %f\n", gyroY Y_scaled);
        delay(100);
    printf("My gyroZ_scaled: %f\n", gyroY Z_scaled);
        delay(100);

        acclX = read_word_2c(0x3B);
        acclY = read_word_2c(0x3D);
        acclZ = read_word_2c(0x3F);

        acclX_scaled = acclX / 16384.0;
        acclY_scaled = acclY / 16384.0;
        acclZ_scaled = acclZ / 16384.0;

    //Print the X, Y, and Z values of the acceleration sensor.
    printf("My acclX_scaled: %f\n", acclX_scaled);
        delay(100);
    printf("My acclY_scaled: %f\n", acclY_scaled);
        delay(100);
    printf("My acclZ_scaled: %f\n", acclZ_scaled);
        delay(100);

    printf("My X rotation: %f\n", get_x_rotation(acclX_scaled, acclY_scaled, acclZ_scaled));
        delay(100);
    printf("My Y rotation: %f\n", get_y_rotation(acclX_scaled, acclY_scaled, acclZ_scaled));
        delay(100);

        delay(100);
    }
    return 0;
}

Explication du code

int read_word_2c(int addr)
{
int val;
val = wiringPiI2CReadReg8(fd, addr);
val = val << 8;
val += wiringPiI2CReadReg8(fd, addr+1);
if (val >= 0x8000)
    val = -(65536 - val);
return val;
}

Lecture des données du capteur envoyées par le MPU6050.

double get_y_rotation(double x, double y, double z)
{
double radians;
radians = atan2(x, dist(y, z));
return -(radians * (180.0 / M_PI));
}

Obtention de l’angle de déviation sur l’axe Y.

double get_x_rotation(double x, double y, double z)
{
double radians;
radians = atan2(y, dist(x, z));
return (radians * (180.0 / M_PI));
}

Calcul de l’angle de déviation sur l’axe X.

gyroX = read_word_2c(0x43);
gyroY = read_word_2c(0x45);
gyroZ = read_word_2c(0x47);

gyroX_scaled = gyroX / 131.0;
gyroY_scaled = gyroY / 131.0;
gyroZ_scaled = gyroZ / 131.0;

//Print values for the X, Y, and Z axes of the gyroscope sensor.
printf("My gyroX_scaled: %f\n", gyroY X_scaled);
printf("My gyroY_scaled: %f\n", gyroY Y_scaled);
printf("My gyroZ_scaled: %f\n", gyroY Z_scaled);

Lecture des valeurs des axes X, Y et Z sur le capteur gyroscope, conversion des métadonnées en valeurs de vitesse angulaire, puis affichage des résultats.

acclX = read_word_2c(0x3B);
acclY = read_word_2c(0x3D);
acclZ = read_word_2c(0x3F);

acclX_scaled = acclX / 16384.0;
acclY_scaled = acclY / 16384.0;
acclZ_scaled = acclZ / 16384.0;

//Print the X, Y, and Z values of the acceleration sensor.
printf("My acclX_scaled: %f\n", acclX_scaled);
printf("My acclY_scaled: %f\n", acclY_scaled);
printf("My acclZ_scaled: %f\n", acclZ_scaled);

Lecture des valeurs des axes X, Y et Z sur le capteur d’accélération, conversion des métadonnées en valeurs d’accélération (unités gravitationnelles), puis affichage des résultats.

printf("My X rotation: %f\n", get_x_rotation(acclX_scaled, acclY_scaled, acclZ_scaled));
printf("My Y rotation: %f\n", get_y_rotation(acclX_scaled, acclY_scaled, acclZ_scaled));

Affichage des angles de déviation sur les axes X et Y.

Pour les utilisateurs du langage Python

Étape 3 : Accédez au dossier du code.

cd ~/davinci-kit-for-raspberry-pi/python

Étape 4 : Exécutez le fichier exécutable.

sudo python3 2.2.6_mpu6050.py

Lorsque le code s’exécute, l’angle de déviation des axes X et Y, ainsi que l’accélération et la vitesse angulaire sur chaque axe lues par le MPU6050, seront calculés et affichés à l’écran.

Code

Note

Vous pouvez Modifier/Réinitialiser/Copier/Exécuter/Arrêter le code ci-dessous. Mais avant cela, vous devez aller dans le chemin du code source comme davinci-kit-for-raspberry-pi/python.

import smbus
import math
import time

# Registres de gestion de l'alimentation
power_mgmt_1 = 0x6b
power_mgmt_2 = 0x6c

def read_byte(adr):
    return bus.read_byte_data(address, adr)

def read_word(adr):
    high = bus.read_byte_data(address, adr)
    low = bus.read_byte_data(address, adr+1)
    val = (high << 8) + low
    return val

def read_word_2c(adr):
    val = read_word(adr)
    if (val >= 0x8000):
        return -((65535 - val) + 1)
    else:
        return val

def dist(a,b):
    return math.sqrt((a*a)+(b*b))

def get_y_rotation(x,y,z):
    radians = math.atan2(x, dist(y,z))
    return -math.degrees(radians)

def get_x_rotation(x,y,z):
    radians = math.atan2(y, dist(x,z))
    return math.degrees(radians)


bus = smbus.SMBus(1) # ou bus = smbus.SMBus(1) pour les cartes Révision 2
address = 0x68       # Ceci est l'adresse lue via la commande i2cdetect

# Réveillez maintenant le MPU6050 car il commence en mode veille
bus.write_byte_data(address, power_mgmt_1, 0)

while True:
    time.sleep(0.1)
    gyro_xout = read_word_2c(0x43)
    gyro_yout = read_word_2c(0x45)
    gyro_zout = read_word_2c(0x47)

    print ("gyro_xout : ", gyro_xout, " scaled: ", (gyro_xout / 131))
    print ("gyro_yout : ", gyro_yout, " scaled: ", (gyro_yout / 131))
    print ("gyro_zout : ", gyro_zout, " scaled: ", (gyro_zout / 131))

    accel_xout = read_word_2c(0x3b)
    accel_yout = read_word_2c(0x3d)
    accel_zout = read_word_2c(0x3f)

    accel_xout_scaled = accel_xout / 16384.0
    accel_yout_scaled = accel_yout / 16384.0
    accel_zout_scaled = accel_zout / 16384.0

    print ("accel_xout: ", accel_xout, " scaled: ", accel_xout_scaled)
    print ("accel_yout: ", accel_yout, " scaled: ", accel_yout_scaled)
    print ("accel_zout: ", accel_zout, " scaled: ", accel_zout_scaled)

    print ("x rotation: " , get_x_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))
    print ("y rotation: " , get_y_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))

    time.sleep(0.5)

Explication du code

def read_word(adr):
    high = bus.read_byte_data(address, adr)
    low = bus.read_byte_data(address, adr+1)
    val = (high << 8) + low
    return val

def read_word_2c(adr):
    val = read_word(adr)
    if (val >= 0x8000):
        return -((65535 - val) + 1)
    else:
        return val

Lecture des données du capteur envoyées par le MPU6050.

def get_y_rotation(x,y,z):
    radians = math.atan2(x, dist(y,z))
    return -math.degrees(radians)

Calcul de l’angle de déviation de l’axe Y.

def get_x_rotation(x,y,z):
    radians = math.atan2(y, dist(x,z))
    return math.degrees(radians)

Calcul de l’angle de déviation de l’axe X.

gyro_xout = read_word_2c(0x43)
gyro_yout = read_word_2c(0x45)
gyro_zout = read_word_2c(0x47)

print ("gyro_xout : ", gyro_xout, " scaled: ", (gyro_xout / 131))
print ("gyro_yout : ", gyro_yout, " scaled: ", (gyro_yout / 131))
print ("gyro_zout : ", gyro_zout, " scaled: ", (gyro_zout / 131))

Lecture des valeurs des axes X, Y et Z du capteur gyroscope, conversion des données en valeurs de vitesse angulaire, et affichage des résultats.

accel_xout = read_word_2c(0x3b)
accel_yout = read_word_2c(0x3d)
accel_zout = read_word_2c(0x3f)

accel_xout_scaled = accel_xout / 16384.0
accel_yout_scaled = accel_yout / 16384.0
accel_zout_scaled = accel_zout / 16384.0

print ("accel_xout: ", accel_xout, " scaled: ", accel_xout_scaled)
print ("accel_yout: ", accel_yout, " scaled: ", accel_yout_scaled)
print ("accel_zout: ", accel_zout, " scaled: ", accel_zout_scaled)

Lecture des valeurs des axes X, Y et Z du capteur d’accélération, conversion des données en valeurs d’accélération (en unités gravitationnelles), puis affichage des résultats.

print ("x rotation: " , get_x_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))
print ("y rotation: " , get_y_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))

Affichage des angles de déviation des axes X et Y.

Image du phénomène

_images/image228.jpeg