Mesure d'angle MPU9250 + Arduino Uno
laurentcouty
14 Messages
Le lundi 15 mars 2021 à 20:47:26
Bonjour,
Dans mon projet de datalogger pour moto.
J'ai donc en matériel un MPU9250 (grove) et un Arduino Uno.
J'ai repris finalement l'intégralité du code du chapitre dédié a la mesure d'angle du site.
J'ai adapté un peu le code pour tout mettre dans le main (je sais c'est sale...)
Mais bon...
Mon problème est que le résultat des valeurs d'angle du gyro sont de 12,... Pour un angle de 90°.
J'ai pensé à la calibration de l'IMU mais en débutant j'ai les bonnes valeurs ente -500 et +500 en vitesse....
Donc je pense avoir un soucis pour intégrer.... J'ai vérifié j'ai bien mis 250hz soit 0,004s et c'est là que j'ai surment un problème ! Mon programme s'exécute (le main) en 0,0378s ... Donc j'ai essayé de baisser la fréquence à 25hz et là le problème est que le programme ne s'exécute pas en 0,040s donc là boucle d'attente a la fin ne fonctionne pas...
J'ai essayé d'écrire dans mon debug "wait" une fois dans la boucle pour faire pattienter... Mais je n'en ressort jamais.... Aurais-je loupé une étape ?
Help?
Dans mon projet de datalogger pour moto.
J'ai donc en matériel un MPU9250 (grove) et un Arduino Uno.
J'ai repris finalement l'intégralité du code du chapitre dédié a la mesure d'angle du site.
J'ai adapté un peu le code pour tout mettre dans le main (je sais c'est sale...)
Mais bon...
Mon problème est que le résultat des valeurs d'angle du gyro sont de 12,... Pour un angle de 90°.
J'ai pensé à la calibration de l'IMU mais en débutant j'ai les bonnes valeurs ente -500 et +500 en vitesse....
Donc je pense avoir un soucis pour intégrer.... J'ai vérifié j'ai bien mis 250hz soit 0,004s et c'est là que j'ai surment un problème ! Mon programme s'exécute (le main) en 0,0378s ... Donc j'ai essayé de baisser la fréquence à 25hz et là le problème est que le programme ne s'exécute pas en 0,040s donc là boucle d'attente a la fin ne fonctionne pas...
J'ai essayé d'écrire dans mon debug "wait" une fois dans la boucle pour faire pattienter... Mais je n'en ressort jamais.... Aurais-je loupé une étape ?
Help?
Le mardi 16 mars 2021 à 08:55:19
Salut,
L'IMU fonctionne à une fréquence de 250 Hz pour être compatible avec l'asservissement du drone. Dans le cas de ton datalogger as-tu besoin d'une telle fréquence d'échantillonnage ?
Si non, je te conseille cet article qui sera sans doute plus adapté : https://www.firediy.fr/article/calibrer-le-capteur-mpu6050-avec-un-arduino-drone-ch-5
L'IMU fonctionne à une fréquence de 250 Hz pour être compatible avec l'asservissement du drone. Dans le cas de ton datalogger as-tu besoin d'une telle fréquence d'échantillonnage ?
Si non, je te conseille cet article qui sera sans doute plus adapté : https://www.firediy.fr/article/calibrer-le-capteur-mpu6050-avec-un-arduino-drone-ch-5
laurentcouty
14 Messages
Le mardi 16 mars 2021 à 16:53:06
Mince je croyais avoir répondu!
Donc c'est bon j'ai réussi à adapter le code! Je comprends pas vraiment pourquoi ca marchait pas...
En tout cas, les "serial.print" ca consomme énormément de temps
Donc c'est bon j'ai réussi à adapter le code! Je comprends pas vraiment pourquoi ca marchait pas...
En tout cas, les "serial.print" ca consomme énormément de temps
laurentcouty
14 Messages
Le mardi 16 mars 2021 à 17:08:52
#include "Wire.h"
#include "MPU9250.h"
#include "BMP280.h"
#include "I2Cdev.h"
#define X 0
#define Y 1
#define Z 2
#define FREQ 25
#define SSF_GYRO 65.5
MPU9250 accelgyro;
I2Cdev I2C_M;
int16_t ax, ay, az;
int16_t gx, gy, gz;
int acc_raw[3] = {0, 0 , 0};
long acc_offset[3] = {0, 0, 0};
int gyro_raw[3] = {0, 0, 0};
long gyro_offset[3] = {0, 0, 0};
float gyro_angle[3] = {0, 0, 0};
float acc_angle[3] = {0, 0, 0};
long acc_total_vector;
boolean initialized;
unsigned long loop_timer;
unsigned long int prog_time;
unsigned int period;
void setup() {
Wire.begin();
Wire.setClock(400000);
Serial.begin(9600);
accelgyro.initialize();
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU9250 connection successful" : "MPU9250 connection failed");
// Calibration de l'IMU 9250
int max_samples = 500;
for (int i = 0; i < max_samples; i++) {
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
acc_offset[X] += (int) ax;
acc_offset[Y] += (int) ay;
acc_offset[Z] += (int) az;
gyro_offset[X] += (int) gx;
gyro_offset[Y] += (int) gy;
gyro_offset[Z] += (int) gz;
delay(2); //Delay 3us to have 250Hz for-loop
}
acc_offset[X] /= max_samples;
acc_offset[Y] /= max_samples;
acc_offset[Z] /= max_samples;
gyro_offset[X] /= max_samples;
gyro_offset[Y] /= max_samples;
gyro_offset[Z] /= max_samples;
period = (1000000 / FREQ) ;
loop_timer = micros();
}
void loop() {
// Acces données de l'acceleromètre
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// Axes Gyroscope calibrés (valeur en bits)
acc_raw[X] = (int) ax;
acc_raw[Y] = (int) ay;
acc_raw[Z] = (int) az;
gyro_raw[X] = (int) gx - gyro_offset[X];
gyro_raw[Y] = (int) gy - gyro_offset[Y];
gyro_raw[Z] = (int) gz - gyro_offset[Z];
// Valeurs des Angles du Gyroscope(intégration + bits => °/s)
gyro_angle[X] += (gyro_raw[X] / (FREQ * SSF_GYRO ));
gyro_angle[Y] += (-gyro_raw[Y] / (FREQ * SSF_GYRO ));
gyro_angle[Z] += (gyro_raw[Z] / (FREQ * SSF_GYRO ));
// Transfert si rotation autour de Z
gyro_angle[Y] += gyro_angle[X] * sin(gyro_raw[Z] * (PI / (FREQ * SSF_GYRO * 180)));
gyro_angle[X] -= gyro_angle[Y] * sin(gyro_raw[Z] * (PI / (FREQ * SSF_GYRO * 180)));
// Calcul du vecteur total
acc_total_vector = sqrt(pow(acc_raw[X], 2) + pow(acc_raw[Y], 2) + pow(acc_raw[Z], 2));
// Calcul des Angles de l'acceleromètre
if (abs(acc_raw[X]) < acc_total_vector) {
acc_angle[X] = asin((float)acc_raw[Y] / acc_total_vector) * (180 / PI);
}
if (abs(acc_raw[Y]) < acc_total_vector) {
acc_angle[Y] = asin((float)acc_raw[X] / acc_total_vector) * (180 / PI);
}
if (initialized) {
// Correct the drift of the gyro with the accelerometer
gyro_angle[X] = gyro_angle[X] * 0.9996 + acc_angle[X] * 0.0004;
gyro_angle[Y] = gyro_angle[Y] * 0.9996 + acc_angle[Y] * 0.0004;
gyro_angle[Z] = gyro_angle[Z] * 0.9996 + acc_angle[Z] * 0.0004;
}
else {
// At very first start, init gyro angles with accelerometer angles
gyro_angle[X] = acc_angle[X];
gyro_angle[Y] = acc_angle[Y];
gyro_angle[Z] = acc_angle[Z];
initialized = true;
}
while(micros() - loop_timer < period){
Serial.println("waiting");
}
loop_timer = micros();
}
Le mardi 16 mars 2021 à 21:07:37
Ah cool, bonne nouvelle !
Oui, les serial.print() c'est loin d'être immédiat 😉
Oui, les serial.print() c'est loin d'être immédiat 😉
laurentcouty
14 Messages
Le mardi 16 mars 2021 à 22:05:53
Si quelqu'un voit des grosses incohérences dans mon code ou des choses à améliorer. Je suis preneur de tout conseil pour m'améliorer
laurentcouty
14 Messages
Le jeudi 18 mars 2021 à 15:49:43
Et je suis preneur de connaître le temps d'exécution de vos "loop" et avec quel matériel vous le faite tourner... J'ai toujours des soucis de lenteur....
Le jeudi 18 mars 2021 à 19:57:19
Ah, mais attends, tu fais un mélange entre la librairie MPU9250.h et l'implémentation manuelle de l'IMU. Du coup, c'est pas étonnant que tu ais des résultats incohérents.
Question : à quoi sert cet include ?
Dans un premier temps, laisse tomber l'IMU et utilise les fonctions offertes par la librairie MPU9250. Là, tu auras les bonnes valeurs. Par contre, si la lecture des data est trop lente, là il faudra implémenter l'IMU comme je l'ai fait avec le MPU6050.
Question : à quoi sert cet include ?
#include "BMP280.h"
Dans un premier temps, laisse tomber l'IMU et utilise les fonctions offertes par la librairie MPU9250. Là, tu auras les bonnes valeurs. Par contre, si la lecture des data est trop lente, là il faudra implémenter l'IMU comme je l'ai fait avec le MPU6050.
laurentcouty
14 Messages
Le jeudi 18 mars 2021 à 20:15:21
La différence entre la librairie MPU6050 et MPU9250 c'est la gestion du magnétomètre de ce que j'en au vue.... Mais j'ai pas trouvé de fonction qui sort directement une valeur d'angle.
Après il y a une histoire de quaternions, et j'avoue que là je perds le fils....
C'est pour ça que je me suis penché sur une implémentation comme la tienne.
BMP280.h c'est un baromètre + sonde température qui est intégré mais que je n'utilise pas.
Dans la librairie MPU6050, il ya une fonction qui permet de sortir directement les valeurs d'angles?
Après il y a une histoire de quaternions, et j'avoue que là je perds le fils....
C'est pour ça que je me suis penché sur une implémentation comme la tienne.
BMP280.h c'est un baromètre + sonde température qui est intégré mais que je n'utilise pas.
Dans la librairie MPU6050, il ya une fonction qui permet de sortir directement les valeurs d'angles?
Le jeudi 18 mars 2021 à 20:19:28
Yes, regarde cet article : https://www.firediy.fr/article/calibrer-le-capteur-mpu6050-avec-un-arduino-drone-ch-5