Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Comment suivre l'orientation avec Arduino et l'accéléromètre ADXL345

Dans ce didacticiel, nous apprendrons à mesurer l'angle et l'orientation de la piste à l'aide de l'Arduino et du capteur accéléromètre ADXL345. Vous pouvez regarder la vidéo suivante ou lire le didacticiel écrit ci-dessous pour plus de détails.

Aperçu

Tout d'abord, j'expliquerai comment fonctionne le capteur et comment en lire les données, puis à l'aide de l'environnement de développement Processing, nous ferons une visualisation 3D de l'orientation de l'accéléromètre.

Fonctionnement de l'accéléromètre ADXL345

Pour commencer, regardons comment fonctionne le capteur ADXL345. Il s'agit d'un accéléromètre à 3 axes qui peut mesurer les forces d'accélération statiques et dynamiques. La force gravitationnelle terrestre est un exemple typique de force statique, tandis que les forces dynamiques peuvent être causées par des vibrations, des mouvements, etc.

L'unité de mesure de l'accélération est le mètre par seconde au carré (m/s^2). Cependant, les capteurs accéléromètres expriment généralement les mesures en "g" ou gravité. Un "g" est la valeur de la force gravitationnelle terrestre qui est égale à 9,8 mètres par seconde au carré.

Ainsi, si nous avons un accéléromètre positionné à plat, avec son axe Z pointant vers le haut, à l'opposé de la force gravitationnelle, la sortie de l'axe Z du capteur sera de 1g. D'autre part, les sorties X et Y seront nulles, car la force gravitationnelle est perpendiculaire à ces axes et ne les affecte pas du tout.

Si nous renversons le capteur, la sortie de l'axe Z sera de -1 g. Cela signifie que les sorties du capteur en raison de son orientation par rapport à la gravité peuvent varier de -1g à +1g.

Donc, selon ces données et en utilisant des calculs de trigonométrie, nous pouvons calculer l'angle auquel le capteur est positionné.

Comment lire les données de l'accéléromètre ADXL345 avec Arduino

Ok, voyons maintenant comment lire les données de l'accéléromètre ADXL345 à l'aide de l'Arduino. Ce capteur utilise le protocole I2C pour communiquer avec l'Arduino, nous n'avons donc besoin que de deux fils pour le connecter, plus les deux fils pour l'alimenter.

Vous pouvez obtenir les composants nécessaires pour ce didacticiel Arduino à partir des liens ci-dessous :

  • Accéléromètre ADXL345 ………………. Amazon / Banggood /AliExpress
  • Carte Arduino …………………………….. 
  • Breadboard et Jump Wires ………… 

Code Arduino de l'accéléromètre ADXL345

Voici le code Arduino pour lire les données de l'accéléromètre ADXL345.

/*
    Arduino and ADXL345 Accelerometer Tutorial
     by Dejan, https://howtomechatronics.com
*/

#include <Wire.h>  // Wire library - used for I2C communication

int ADXL345 = 0x53; // The ADXL345 sensor I2C address

float X_out, Y_out, Z_out;  // Outputs

void setup() {
  Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device 
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable 
  Wire.endTransmission();
  delay(10);
}

void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
  X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
  Y_out = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
  Z_out = Z_out/256;

  Serial.print("Xa= ");
  Serial.print(X_out);
  Serial.print("   Ya= ");
  Serial.print(Y_out);
  Serial.print("   Za= ");
  Serial.println(Z_out);
}Code language: Arduino (arduino)

Description : Nous devons donc d'abord inclure la bibliothèque Wire.h qui est utilisée pour la communication I2C. Si vous voulez en savoir plus sur le fonctionnement de la communication I2C et sur son utilisation avec Arduino, vous pouvez consulter mon autre tutoriel détaillé.

Chaque appareil qui utilise la communication I2C a une adresse I2C unique, et cette adresse peut être trouvée dans la fiche technique du capteur (ADXL345 Datasheet). Donc, une fois que nous avons défini l'adresse et les variables pour les trois sorties, dans la section de configuration, nous devons d'abord initialiser la bibliothèque de fils, puis régler l'accéléromètre en mode mesure. Pour ce faire, si nous regardons à nouveau la fiche technique, nous pouvons voir que nous devons définir le bit D3 du registre POWER_CTL sur HIGH.

Ainsi, en utilisant la fonction beginTransmission() nous commençons la communication, puis en utilisant la fonction write() nous indiquons à quel registre nous voulons accéder, et encore en utilisant la fonction write() nous définissons le bit D3 HIGH, en écrivant le nombre 8 dans décimal qui correspond au réglage du bit D3 HIGH.

// Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device 
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable 
  Wire.endTransmission();Code language: Arduino (arduino)

Dans la section de la boucle, nous lisons maintenant les données du capteur. Les données de chaque axe sont stockées dans deux octets ou registres. Nous pouvons voir les adresses de ces registres à partir de la fiche technique.

Afin de tous les lire, on commence par le premier registre, et à l'aide de la fonction requestionFrom() on demande de lire les 6 registres. Ensuite, en utilisant la fonction read(), nous lisons les données de chaque registre, et comme les sorties sont des compléments à deux, nous les combinons de manière appropriée pour obtenir les valeurs correctes.

// === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
  X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
  Y_out = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
  Z_out = Z_out/256;Code language: Arduino (arduino)

Les valeurs de sortie du capteur dépendent en fait de la sensibilité choisie, qui peut varier de +- 2g à +-16g. La sensibilité par défaut est de +-2g, c'est pourquoi nous devons diviser la sortie par 256 afin d'obtenir des valeurs de -1 à +1g. Le 256 LSB/g signifie que nous avons 256 comptes par g.

En fonction de l'application, nous pouvons sélectionner la sensibilité appropriée. Dans ce cas, pour le suivi de l'orientation, la sensibilité de +-2g est correcte, mais pour une application où nous devons détecter une force d'accélération plus élevée à partir de mouvements brusques, de chocs, etc., nous pouvons choisir certaines des autres plages de sensibilité à l'aide du registre DATA_FORMAT et ses bits D1 et D0.

Étalonnage de l'accéléromètre ADXL345

Néanmoins, une fois que nous avons lu les données, nous pouvons simplement les imprimer sur le moniteur série pour vérifier si les valeurs sont celles attendues. Dans mon cas, les valeurs que j'obtenais n'étaient pas exactement comme elles devraient l'être, en particulier l'axe Z qui présentait une erreur notable de 0,1 g.

Pour résoudre ce problème, nous devons étalonner l'accéléromètre à l'aide des 3 registres d'étalonnage de décalage, et voici comment nous pouvons le faire. Nous devons donc positionner le capteur à plat et imprimer les valeurs RAW sans les diviser par 256.

À partir de là, nous pouvons maintenant remarquer à quel point les sorties sont désactivées, dans mon cas, la sortie Z était d'environ 283. C'est une différence de 27 en positif. Maintenant, nous devons diviser cette valeur par 4, et cela donnera le nombre que nous devons écrire dans le registre de décalage de l'axe Z. Si nous téléchargeons le code maintenant, la sortie de l'axe Z sera exactement de 256, ou 1g comme il se doit.

// This code goes in the SETUP section
// Off-set Calibration
  //X-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1E);  // X-axis offset register
  Wire.write(1);
  Wire.endTransmission();
  delay(10);
  //Y-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1F); // Y-axis offset register
  Wire.write(-2);
  Wire.endTransmission();
  delay(10);
  
  //Z-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x20); // Z-axis offset register
  Wire.write(-7);
  Wire.endTransmission();
  delay(10);Code language: Arduino (arduino)

Si nécessaire, nous devrions calibrer l'autre axe en utilisant la même méthode. Et juste une note rapide que cet étalonnage n'est pas écrit en permanence dans les registres. Nous devons écrire ces valeurs dans les registres à chaque mise sous tension du capteur.

Une fois que nous avons terminé l'étalonnage, nous pouvons enfin calculer le roulis et le tangage, ou la rotation autour de l'axe X et la rotation autour de l'axe Y en degrés, en utilisant ces deux formules.

// Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
  roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
  pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;Code language: Arduino (arduino)

Pour plus de détails sur le fonctionnement de ces formules, vous pouvez consulter cette note d'application Freescale Semiconductor.

Suivi de l'orientation de l'accéléromètre Arduino et ADXL345 - Visualisation 3D

Ok, faisons maintenant l'exemple de visualisation 3D de l'accéléromètre.

Nous utilisons donc le même code, qui envoie les valeurs de roulis et de tangage via le port série. Voici le code Arduino complet :

/*
    Arduino and ADXL345 Accelerometer - 3D Visualization Example 
     by Dejan, https://howtomechatronics.com
*/
#include <Wire.h>  // Wire library - used for I2C communication

int ADXL345 = 0x53; // The ADXL345 sensor I2C address

float X_out, Y_out, Z_out;  // Outputs
float roll,pitch,rollF,pitchF=0;

void setup() {
  Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
 
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // Bit D3 High for measuring enable (8dec -> 0000 1000 binary)
  Wire.endTransmission();
  delay(10);

  //Off-set Calibration
  //X-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1E);
  Wire.write(1);
  Wire.endTransmission();
  delay(10);
  //Y-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1F);
  Wire.write(-2);
  Wire.endTransmission();
  delay(10);

  //Z-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x20);
  Wire.write(-9);
  Wire.endTransmission();
  delay(10);
}

void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read() | Wire.read() << 8); // X-axis value
  X_out = X_out / 256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value
  Y_out = Y_out / 256;
  Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value
  Z_out = Z_out / 256;

  // Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
  roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
  pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;

  // Low-pass filter
  rollF = 0.94 * rollF + 0.06 * roll;
  pitchF = 0.94 * pitchF + 0.06 * pitch;

  Serial.print(rollF);
  Serial.print("/");
  Serial.println(pitchF);
}Code language: Arduino (arduino)

Maintenant, dans l'environnement de développement Processing, nous devons recevoir ces valeurs et les utiliser pour faire pivoter l'objet 3D que nous allons créer. Voici le code de traitement complet :

/*
    Arduino and ADXL345 Accelerometer - 3D Visualization Example 
     by Dejan, https://howtomechatronics.com
*/

import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;

Serial myPort;

String data="";
float roll, pitch;

void setup() {
  size (960, 640, P3D);
  myPort = new Serial(this, "COM8", 9600); // starts the serial communication
  myPort.bufferUntil('\n');
}

void draw() {
  translate(width/2, height/2, 0);
  background(33);
  textSize(22);
  text("Roll: " + int(roll) + "     Pitch: " + int(pitch), -100, 265);

  // Rotate the object
  rotateX(radians(roll));
  rotateZ(radians(-pitch));
  
  // 3D 0bject
  textSize(30);  
  fill(0, 76, 153);
  box (386, 40, 200); // Draw box
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);

  //delay(10);
  //println("ypr:\t" + angleX + "\t" + angleY); // Print the values to check whether we are getting proper values
}

// Read data from the Serial Port
void serialEvent (Serial myPort) { 
  // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
  data = myPort.readStringUntil('\n');

  // if you got any bytes other than the linefeed:
  if (data != null) {
    data = trim(data);
    // split the string at "/"
    String items[] = split(data, '/');
    if (items.length > 1) {

      //--- Roll,Pitch in degrees
      roll = float(items[0]);
      pitch = float(items[1]);
    }
  }
}Code language: Arduino (arduino)

Description : Donc ici, nous devons inclure la bibliothèque série, définir le port série et le débit en bauds qui doit correspondre au débit en bauds de l'esquisse Arduino téléchargée. Ensuite, nous lisons les données entrantes et les mettons dans les variables de roulis et de tangage appropriées. Dans la boucle de dessin principale, nous utilisons ces valeurs pour faire pivoter l'objet 3D, et dans ce cas, c'est une simple boîte avec une couleur particulière et un texte dessus.

Si nous exécutons l'esquisse, l'objet 3D apparaîtra et il suivra l'orientation du capteur de l'accéléromètre. Nous pouvons remarquer ici que l'objet est en fait un peu tremblant et c'est parce que l'accéléromètre capture non seulement la force gravitationnelle, mais aussi de petites forces générées par les mouvements de notre main. Afin d'obtenir un résultat plus fluide, nous pouvons utiliser un simple filtre passe-bas. Ici, j'ai implémenté un tel filtre dans le code Arduino, qui prend 94 % de l'état précédent et ajoute 6 % de l'état ou de l'angle actuel.

// Low-pass filter
  rollF = 0.94 * rollF + 0.06 * roll;
  pitchF = 0.94 * pitchF + 0.06 * pitch;Code language: Arduino (arduino)

Avec ce filtre, nous pouvons remarquer que l'objet se déplace beaucoup plus facilement maintenant, mais il y a aussi un effet secondaire et c'est une réactivité plus lente. Nous pouvons également remarquer qu'il nous manque le lacet, ou la rotation autour de l'axe Z. En utilisant uniquement les données de l'accéléromètre à 3 axes, nous ne sommes pas en mesure de calculer le lacet.

Pour ce faire et améliorer les performances globales de notre capteur de suivi d'orientation, nous devons en fait inclure un capteur supplémentaire, un gyroscope, et fusionner ses données avec l'accéléromètre.

Ainsi, nous pouvons soit utiliser l'accéléromètre ADXL345 en combinaison avec un capteur de gyroscope, soit utiliser l'IMU MPU6050 qui a à la fois un accéléromètre 3 axes et un gyroscope 3 axes intégrés sur une seule puce. Vous trouverez un tutoriel plus détaillé sur ce capteur dans ma prochaine vidéo.

J'espère que vous avez apprécié ce tutoriel et appris quelque chose de nouveau. N'hésitez pas à poser des questions dans la section des commentaires ci-dessous et n'oubliez pas de consulter ma collection de projets Arduino.


Processus de fabrication

  1. Contrôle du servomoteur avec Arduino et MPU6050
  2. module GPS u-blox LEA-6H 02 avec Arduino et Python
  3. Comment lire la température et l'humidité sur Blynk avec DHT11
  4. Reconnaissance et synthèse vocales avec Arduino
  5. Comment faire de la musique avec un Arduino
  6. Comment utiliser NMEA-0183 avec Arduino
  7. Comment utiliser Modbus avec Arduino
  8. Machine à café intelligente avec Arduino et Bluetooth
  9. Lumière intelligente animée avec Alexa et Arduino