Program using DMP to get filtered values

I have the code below but I want to use DMP because the drift is too much and I tried implementing complementary filter but the outcome did not seem convincing to me. Can someone help me use DMP without changing the settings like DLPF and interrupt. I want to keep majority on the code here and only implement the DMP to get more accurate values. It is also possible to implement a complementary filter. I implemented it but it did not work for me.

  1. I will also like to keep the sample rate at 35.2 Hz.

  2. I will like to also use interrupt when new data is available. I dont know if there is an interrupt for DMP, but would the interrupt for raw_data_available work as well?

Thank you in advance. :smiley: :smiley:

const int FIRMWARE_VERSION_MAJOR = 1;
const int FIRMWARE_VERSION_MINOR = 7;
// OLA Specifics:
const byte PIN_IMU_POWER = 27; // The Red SparkFun version of the OLA (V10) uses pin 27
//const byte PIN_IMU_POWER = 22; // The Black SparkX version of the OLA (X04) uses pin 22
const byte PIN_IMU_INT = 37;
const byte PIN_IMU_CHIP_SELECT = 44;
const byte PIN_PWR_LED = 29;
const byte PIN_STAT_LED = 19;
const byte PIN_TRIGGER = 11;
#define OLA_IDENTIFIER 0x117
#define HARDWARE_VERSION_MAJOR 1
#define HARDWARE_VERSION_MINOR 0



uint8_t count = 1;
uint8_t csum;
uint8_t imu_id = 17;

uint32_t baudrate = 230400;



  float x_accel;
  float y_accel;
  float z_accel;

  float x_gyro;
  float y_gyro;
  float z_gyro;



#define MISO 6
#include "ICM_20948.h"  // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU

#define USE_SPI       // Uncomment this to use SPI 

#define SERIAL_PORT Serial

#define SPI_PORT SPI    // Your desired SPI port.       Used only when "USE_SPI" is defined
#define CS_PIN PIN_IMU_CHIP_SELECT // Which pin you connect CS to. Used only when "USE_SPI" is defined. OLA uses pin 44.

#define WIRE_PORT Wire  // Your desired Wire port.      Used when "USE_SPI" is not defined
#define AD0_VAL   1     // The value of the last bit of the I2C address. 
                        // On the SparkFun 9DoF IMU breakout the default is 1, and when 
                        // the ADR jumper is closed the value becomes 0

#ifdef USE_SPI
  ICM_20948_SPI myICM;  // If using SPI create an ICM_20948_SPI object
#else
  ICM_20948_I2C myICM;  // Otherwise create an ICM_20948_I2C object
#endif

// Some vars to control or respond to interrupts
volatile bool isrFired = false;
volatile bool sensorSleep = false;


void setup() {
  
  powerLEDOn(); // Turn the power LED on - if the hardware supports it
  pinMode(PIN_STAT_LED, OUTPUT);
  digitalWrite(PIN_STAT_LED, HIGH);

  Serial.begin(baudrate); //Default for initial debug messages if necessary
  //Serial.println();
//  Serial.flush();
//  while (Serial.available()){
//    Serial.read(); // remove 1 character
//  }

  
#ifdef USE_SPI
    SPI_PORT.begin();
#else
    WIRE_PORT.begin();
    WIRE_PORT.setClock(400000);
#endif
  
  enableCIPOpullUp(); // Enable CIPO pull-up on the OLA

  pinMode(PIN_IMU_INT, INPUT_PULLUP);   // Using a pullup b/c ICM-20948 Breakout board has an onboard pullup as well and we don't want them to compete
  attachInterrupt(digitalPinToInterrupt(PIN_IMU_INT), icmISR, FALLING); // Set up a falling interrupt

  //beginIMU();
  pinMode(PIN_IMU_POWER, OUTPUT);
  pinMode(PIN_IMU_CHIP_SELECT, OUTPUT);
  digitalWrite(PIN_IMU_CHIP_SELECT, HIGH); //Be sure IMU is deselected
  //Serial.println("HELLO");

  //Reset ICM by power cycling it
  imuPowerOff();
  delay(10);
  imuPowerOn(); // Enable power for the OLA IMU
  delay(100); // Wait for the IMU to power up
  SERIAL_PORT.begin(baudrate);
  while(!SERIAL_PORT){};

  bool initialized = false;
  while( !initialized ){

#ifdef USE_SPI
    myICM.begin( CS_PIN, SPI_PORT ); 
#else
    myICM.begin( WIRE_PORT, AD0_VAL );
#endif
    
  if( myICM.status != ICM_20948_Stat_Ok ){
  //SERIAL_PORT.println( "Trying again..." );
  delay(500);
  }else{
   initialized = true;
  }
 }
  digitalWrite(PIN_STAT_LED, LOW); // Turn the STAT LED off now that everything is configured
  
  // Here we are doing a SW reset to make sure the device starts in a known state
  myICM.swReset( );
  if( myICM.status != ICM_20948_Stat_Ok){
    //SERIAL_PORT.print(F("Software Reset returned: "));
    //SERIAL_PORT.println(myICM.statusString());
  }
  delay(250);

  // Now wake the sensor up
  myICM.sleep( sensorSleep );
  myICM.lowPower( false );

  // The next few configuration functions accept a bit-mask of sensors for which the settings should be applied.

  // Set Gyro and Accelerometer to a particular sample mode
  // options: ICM_20948_Sample_Mode_Continuous
  //          ICM_20948_Sample_Mode_Cycled
  myICM.setSampleMode( (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Continuous);
  
  ICM_20948_smplrt_t mySmplrt;
  mySmplrt.a = 31;  // specify the accel sample rate to maximum: see Table 19 in datasheet DS-000189-ICM-20948-v1.3.pdf - as
  mySmplrt.g = 31;  // specify the gyro sample rate to maximum: see Table 17 in datasheet DS-000189-ICM-20948-v1.3.pdf  - as 
  myICM.setSampleRate( ICM_20948_Internal_Acc, mySmplrt );
  myICM.setSampleRate( ICM_20948_Internal_Gyr, mySmplrt );

  ICM_20948_dlpcfg_t myDLPcfg; 
  myDLPcfg.a = acc_d473bw_n499bw;
  myDLPcfg.g = gyr_d361bw4_n376bw5;
  myICM.setDLPFcfg( (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myDLPcfg );

//     // replies only when you receive data:
//  while (!Serial.find("Start Sensor")) {}
  
  /*
  if( myICM.status != ICM_20948_Stat_Ok){
    SERIAL_PORT.print(F("setDLPcfg returned: "));
    SERIAL_PORT.println(myICM.statusString());
  }
  
  */

  //delay(5000);
  // Choose whether or not to use DLPF
  // Here we're also showing another way to access the status values, and that it is OK to supply individual sensor masks to these functions
  ICM_20948_Status_e accDLPEnableStat = myICM.enableDLPF( ICM_20948_Internal_Acc, true );
  ICM_20948_Status_e gyrDLPEnableStat = myICM.enableDLPF( ICM_20948_Internal_Gyr, true );

  
  myICM.cfgIntActiveLow(true);                      // Active low to be compatible with the breakout board's pullup resistor
  myICM.cfgIntOpenDrain(false);                     // Push-pull, though open-drain would also work thanks to the pull-up resistors on the breakout
  myICM.cfgIntLatch(false);                          // Latch the interrupt until cleared
  myICM.intEnableRawDataReady(true);                // enable interrupts on raw data ready

}


void loop() {

   // replies only when you receive data:
//  if (Serial.available() > 0) {
//    // read the incoming byte:
//    if (Serial.find("SEND ME SENSOR_ID")) {
//    // say what you got:
//      Serial.print("\n imu_id:="+String(imu_id) + " \n");
//      Serial.end();
//    }
//  }
    
//  Check for a trigger event
  if( isrFired ){                       // If our isr flag is set then clear the interrupts on the ICM
    isrFired = false;


    x_accel = (myICM.agmt.acc.axes.x/16384);
  y_accel = (myICM.agmt.acc.axes.y/16384);
  z_accel = (myICM.agmt.acc.axes.z/16384);

  x_gyro = myICM.agmt.gyr.axes.x/131.0;
  y_gyro = myICM.agmt.gyr.axes.y/131.0;
  z_gyro = myICM.agmt.gyr.axes.z/131.0;
    //getData(count);
  }
    
}


void imuPowerOn()
{
  pinMode(PIN_IMU_POWER, OUTPUT);
  digitalWrite(PIN_IMU_POWER, HIGH);
}
void imuPowerOff()
{
  pinMode(PIN_IMU_POWER, OUTPUT);
  digitalWrite(PIN_IMU_POWER, LOW);
}

void powerLEDOn()
{
#if(HARDWARE_VERSION_MAJOR >= 1)
  pinMode(PIN_PWR_LED, OUTPUT);
  digitalWrite(PIN_PWR_LED, HIGH); // Turn the Power LED on
#endif
}

bool enableCIPOpullUp()
{
  //Add CIPO pull-up
  ap3_err_t retval = AP3_OK;
  am_hal_gpio_pincfg_t cipoPinCfg = AP3_GPIO_DEFAULT_PINCFG;
  cipoPinCfg.uFuncSel = AM_HAL_PIN_6_M0MISO;
  cipoPinCfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA;
  cipoPinCfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL;
  cipoPinCfg.uIOMnum = AP3_SPI_IOM;
  cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K;
  padMode(MISO, cipoPinCfg, &retval);
  return (retval == AP3_OK);
}
//Trigger Pin ISR
void icmISR( void ){
  isrFired = true; 
  count++;                    // Can't use I2C within ISR on 328p, so just set a flag to know that data is available
}
void powerLEDOff()
{
#if(HARDWARE_VERSION_MAJOR >= 1)
  pinMode(PIN_PWR_LED, OUTPUT);
  digitalWrite(PIN_PWR_LED, LOW); // Turn the Power LED off
#endif
}