Boussole avec LIS3MDL, LSM6DS3 et Madgwick sur ESP32

Bonjour à tous,

J'ai comme projet de faire une boussole numérique qui affiche les degrés de 0 à 360 à l'aide des composants LIS3MDL, LSM6DS3 et Madgwick sur ESP32. Le problème est que je n'arrive vraiment pas à avoir un résultat fiable, j'ai essayé de nombreuses méthodes mais soit la boussole ne fonctionne pas bien (valeur incorrecte du style il m'indique le sud alors qu'il est à l'est) soit les valeurs restent entre 100 et 200 soit la valeur de la boussole à tendance à dériver et n'est donc plus à sa position initiale qui était correcte (le nord au nord) ce qui est le cas de ce code :

#include <Adafruit_ISM330DHCX.h>
#include <Adafruit_LSM6DS.h>
#include <Adafruit_LSM6DS3.h>
#include <Adafruit_LSM6DS33.h>
#include <Adafruit_LSM6DS3TRC.h>
#include <Adafruit_LSM6DSL.h>
#include <Adafruit_LSM6DSO32.h>
#include <Adafruit_LSM6DSOX.h>
#include <MadgwickAHRS.h>
#include <Adafruit_LIS3MDL.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

// Capteurs
Adafruit_LSM6DS3 imu;
Adafruit_LIS3MDL mag;

// Algorithme de fusion
Madgwick filter;

// Fréquence de mise à jour (en Hz)
float samplingRate = 150.0;
unsigned long lastUpdate = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial);

  // Init IMU
  if (!imu.begin_I2C(0x6B)) {
    Serial.println("Erreur LSM6DS3 !");
    while (1);
  }

  // Init Magnétomètre
  if (!mag.begin_I2C(0x1E)) {
    Serial.println("Erreur LIS3MDL !");
    while (1);
  }

  // Réglage magnétomètre (valeurs recommandées par Adafruit)
  mag.setPerformanceMode(LIS3MDL_MEDIUMMODE);
  mag.setOperationMode(LIS3MDL_CONTINUOUSMODE);
  mag.setDataRate(LIS3MDL_DATARATE_155_HZ);
  mag.setRange(LIS3MDL_RANGE_4_GAUSS);

  // Init Madgwick
  filter.begin(samplingRate);
}

void loop() {
  unsigned long now = millis();
  if (now - lastUpdate < 1000.0 / samplingRate) return;
  lastUpdate = now;

  sensors_event_t accel, gyro, temp;
  sensors_event_t mag_event;

  imu.getEvent(&accel, &gyro, &temp);
  mag.getEvent(&mag_event);

  // Convertir les valeurs en unités standard
  float ax = accel.acceleration.x;
  float ay = accel.acceleration.y;
  float az = accel.acceleration.z;

  float gx = gyro.gyro.x * 180 / PI; // °/s
  float gy = gyro.gyro.y * 180 / PI;
  float gz = gyro.gyro.z * 180 / PI;

  float mx = mag_event.magnetic.x;
  float my = mag_event.magnetic.y;
  float mz = mag_event.magnetic.z;

  // Mise à jour du filtre
  filter.update(gx, gy, gz, ax, ay, az, mx, my, mz);

  // Extraction de l’orientation (yaw = azimut)
  float heading = filter.getYaw();

  // Correction pour avoir une boussole entre 0° et 360°
  if (heading < 0) heading += 360.0;

  Serial.print("Boussole (degré): ");
  Serial.println(heading);
}

Je bloque depuis 1 semaine cette boussole commence à me rendre fou :face_with_steam_from_nose:

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Bonjour 0_erwan_0

Je ne connais pas ce matériel et ne peut pas donc t'aider directement :wink:

J'ai posé ta question à ChatGPT, je te laisse lire sa réponse.

PS: Ce lien ne sera pas disponible en permanence.

Cordialement
jpbbricole