Capteurs de mouvements, au pays des MEMS

par dolivier

Ce document est en cours de rédaction. Il est donc sujet à de fortes modifications.

Introduction

Pendule À l’université du Havre nous avons la chance de bénéficier d’une bibliothèque dont l’architecture intérieure est remarquable. Un projet collectif initié par J. Brossard professeur émérite de mécanique a émergé, il s’agit de réaliser un pendule de Foucault qui serait hébergé dans cet écrin.

Foucault par ce pendule en 1851 a démontré que la Terre tournait sur elle-même. Une fois mis en mouvement le plan d’oscillation du pendule pivote au fil des minutes. Aux pôles, le pendule fait un tour complet en exactement 24 heures. Au Havre, à cause d’un effet de latitude, le pendule n’accomplit pas un tour complet en une journée. Cette rotation du plan d’oscillation n’est qu’apparente, le plan reste fixe et c’est la Terre qui tourne !

Parmi les objectifs que nous nous sommes fixés, figure l’instrumentation du pendule avec des moyens “simples” et la mise à disposition des mesures sur la toile. L’utilisation d’un arduino, d’accéléromètres et de gyroscopes appartenant à la famille des MEMS nous a semblé répondre à ces exigences.

Au travers de cette présentation, je vais donc essayer de retracer la mise en place des différents éléments de la chaîne de mesure mais également d’amener des éléments de connaissance autour des capteurs de mouvement que j’ai, il faut bien l’admettre, découvert récemment et que tous ceux qui jouent ou ont joué avec une wii utilisent régulièrement !

Capteurs de mouvement

Les capteurs de mouvement sont présents sous la forme d’accéléromètres ou de gyroscopes dans nos téléphones portables ou encore utilisés comme des éléments de mesure associés à un arduino ou autres micro-calculateurs dans un drone par exemple. Ce sont ce que l’on appelle des MEMS. Les Micro Electro Mechanical Systems appartiennent à la micro technologie. Ces MEMS comportent un ou plusieurs systèmes mécaniques et une partie électronique. Les gyroscopes et les accéléromètres n’échappent pas à cela.

Rotation (gyroscope) / Déplacement linéaire (accéléromètre)
Rotation (gyroscope) / Déplacement linéaire (accéléromètre) Source

L’idée générale d’un capteur de mouvement est simple : l’accélération et les mouvements créent des forces qui provoquent des déplacements ou des déformations de pièces mécaniques qui sont alors transformés en signaux électriques. C’est donc avant tout une force qui est mesurée à l’aide d’une variation de capacité électrique.

Accéléromètre

Il existe différents types d’accéléromètres, nous nous intéressons simplement ici aux accéléromètres capacitifs. Ils sont composés d’une ou plusieurs masses mobiles qui par leurs déplacements font varier des capacités. Cette capacité dépend en particulier de la distance entre les deux plaques lorsqu’on considère un condensateur plan.

Plaque mobile et plaque fixe d'un condensateur plan pour accéléromètre
Plaque mobile et plaque fixe d’un condensateur plan pour accéléromètre. Source

Si représente l’aire d’une plaque, la permittivité électrique de l’air (), la permittivité électrique relative de l’isolant, la distance initiale entre les deux plaques et le déplacement alors la capacité peut s’écrire de la façon suivante :

Le système utilisé est en fait généralement un condensateur double différentiel à écartement variable. Il y a une unique plaque mobile, qui est placée sur un ressort mécanique entre deux plaques fixes. Le mouvement de la plaque mobile par rapport aux plaques fixes (D1 et D2), génère un changement des capacités (C1 et C2). En calculant la différence entre C2 et C1, il est possible de calculer le déplacement de la plaque mobile et sa direction.

Condensateur double différentiel
Condensateur double différentiel

Il reste maintenant à placer un tel système sur les trois axes perpendiculaires.

Si vous désossez votre téléphone portable vous trouverez sans doute un MEMS et si vous l’ouvrez vous verrez quelque chose comme cela :

Accéléromètre dans un téléphone
Accéléromètre dans un téléphone. source

Gyroscope

Un gyroscope permet de maintenir ou de mesurer une direction. Il a été inventé (1852) par Léon Foucault (et Froment) pour une expérience prouvant la rotation de la terre. Cette rotation avait déjà été mise en évidence par son pendule en 1851, cependant comme la rotation du pendule s’effectue plus lentement que la rotation de la terre (d’un facteur ), il a cherché donc une manière plus directe de le montrer.

Le gyroscope de Foucault repose sur le principe de la conservation du moment angulaire en physique (ou moment cinétique). Ce principe est l’équivalent du principe de conservation de la quantité de mouvement dans le cas d’une translation pour les rotations. De façon grossière, si vous vous rappelez vos souvenirs d’élèves la conservation de la quantité de mouvement d’un système isolé signifie qu’un corps quelconque poursuit son mouvement en l’absence de forces extérieures. Sur terre les systèmes ne sont pas isolés (sauf dispositif expérimental particulier, il vous faudra par exemple un avion que vous mettrez en condition d’apesanteur !). Ainsi lorsque vous lancez un galet sur la plage du Havre, la force de pesanteur ramène ce galet vers le sol et les frottements freinent sa course alors que si lors de votre prochain voyage dans l’espace à l’occasion d’une sortie vous tentez la même expérience, votre galet se déplacera en ligne droite et à vitesse constante. Pour la conservation du moment angulaire, il suffit de mettre en rotation un objet sur son axe. Votre roue avant de vélo que vous aurez démontée fera très bien l’affaire. Si vous tenez cette dernière par son axe de façon verticale et que vous demandez à un camarade de la mettre en rotation vous constaterez que la rotation à tendance à se poursuivre, surtout s’il n’y a pas de frottement ou plus exactement s’il n’y a pas de forces extérieures. Si maintenant vous essayez d’incliner votre roue (axe vertical), vous constaterez que cette dernière résiste et qu’elle à tendance à se remettre sur cette verticale dès que vous relâchez la contrainte. Bien sur l’expérience sera plus probante dans l’espace, mais vous pouvez éviter un voyage éventuellement en observant déjà ces phénomènes sur terre, il faudra simplement vous rappelez que des forces extérieures viennent perturber votre expérience.

Un gyroscope est basé sur ces principes, il est composé d’un rotor qui tourne autour d’un axe. Ce rotor est monté sur un anneau intérieur qui tourne sur un axe perpendiculaire au précédent lui même monté sur un anneau extérieur dont l’axe de rotation est perpendiculaire aux deux précédents. L’intérêt par rapport au pendule est que l’axe de rotation reste parallèle à une direction fixe par rapport aux astres et cela, quelle que soit la latitude.

Ouf, plutôt que cette description une image est sans doute plus explicite !

Gyroscope de Foucault
Gyroscope de Foucault. Source

Ce type de gyroscope est évidemment un peu gros pour le mettre dans nos téléphones ou nos drones, c’est une version bien plus petite où là encore un MEMS se cache. Les gyroscopes servent généralement à mesurer une vitesse angulaire par rapport à un axe : lacet, tangage et roulis. C’est grâce à cela que se définit l’attitude d’un drone, d’un avion ou même votre tablette. Elle désigne l’orientation des trois axes.

Attitude
Attitude. Les six degrés de liberté dans un espace à trois dimensions : trois de translation et trois de rotation. Par convention les translations sont positives dans les directions Droite, Avant, et Haut (axes Ox, Oy et Oz). Chacun des mots Tangage (rotation autour de Ox), Roulis (autour de Oy) et Lacet (autour de Oz) a été placé près de la flèche indiquant le sens de rotation positif (trièdre direct Oxyz). Source

Les gyromètres de nos téléphones et autres tablettes ressemblent aux accéléromètres mais le dispositif est un peu plus compliqué. Pour un axe donné, il faut imaginer deux tiges vibrantes placées dans un cadre rigide dont le plan de vibration définit alors cet axe. Lorsque vous faites tourner votre téléphone par exemple, les tiges se tordent sous l’effet de la force de Coriolis et elles n’oscillent plus dans le même plan. La mesure de cette déformation grâce à la variation de la capacité électrique entre les tiges et le support de silicium permet de déterminer dans quel sens et à quelle vitesse votre téléphone a été incliné.

Gyroscope à structure vibrante
Gyroscope de Foucault. Source

Première expérience

Les gyroscopes sont largement utilisés dans les avions télécommandés ou les drones. On trouve maintenant facilement les différents composants que l’on peut interfacer avec un arduino, et/ou avec un EPS8266. L’objectif reste d’instrumenter le pendule et d’être en mesure d’envoyer les informations sans fil à la patte, mais il nous faut dans un premier temps tester et maîtriser le processus, c’est pourquoi nous allons tout d’abord expérimenter cela avec un arduino Uno et un MPU6050.

Instrumentation et câblage

  • Un arduino UNO et une alimentation ;
  • Un MPU6050 comportant accéléromètres et gyroscopes, il utilise le bus I2C pour communiquer ;
Schéma
Schéma de montage initial.

Programmation

La première chose que nous allons faire est de scanner le bus I2C. La connexion est réalisée par l’intermédiaire de 2 broches :

  • SDA (Serial Data Line) : ligne de données bidirectionnelle,
  • SCL (Serial Clock Line) : ligne d’horloge de synchronisation bidirectionnelle ;
  • INT : interruption qui signale que les données sont prêtes.
// --------------------------------------
// i2c_scanner
// Ce programme scanne le bus I2C
//
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Source : http://playground.arduino.cc/Main/I2cScanner

#include <Wire.h>
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("\n Scan du bus I2C");
}

void loop()
{
  byte error, address;
  int nDevices;
  Serial.println("Recherche...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) //Adresses 1-127
  {
    // Le scanner I2C utilise la valeur retournée par Write.endTransmisstion
   //pour voir si un dispositif répond à cette adresse
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("Dispositif I2C trouvé à l'addresse 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println(" ");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Erreur inconnue à l'addresse 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("Pas de dispositif I2C trouvé\n");
  else
    Serial.println("Terminé\n");
  delay(5000);        // Attend 5 secondes pour lancer le scan suivant
}
Recherche...
Dispositif I2C trouvé à l'addresse 0x68
Terminé

Notez l’adresse trouvée pour votre MPU6050. Elle resservira. Si vous voulez comprendre comment fonctionne le bus I2C allez donc lire le tutoriel ici.

Passons maintenant à la lecture des données brutes d’accélération mesurées par le MPU6050. L’arduino et le MPU6050 fonctionnent en maître/esclave. On utilise la bibliothèque wire pour communiquer. On se connecte en mode maître, on débute la connexion et on réveille le MPU6050, pour la partie initialisation.

#include<Wire.h>

const int MPU_addr     = 0x68; // Adresse du gyroscope sur le bus I2C
const int PWR_MGT      = 0x6B; // Adresse du registre gérant l'énergie R/W

void setup(){
  Wire.begin();                     // Connexion en mode maître
  Wire.beginTransmission(MPU_addr); // Débute une transmission avec le MPU-6050
  Wire.write(PWR_MGT);              // Registre gérant l'énergie PWR
  Wire.write(0);                    // 0 on réveille le MPU-6050
  Wire.endTransmission(true);       // Fin de l'écriture sur le bus
  Serial.begin(115200);
}

La lecture des données issues du gyroscope est assez compliquée. Il faut lire les registres deux par deux à partir d’une adresse de départ. Cela se fait avec wide.read() qui renvoie un entier sur 16 bits où les bits de poids forts sont nuls. La valeur retournée est du type 00000000xxxxxxxx. La lecture de deux registres nous donne donc 00000000xxxxxxxx et 00000000yyyyyyyy et la donnée brute est xxxxxxxxyyyyyyyy. On peut utiliser une union pour faire cela (lignes 49 à 51) ou travailler avec des décalages de bits et un masque.

// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Version adaptée
// 13 juillet 2016
// Public Domain


#include<Wire.h>

typedef union registre_gyro
{
  struct
  {
    uint8_t faible;     // LSB
    uint8_t fort;       // MSP
  } poids_fort_faible ;
  int16_t registre16;
};

const int MPU_addr     = 0x68; // Adresse du gyroscope sur le bus I2C
const int PWR_MGT      = 0x6B; // Adresse du registre gérant l'énergie R/W
const int ACCEL_XOUT_H = 0x3B; // Premier registre Accélération sur X
const int NB_REGISTRE  = 14;   // Nombre de registre
registre_gyro ValeurBrute1, ValeurBrute2;

char * DonneesGyro[] = { "AcX ", "AcY ", "AcZ ", "Temp", "GyX ", "GyY ", "GyZ " };

void setup(){
  Wire.begin();                     // Connexion en mode maître
  Wire.beginTransmission(MPU_addr); // Débute une transmission avec le MPU-6050
  Wire.write(PWR_MGT);              // Registre gérant l'énergie PWR
  Wire.write(0);                    // 0 on réveille le MPU-6050
  Wire.endTransmission(true);       // Fin de l'écriture sur le bus
  Serial.begin(115200);
}

void loop(){
  int i;

  Wire.beginTransmission(MPU_addr);
  Wire.write(ACCEL_XOUT_H);    // Premier registre où on commence ACCEL_XOUT_H
  Wire.endTransmission(false); // Connexion active et réinitialisée
  Wire.requestFrom(MPU_addr,14,true); // Requête sur les registres de données

  for(i = 0; i < sizeof(DonneesGyro) / sizeof(char *); i++)
  {  // On pourrait écrire
     // ValeurBrute2.registre16 = Wire.read() << 8 | Wire.read();
    ValeurBrute1.registre16 = Wire.read();
    ValeurBrute2.registre16 = Wire.read();
    ValeurBrute2.poids_fort_faible.fort = ValeurBrute1.poids_fort_faible.faible;
    Serial.print(DonneesGyro[i]); Serial.print("=");
    if (i != 3)
     Serial.print(ValeurBrute2.registre16);
     else Serial.print(ValeurBrute2.registre16 / 340.00 + 36.53 );
    Serial.print("  |   ");
  }
  Serial.println();

  delay(333);
}

Sources

Nous contacter

Vous pouvez nous contacter à cette adresse ou utiliser le formulaire ci-dessous.