adafruit / Adafruit_AHRS

Arduino library for AHRS (Attitude and Heading Reference System) for Adafruit motion sensors
214 stars 64 forks source link

Update code to work with the LSM9DS1 #6

Closed lcipolina closed 4 years ago

lcipolina commented 4 years ago

The code for AHRS should be updated to be able to do sensor fusion work with the newest version of the chip. This is the code to change https://github.com/adafruit/Adafruit_AHRS/blob/master/examples/ahrs_fusion_usb/ahrs_fusion_usb.ino

ladyada commented 4 years ago

yeah this library needs a big cleanup. is that something you'd like to PR? :)

lcipolina commented 4 years ago

Thank you for replying. I can take a look, yes. First the magnetometer script needs to be updated (to do the mag calibration) Then this code should be further adapted for the S1

ladyada commented 4 years ago

thank you it would be most appreciated :)

outlandnish commented 4 years ago

@ladyada @lcipolina I've got a version of the code running with a modified version of the SparkFun LSM9DS1 library. Is it alright if I PR that version or would you prefer that any PR uses the Adafruit LSM9DS1 library that uses the Adafruit Sensors interface?

ladyada commented 4 years ago

either/both ways appreciated :)

outlandnish commented 4 years ago

Here's the calibration code using my fork of the SparkFun LSM9DS1 library. The lowest fit error I can achieve is 12% in the PJRC MotionCal app for my custom hardware. If you can get a better result by tweaking the parameters, please let me know!

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>

#define ST_LSM303DLHC_L3GD20        (0)
#define ST_LSM9DS1                  (1)
#define NXP_FXOS8700_FXAS21002      (2)

// Define your target sensor(s) here based on the list above!
// #define AHRS_VARIANT    ST_LSM303DLHC_L3GD20
#define AHRS_VARIANT   ST_LSM9DS1

// Include appropriate sensor driver(s)
#if AHRS_VARIANT == ST_LSM303DLHC_L3GD20
#include <Adafruit_L3GD20_U.h>
#include <Adafruit_LSM303_U.h>
#elif AHRS_VARIANT == ST_LSM9DS1
#include <SparkFunLSM9DS1.h>
#define AG_ADDRESS  0x6B
#define MAG_ADDRESS 0x1E
#elif AHRS_VARIANT == NXP_FXOS8700_FXAS21002
#include <Adafruit_FXAS21002C.h>
#include <Adafruit_FXOS8700.h>
#else
#error "AHRS_VARIANT undefined! Please select a target sensor combination!"
#endif

// Create sensor instances.
#if AHRS_VARIANT == ST_LSM303DLHC_L3GD20
Adafruit_L3GD20_Unified       gyro(20);
Adafruit_LSM303_Accel_Unified accel(30301);
Adafruit_LSM303_Mag_Unified   mag(30302);
#elif AHRS_VARIANT == ST_LSM9DS1
LSM9DS1 imu;
#elif AHRS_VARIANT == NXP_FXOS8700_FXAS21002
Adafruit_FXAS21002C gyro = Adafruit_FXAS21002C(0x0021002C);
Adafruit_FXOS8700 accelmag = Adafruit_FXOS8700(0x8700A, 0x8700B);
#endif

// NOTE: THIS IS A WORK IN PROGRESS!

// This sketch can be used to output raw sensor data in a format that
// can be understoof by MotionCal from PJRC. Download the application
// from http://www.pjrc.com/store/prop_shield.html and make note of the
// magentic offsets after rotating the sensors sufficiently.
//
// You should end up with 3 offsets for X/Y/Z, which are displayed
// in the top-right corner of the application.

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

  // Wait for the Serial Monitor to open (comment out to run without Serial Monitor)
  // while(!Serial);

  Serial.println(F("Adafruit nDOF AHRS Calibration Example")); Serial.println("");

#if AHRS_VARIANT == NXP_FXOS8700_FXAS21002 || AHRS_VARIANT == ST_LSM303DLHC_L3GD20
  // Initialize the sensors.
  if(!gyro.begin())
  {
    /* There was a problem detecting the gyro ... check your connections */
    Serial.println("Ooops, no gyro detected ... Check your wiring!");
    while(1);
  }
#endif

#if AHRS_VARIANT == ST_LSM9DS1
  Wire.begin(SDA, SCL, 400 * 1000);
  if (!imu.begin(AG_ADDRESS, MAG_ADDRESS, Wire))
  {
    Serial.println("Ooops, no LSM9DS1 detected ... Check your wiring!");
    while(1);
  }
  imu.setAccelScale(4);
  imu.setGyroScale(245);
  imu.setMagScale(12);
  imu.setMagPerformanceMode(3);
  imu.setAccelODR(6);
  imu.setGyroODR(6);
  imu.setMagODR(7);
  imu.magOffset(0, 0);
  imu.magOffset(1, 0);
  imu.magOffset(2, 0);
#endif

#if AHRS_VARIANT == NXP_FXOS8700_FXAS21002
  if(!accelmag.begin(ACCEL_RANGE_4G))
  {
    Serial.println("Ooops, no FXOS8700 detected ... Check your wiring!");
    while(1);
  }
#elif AHRS_VARIANT == ST_LSM303DLHC_L3GD20
  if (!accel.begin())
  {
    /* There was a problem detecting the accel ... check your connections */
    Serial.println("Ooops, no accel detected ... Check your wiring!");
    while (1);
  }

  if (!mag.begin())
  {
    /* There was a problem detecting the mag ... check your connections */
    Serial.println("Ooops, no mag detected ... Check your wiring!");
    while (1);
  }
#endif
}

void loop(void)
{
#if AHRS_VARIANT == NXP_FXOS8700_FXAS21002 || AHRS_VARIANT == ST_LSM303DLHC_L3GD20
  sensors_event_t event; // Need to read raw data, which is stored at the same time

    // Get new data samples
    gyro.getEvent(&event);
#endif
#if AHRS_VARIANT == NXP_FXOS8700_FXAS21002
    accelmag.getEvent(&event);
#elif AHRS_VARIANT == ST_LSM303DLHC_L3GD20
    accel.getEvent(&event);
    mag.getEvent(&event);
#endif
#if AHRS_VARIANT == ST_LSM9DS1
  if (imu.accelAvailable())
    imu.readAccel();
  if (imu.gyroAvailable())
    imu.readGyro();
  if (imu.magAvailable())
    imu.readMag();
#endif

  // Print the sensor data
  Serial.print("Raw:");
#if AHRS_VARIANT == NXP_FXOS8700_FXAS21002
    Serial.print(accelmag.accel_raw.x);
    Serial.print(',');
    Serial.print(accelmag.accel_raw.y);
    Serial.print(',');
    Serial.print(accelmag.accel_raw.z);
    Serial.print(',');
#elif AHRS_VARIANT == AHRS_VARIANT == ST_LSM303DLHC_L3GD20
    Serial.print(accel.raw.x);
    Serial.print(',');
    Serial.print(accel.raw.y);
    Serial.print(',');
    Serial.print(accel.raw.z);
    Serial.print(',');
#endif

#if AHRS_VARIANT == NXP_FXOS8700_FXAS21002 || AHRS_VARIANT == ST_LSM303DLHC_L3GD20
    Serial.print(gyro.raw.x);
    Serial.print(',');
    Serial.print(gyro.raw.y);
    Serial.print(',');
    Serial.print(gyro.raw.z);
    Serial.print(',');
#endif
#if AHRS_VARIANT == NXP_FXOS8700_FXAS21002
    Serial.print(accelmag.mag_raw.x);
    Serial.print(',');
    Serial.print(accelmag.mag_raw.y);
    Serial.print(',');
    Serial.print(accelmag.mag_raw.z);
    Serial.println();
#elif AHRS_VARIANT == ST_LSM303DLHC_L3GD20
    Serial.print(mag.raw.x);
    Serial.print(',');
    Serial.print(mag.raw.y);
    Serial.print(',');
    Serial.print(mag.raw.z);
    Serial.println();
#endif
#if AHRS_VARIANT == ST_LSM9DS1
    Serial.print(imu.ax);
    Serial.print(",");
    Serial.print(imu.ay);
    Serial.print(",");
    Serial.print(imu.az);
    Serial.print(",");
    Serial.print(imu.gx);
    Serial.print(",");
    Serial.print(imu.gy);
    Serial.print(",");
    Serial.print(imu.gz);
    Serial.print(",");
    Serial.print(-imu.my);
    Serial.print(",");
    Serial.print(-imu.mx);
    Serial.print(",");
    Serial.print(imu.mz);
    Serial.println();
#endif

  delay(50);
}
ladyada commented 4 years ago

refactored library, LSM9DS1 is in there now

LazaroFilm commented 1 year ago

This example still says // ToDo! in the code under the LSM9DS1 on line 25.