Calibration MPU 6050 GY 521

Bonjour,

Dans le cadre d’un projet scolaire nous avons besoin de récupérer des données d’accéleration. Pour cela nous utilisons une carte arduino nano et un capteur GY 521.

Nous parvenons bien à récupérer des données, cependant, lorsque nous nous plaçons sur la plage de données ±16G, nos valeurs sont toutes affectées par un facteur 0.5.

En effet la datasheet nous indique que pour obtenir la valeur en G nous devons diviser la donnée brute par 2048, or afin afin d’obtenir une valeur d’1G selon l’axe Y lorsque notre capteur est bien à la verticale ou de 1G selon X lorsqu’il est bien à l’horizontale, nous devons diviser la donnée brute par 1024.

Ce qui biensur pose problème car cela signifierait que nous avons des valeurs pouvant atteindre 32G et non 16G.

Nous avons établi notre code à partir d’exemples trouvés sur internet, ce qui nous a peut-être porté préjudiece. Peut être nous n’effectuons pas une bonne calibration, ou peut etre le capteur est il endommagé.

Ci-dessous le code allégé.

#define LEDPIN   2

#include <Wire.h>
#include "rgb_lcd.h"

#define MPU6050 0x68              //Device address (standard)
#define ACCEL_CONFIG 0x1C         //Accelerometer configuration address
#define GYRO_CONFIG 0x1B          //Gyro configuration address

//Registers: Accelerometer, Temp, Gyroscope
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48

#define PWR_MGMT_1 0x6B
#define PWR_MGMT_2 0x6C


//Sensor output scaling
#define accSens 3          // 0 = 2g, 1 = 4g, 2 = 8g, 3 = 16g



int16_t  AcX, AcY, GyZ;       // acceleration en x et y, angle en z

int nbpas=0;
boolean detectpas = true;
rgb_lcd lcd;


void setup() {
  
  pinMode (LEDPIN, OUTPUT);
  Serial.begin(57600);

    lcd.begin(16, 2);
    lcd.setRGB(255, 0, 0);
    
  
  setup();    
}

void loop() {
  
    
    angle_calc();
    Serial.println("--------------- Nouvelle Mesure ---------------");
    

}

//------------------------------------------------------------------
//Robot angle calculations------------------------------------------
//------------------------------------------------------------------

void writeTo(byte device, byte address, byte value) {
  Wire.beginTransmission(device);
  Wire.write(address);
  Wire.write(value);
  Wire.endTransmission(true);
}



//setup MPU6050
void setup()
{
  Wire.begin();
  delay (100);
  writeTo(MPU6050, PWR_MGMT_1, 0);
  writeTo(MPU6050, ACCEL_CONFIG, accSens << 3); // Specifying output scaling of accelerometer
  delay (100);
  Serial.println("setup done !");
}


//calculate robot tilt angle
void angle_calc()
{
  // read raw accel/gyro measurements from device
  Wire.beginTransmission(MPU6050);
  Wire.write(0x3B);                  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050, 4, true);  // request a total of 4 registers
  AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  Wire.beginTransmission(MPU6050);
  Wire.write(0x47);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050, 2, true);  // request a total of 2 registers
  GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)


float testy = AcY/1024.0;
float testx = AcX/1024.0;


  Serial.print("AcX = "); Serial.print(testx); Serial.print("\t");
                                                                                                                                         

}

Merci d’avance pour votre aide

void setup() {
  pinMode (LEDPIN, OUTPUT);
  Serial.begin(57600);
  lcd.begin(16, 2);
  lcd.setRGB(255, 0, 0);  
  setup();    // <<==== C'EST QUOI CA ??
}

Il y a même un second void setup() plus bas… Je pense que c’est la fonction appelée dans cette fameuse ligne. Il faut changer le nom :

void setup() {
  pinMode (LEDPIN, OUTPUT);
  Serial.begin(57600);
  lcd.begin(16, 2);
  lcd.setRGB(255, 0, 0);  
  setupMPU();    // <<==== NOM CHANGE
}

et

//setup MPU6050
void setupMPU()   // <<==== NOM CHANGE AUSSI
{
  Wire.begin();
  delay (100);
  writeTo(MPU6050, PWR_MGMT_1, 0);
  writeTo(MPU6050, ACCEL_CONFIG, accSens << 3); // Specifying output scaling of accelerometer
  delay (100);
  Serial.println("setup done !");
}

Excusez moi j'ai voulu simplifier le code avant de le poster sur le forum afin de le rendre plus lisible et je me suis trompé en renommant certaines fonctions. Le deuxième void setup est celui appelé dans le premier void setup, il devrait en effet s'appeller mpu_setup.

J'ai cependant eu l'occasion de me documenter un peu sur ce problème et en fouillant sur divers forums j'ai pu trouver des personnes ayant le meme soucis mais aucune solution concrète.

https://forum.sparkfun.com/viewtopic.php?t=30624

1024, 2048 ça ressemble à un ADC sur 10 bits. Dans ce cas ce serait bien 1024 et le 2048 serait simplement une erreur...

lesept:
1024, 2048 ça ressemble à un ADC sur 10 bits. Dans ce cas ce serait bien 1024 et le 2048 serait simplement une erreur…

Non le MPU-6050 contient bien de quoi faire du 16 bits analogique et la spec dit qu’en réglage ±16g vous avez 2048 LSB/g

doc.png

En français:

si vous configurez le MPU pour lire une accélération entre -16g et +16g, l’amplitude est de 32g que vous allez représentez avec leur ADC qui fonctionne sur 16 bits.

Sur 16 bits on représente des valeurs entre 0 et 65535 mais la doc dit qu’on travaille en complément à 2. donc on va travailler entre −2(16 − 1) à 2(16 − 1) − 1, c’est à dire entre -32768 à 32767

donc -16g détecté, le registre contiendra -32768 et pour +16g détecté 32767

donc pour 1g le registre contiendra 32767/16 = ~2048 → on retrouve bien ce que dit la doc (ou alors on représente 32g d’amplitude sur 65536 valeurs → 65536 / 32 = 2048 valeurs par g)

en fait ce post explique ce qu'il en est

vous avez une unité qui a un échantillon d'engineering qui n'est pas configuré comme dans la spec

Merci pour vos réponses,

J-M-L en effet c'est ce que j'avais finalement compris. Cependant impossible de trouver la documentation associée à ce capteur.. pensez vous qu'il s'agisse d'un capteur pouvant opérer sur la plage de -32/+32G?

Bof ils mentionnent

I read in the Invensense developers forum that this part should only be used with full-scale range selected as ±8 g (AFS_SEL=2). Another significant difference of this part is that the accelerometer may have very large bias errors.

donc à voir....

D'accord.

Nous allons voir avec nos encadrants afin de changer de capteur dans ce cas

Merci beaucoup de votre réponse