Code Monkey home page Code Monkey logo

sparkfun_icm-20948_arduinolibrary's People

Contributors

adamgarbo avatar daescobarh avatar loricrotser avatar lwestfall avatar mkrawcz1 avatar paulzc avatar per1234 avatar peterleif avatar ruffner avatar spacecheese avatar threadoffate avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sparkfun_icm-20948_arduinolibrary's Issues

Fixing Drift Issues w/ Sensor Fusion (MadgwickAHRS) on an Arduino Uno

I'm still working on the MEGA to get access to the DMP, but in the meanwhile, I'm also interested in having a working orientation sensor using an Arduino Uno. I'm using the (MadgwickAHRS)[https://github.com/arduino-libraries/MadgwickAHRS] to perform the sensor fusion. I'm having some issues where the orientation drifts over time.

What can I do to remedy this?

So far this is my code:

// This is meant to be nothing more than a sketch that dumps data on the serial port
// for the python application to show/visualize.
//
// For the actual application:
//   - This should use the DMP on the chip for Sensor fusion instead of the Madgwick code
//     - Probably can't use Arduino then anymore, since the Sparkfun code breaks the Memory limits of the Arduino UNO chip
//   - Gyroscope sensitivity probably needs to be adjusted to be a little less sensitive (giving a greater DPS range)
//   - Should properly use the interrupt pin
//
// Communication protocol:  This print strings on the Serial port, at the rate of 115200 baud; it never reads data
//   It might print out status messages like "waiting for data"
//   Actual orientation data will follow the format:
//
//     HPR <heading/yaw deg> <pitch deg> <roll deg>
//
//   For example:
//
//     HPR 5.5 -10.07773 0.22000023
//

#include <Arduino.h>
#include <Wire.h>
#include <ICM_20948.h>
#include "MadgwickAHRS.h"


#define SERIAL_BAUD_RATE 115200
#define I2C_RATE 400000
#define IMU_TIMEOUT_MS 500                                                  // When there was a failure in talking to the IMU (or no data ready), how many milliseconds should we wait?
#define IMU_DATA_READING_WAIT_MS 25                                         // How many milliseconds to wait before attempting the next data reading
#define IMU_FUSION_FREQUENCY (1000.0f / float(IMU_DATA_READING_WAIT_MS))    // The sensor fusion algorithm needs to know how often the IMU is being read from
#define SERIAL_PRECISION 12                                                 // How many digits of the float to print to Serial

// TODO research this better
#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

// Using I2C to connect to the imu
ICM_20948_I2C imu;

// For orientation calculation
Madgwick filter;
float heading, pitch, roll;     // The orientation


void setup() {
    // Setup communications
    Serial.begin(SERIAL_BAUD_RATE);     // To computer
    Wire.begin();                       // To IMU
    Wire.setClock(I2C_RATE);

//    imu.enableDebugging();

    // Try to enable the IMU
    bool connected = false;
    while (!connected) {
        imu.begin(Wire, AD0_VAL);

        // Print status to serial
        Serial.print("Init connection to ICM 20948: ");
        Serial.println(imu.statusString());

        // If it didn't work, try again shortly
        if (imu.status != ICM_20948_Stat_Ok) {
            Serial.println("Try again in 500 ms");
            delay(IMU_TIMEOUT_MS);
        } else
            connected = true;
    }

    Serial.println("Connected to ICM 20948");

    // Setup filter
    filter.begin(IMU_FUSION_FREQUENCY);
}


void loop() {
    if (imu.dataReady()) {
        // Some data is ready
        imu.getAGMT();          // Retrieves data

        // Update the sensor fusion state
        filter.update(
            imu.gyrX(), imu.gyrY(), imu.gyrZ(),     // These units might be in degrees and not radiasn
            imu.accX(), imu.accY(), imu.accZ(),
            imu.magX(), imu.magY(), imu.magZ()
        );

        // Read data
        heading = filter.getYaw();
        pitch = filter.getPitch();
        roll = filter.getRoll();

        // Send Orientation data to the PC
        Serial.print("HPR ");                       // HPR = Heading, Pitch, Roll
        Serial.print(heading, SERIAL_PRECISION);
        Serial.print(" ");
        Serial.print(pitch, SERIAL_PRECISION);
        Serial.print(" ");
        Serial.print(roll, SERIAL_PRECISION);
        Serial.println("");     // End the line reading

        // Wait a little before the next reading
        delay(IMU_DATA_READING_WAIT_MS);
    } else {
        // Nothing, pause for a moment
        Serial.println("Waiting for data...");
        delay(IMU_TIMEOUT_MS);
    }
}

I made a 3D model of the breakout board and a Python (w/ Panda3D) visualization:

icm_drift.mov

The parts where the movement jerks fast is actually where I move the board. The parts where the rotation is linear is actually drift. I've before had the board completely stationary but then seen it drift slowly at the rate of about 2 deg / second, for minutes on end. I really want to eliminate this drift when using an Uno

Linear acceleration

Hi,
I'm trying to use the ICM20948 for both orientation and acceleration sensors.
With your Example7_DMP_Quat6_EulerAngles file it's easy to get the corrected orientation data.

But for the acceleration it seems more difficule.
I tryed to add the sensor linear acceleration mode for the DMP:

	success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_GAME_ROTATION_VECTOR) == ICM_20948_Stat_Ok);
	// Enable any additional sensors / features
	success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_LINEAR_ACCELERATION) == ICM_20948_Stat_Ok);

The result is that the DMP data contains now raw acceleration : data.Raw_Accel.Data

these accelerations are not corrected by the orientation of the IMU, then I can't use it directly (and I don't know how to use it !)

it seems that this configuration provide the same result as

success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_RAW_ACCELEROMETER) == ICM_20948_Stat_Ok);

Is there a way to have the x, y, z acceleration (without the 1g gravity and calibrated ) to be able to know if my sensor is moving left, right, up or down ?

thanks.

Compile error when SPI_INTERFACES_COUNT 0

Subject of the issue

Compile generates an error when SPI_INTERFACES_COUNT 0

Your workbench

Custom variants.h has no SPI ports defined.

Steps to reproduce

Edit variants.h:

// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 0

Expected behaviour

Code compiles with SPI disabled

Actual behaviour

Sketch does not compile.

error: 'SPI' was not declared in this scope
ICM_20948_Status_e begin( uint8_t csPin, SPIClass &spiPort = SPI );

Paid Support

Subject of the issue

Im making a project that automatically points a camera to a star, moon, planet, galaxy etc.

It gets the coordinates of the desired star or moon etc from stellarium (open source astronomy program), and then its supposed to use the ICM-29048 (attached to the camera) and little motors to move the camera until it points to the proper coordinates using positional feedback from the ICM-20948.

I was willing to pay someone to help me get that working using Arduino since i dont have time to do it all myself.

Please contact me at [email protected] if you are interested, and let me know your price.

Quat9 Issues with Q0 Calculations

For the Example6_DMP_Quat9_Orientation sketch, when calculating Q0 (line 376) you do:

q0 = sqrt( 1.0 - ((q1 * q1) + (q2 * q2) + (q3 * q3)));

Isn't this incorrect because q0 can be positive or negative? The equation above always makes q0 positive, which is incorrect.

I am thinking of how to solve this issue but my understand of quaternions is entry level in terms of finding Q0 from the DMP or through math with XYZ while getting the correct sign. Is there a way to get Q0 directly from the DMP like we do for Q1, Q2, and Q3?

Thank you,
Zed

In which way are the agmt values set?

Subject of the issue

I can't find/understand the way, the value of the agmt are set.

Currently I am starting the process of re purposing your library for a Raspberry 4. I am already able to get readings from accY(); and the others, now in testing the readouts they are either nonsensical or unchanging. So i am trying to understand where the values are actually "created".

Thank you for your patience.

PS.: I am only aware of your library, you don't know randomly of a raspberry library for the SparkFun_ICM-20948?

Failure to read magnetometer from DMP FIFO

Hello,

we really appreciate the simplification in this library over the original drivers from Invensense.
The hope was to use the DMP for 9-axis sensor fusion with Orientation output referenced to magnetic north.

Using example 6 (Quat9_Orientation) and 9 (MultipleSensors) as a basis, we get stable quaternion output. However, the heading always starts out at zero, and changes in the magnetic field do not seem to matter at all. Digging into this, it is quick to see that there are issues reading the magnetic sensor. If true, this might also explain some other issues posted here.

Steps to reproduce:

  • Get the Multi Sensor example 9 to work
  • Verify now other hardware or communication issues are present
  • Avoid strong magnetic fields nearby which would saturate the magnetometer
  • Make the following changes to example 9:
  1. Change enableDMPSensor from GAME_ROTATION_VECTOR to ORIENTATION (optional)
  2. Enable setDMPODRrate(DMP_ODR_Reg_Cpass, 0)
  3. Comment out all other setDMPODRrate calls (optional)

What we would expect is to receive valid magnetometer readings at 55Hz.
The magnetometer was configured to 100Hz continuous mode previously.
I do not know how the sample rate for the external I2C slave (magnetometer) is configured in the DMP.

The actual output is the following:

Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x -677.00  y -256.00  z -103.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x -661.00  y -256.00  z -107.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x -665.00  y -256.00  z -111.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00
Compass:  x 32767.00  y 32767.00  z 32767.00

There are occasional valid readings in the output, but most values are invalid.
Readings that are not 32767 change with the sensor orientation and seem to be the actual magnetic field.

No matter what other options I changed, the DMP keeps posting mostly invalid magnetometer data into the FIFO.
If this is the same data the DMP uses for 9-axis fusion, it is clear why magnetometer is not used in the Quat9 result.
So far, I did not manage to find a different library to cross-reference a possible configuration error.

Please advise if you can reproduce this behaviour.
Thank you!

Unable to compile for Arduino Nano 33 BLE

Subject of the issue

Unable to compile for Arduino Nano 33 BLE

Your workbench

  • What platform are you using? Windows 10, Arduino IDE 1.8.13 (Windows store 1.8.42.0)
  • What version of the device are you using? Is there a firmware version? Arduino Nano 33 BLE
  • How is the device wired to your platform? 3.3v, GND, SDA, SCL
  • How is everything being powered? USB from PC
  • Are there any additional details that may help us help you?

Steps to reproduce

Use an Arduino Nano 33 BLE and attempt to compile and upload the Basic example sketch provided with this library.

Expected behaviour

Should successfully compile the example sketch and upload it to the device

Actual behaviour

Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "Arduino Nano 33 BLE"

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware -hardware C:\Users\Aaron\Documents\ArduinoData\packages -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\tools-builder -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr -tools C:\Users\Aaron\Documents\ArduinoData\packages -built-in-libraries C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries -libraries C:\Users\Aaron\Documents\Arduino\libraries -fqbn=arduino:mbed:nano33ble -vid-pid=2341_805A -ide-version=10813 -build-path C:\Users\Aaron\AppData\Local\Temp\arduino_build_589287 -warnings=none -build-cache C:\Users\Aaron\AppData\Local\Temp\arduino_cache_73247 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arm-none-eabi-gcc.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\arm-none-eabi-gcc\7-2017q4 -prefs=runtime.tools.arm-none-eabi-gcc-7-2017q4.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\arm-none-eabi-gcc\7-2017q4 -prefs=runtime.tools.openocd.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\openocd\0.10.0-arduino13 -prefs=runtime.tools.openocd-0.10.0-arduino13.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\openocd\0.10.0-arduino13 -prefs=runtime.tools.dfu-util.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\dfu-util\0.9.0-arduino2 -prefs=runtime.tools.dfu-util-0.9.0-arduino2.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\dfu-util\0.9.0-arduino2 -prefs=runtime.tools.bossac.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\bossac\1.9.1-arduino2 -prefs=runtime.tools.bossac-1.9.1-arduino2.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\bossac\1.9.1-arduino2 -verbose C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\arduino-builder -compile -logger=machine -hardware C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware -hardware C:\Users\Aaron\Documents\ArduinoData\packages -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\tools-builder -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr -tools C:\Users\Aaron\Documents\ArduinoData\packages -built-in-libraries C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries -libraries C:\Users\Aaron\Documents\Arduino\libraries -fqbn=arduino:mbed:nano33ble -vid-pid=2341_805A -ide-version=10813 -build-path C:\Users\Aaron\AppData\Local\Temp\arduino_build_589287 -warnings=none -build-cache C:\Users\Aaron\AppData\Local\Temp\arduino_cache_73247 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arm-none-eabi-gcc.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\arm-none-eabi-gcc\7-2017q4 -prefs=runtime.tools.arm-none-eabi-gcc-7-2017q4.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\arm-none-eabi-gcc\7-2017q4 -prefs=runtime.tools.openocd.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\openocd\0.10.0-arduino13 -prefs=runtime.tools.openocd-0.10.0-arduino13.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\openocd\0.10.0-arduino13 -prefs=runtime.tools.dfu-util.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\dfu-util\0.9.0-arduino2 -prefs=runtime.tools.dfu-util-0.9.0-arduino2.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\dfu-util\0.9.0-arduino2 -prefs=runtime.tools.bossac.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\bossac\1.9.1-arduino2 -prefs=runtime.tools.bossac-1.9.1-arduino2.path=C:\Users\Aaron\Documents\ArduinoData\packages\arduino\tools\bossac\1.9.1-arduino2 -verbose C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino

Using board 'nano33ble' from platform in folder: C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1

Using core 'arduino' from platform in folder: C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1

Detecting libraries used...

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\sketch\\Example1_Basics.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for ICM_20948.h: [[email protected]]

ResolveLibrary(ICM_20948.h)

  -> candidates: [[email protected]]

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\sketch\\Example1_Basics.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for Wire.h: [Wire]

ResolveLibrary(Wire.h)

  -> candidates: [Wire]

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\sketch\\Example1_Basics.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for SPI.h: [SPI]

ResolveLibrary(SPI.h)

  -> candidates: [SPI]

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\sketch\\Example1_Basics.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src\\ICM_20948.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src\\util\\ICM_20948_C.c" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire\\Wire.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI\\SPI.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Generating function prototypes...

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -w -x c++ -E -CC -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\sketch\\Example1_Basics.ino.cpp" -o "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\preproc\\ctags_target_for_gcc_minus_e.cpp" -DARDUINO_LIB_DISCOVERY_PHASE

"C:\\Program Files\\WindowsApps\\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\preproc\\ctags_target_for_gcc_minus_e.cpp"

Compiling sketch...

"C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -w -g -Os -nostdlib "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -MMD -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DARDUINO=10813 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\Aaron\\Documents\\Arduino\\libraries\\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\\src" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\Wire" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\libraries\\SPI" "-IC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\cores\\arduino" "@C:\\Users\\Aaron\\Documents\\ArduinoData\\packages\\arduino\\hardware\\mbed\\1.3.1\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\sketch\\Example1_Basics.ino.cpp" -o "C:\\Users\\Aaron\\AppData\\Local\\Temp\\arduino_build_589287\\sketch\\Example1_Basics.ino.cpp.o"

In file included from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:0:

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:122:7: error: using typedef-name 'TwoWire' after 'class'

 class TwoWire;

       ^~~~~~~

In file included from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:14:0,

                 from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:

C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\libraries\Wire/Wire.h:87:26: note: 'TwoWire' has a previous declaration here

 typedef arduino::MbedI2C TwoWire;

                          ^~~~~~~

In file included from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:0:

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:148:8: error: reference to 'SPIClass' is ambiguous

 extern SPIClass SPI;

        ^~~~~~~~

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:147:7: note: candidates are: class SPIClass

 class SPIClass;

       ^~~~~~~~

In file included from C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\libraries\SPI/SPI.h:22:0,

                 from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:15,

                 from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:

C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\cores\arduino/api/HardwareSPI.h:128:21: note:                 typedef class arduino::HardwareSPI arduino::SPIClass

 typedef HardwareSPI SPIClass;

                     ^~~~~~~~

In file included from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:0:

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:155:5: error: reference to 'SPIClass' is ambiguous

     SPIClass *_spi;

     ^~~~~~~~

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:147:7: note: candidates are: class SPIClass

 class SPIClass;

       ^~~~~~~~

In file included from C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\libraries\SPI/SPI.h:22:0,

                 from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:15,

                 from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:

C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\cores\arduino/api/HardwareSPI.h:128:21: note:                 typedef class arduino::HardwareSPI arduino::SPIClass

 typedef HardwareSPI SPIClass;

                     ^~~~~~~~

In file included from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:0:

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:162:45: error: reference to 'SPIClass' is ambiguous

     ICM_20948_Status_e begin(uint8_t csPin, SPIClass &spiPort = SPI, uint32_t SPIFreq = ICM_20948_SPI_DEFAULT_FREQ);

                                             ^~~~~~~~

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:147:7: note: candidates are: class SPIClass

 class SPIClass;

       ^~~~~~~~

In file included from C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\libraries\SPI/SPI.h:22:0,

                 from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:15,

                 from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:

C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\cores\arduino/api/HardwareSPI.h:128:21: note:                 typedef class arduino::HardwareSPI arduino::SPIClass

 typedef HardwareSPI SPIClass;

                     ^~~~~~~~

In file included from C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\examples\Arduino\Example1_Basics\Example1_Basics.ino:13:0:

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:162:45: error: 'SPIClass' has not been declared

     ICM_20948_Status_e begin(uint8_t csPin, SPIClass &spiPort = SPI, uint32_t SPIFreq = ICM_20948_SPI_DEFAULT_FREQ);

                                             ^~~~~~~~

C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library\src/ICM_20948.h:162:65: error: could not convert 'SPI' from 'arduino::MbedSPI' to 'int&'

     ICM_20948_Status_e begin(uint8_t csPin, SPIClass &spiPort = SPI, uint32_t SPIFreq = ICM_20948_SPI_DEFAULT_FREQ);

                                                                 ^~~

Using library SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library at version 1.1.2 in folder: C:\Users\Aaron\Documents\Arduino\libraries\SparkFun_9DoF_IMU_Breakout_-_ICM_20948_-_Arduino_Library 

Using library Wire in folder: C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\libraries\Wire (legacy)

Using library SPI in folder: C:\Users\Aaron\Documents\ArduinoData\packages\arduino\hardware\mbed\1.3.1\libraries\SPI (legacy)

exit status 1

Error compiling for board Arduino Nano 33 BLE.



ICM_20948_DMP.h L suffix lost for some items

#define INV_NEEDS_ACCEL_MASK   ((1L<<1)|        (1L<<3)|        (1L<<9)|(1L<<10)|(1L<<11)|         (1L<<15)|         (1L<<17)|(1L<<18)|(1L<<19)|(1L<<20)|(1<<23)|       (1<<25)|        (1<<29)|(1<<30)|(1<<31))

L suffix lost for some items, that cause compile time warnings

Accelerometer Raw Values at rest horizontal position gives 1 unit shift values

I want to calculate gravity values at rest horizontal position. Ideally for 2g sensitivity , it should give me raw values around 16500 but it gives me values around 14000 for positive z axis and 17000 for negative z axis. Which eventually makes calculation 8.8m/s2 and 10m/s2 respectively. What should be reason for such higher and lower raw values ? What is solution to this problem ?

Sensor Fusion

I'm sorry if this is not the best place to make this question, but I wasn't sure where else to do it on.

Im trying to understand and validate the raw data I'm getting from the DMP (acc, gyro and mag) and also understand how one gets from that raw data to the processed data: quaternion.
So questions like:

  • What sensor data is calibrated

  • How is the sensor fusion done in the DMP to calculate the 9DoF quaternions?

All of this, of course, considering the ICM 20948. I've searched the dataset but I found nothing to clarify my questions...

Accelerometer full scale range issue

Hi,

I tried to change the full scale settings of the accelerometer in the arduino Example2_Advanced code and it did not seem to work.
I am using ICM20948 with SPI communication.

myFSS.a = gpm8; // (ICM_20948_ACCEL_CONFIG_FS_SEL_e)
// gpm2
// gpm4
// gpm8
// gpm16
This is all I need to do to change the settings to +-8G, is that correct?
(In the example code this was myFSS.a = gpm2);

The output raw values for the vertically pointed axis (z-axis in my case) shows +16384 value for all the 4 settings (gpm2, gpm4, gmp8 and gmp16).

If the 4G, 8G, 16G settings have been configured successfully, then the expected output for z-axis raw values is:
approx 8192 for +-4G setting
approx 4096 for +-8G setting
approx 2048 for +-16G setting

Have you observed the same problem or am I doing something wrong here?

Quaternion outputs?

I understand that this chip will output the game rotation vectors as quaternions. Is it possible to extract them using this library? I looked through the examples, but did not see any mention of quaternions.

Connecting multiple SPI sensors to Arduino Nano

Subject of the issue

I cannot receive SPI data from multiple ICM-20948 sensors. I have four ICM-20948 sensors soldered to a custom PCB which connects to an Arduino Nano. The PCB layout is nearly identical to the Adafruit TDK InvenSense ICM-20948 9-DoF IMU board. Each sensor has its own CS line.

Your workbench

  • Windows 10
  • Arduino IDE 1.8.13
  • Arduino Nano
  • Custom PCB board, very similar to Adafruit TDK InvenSense ICM-20948 9-DoF IMU
  • Power from USB, dropped to 1.8 V on custom board using LDO regulator and logic level converter
  • Each ICM-20948 has its own CS line

Steps to reproduce

I am using the Example1_Basics.ino code, but I include three additional ICM_20948 objects and CS lines:

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

#define USE_SPI
#define SERIAL_PORT Serial
#define SPI_PORT SPI // Your desired SPI port. Used only when "USE_SPI" is defined

#define CS_PIN 10 // Which pin you connect CS to. Used only when "USE_SPI" is defined
#define CS_PIN_orange 9
#define CS_PIN_white 8
#define CS_PIN_gray 7

#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
ICM_20948_SPI orange;
ICM_20948_SPI white;
ICM_20948_SPI gray;
#else
ICM_20948_I2C myICM; // Otherwise create an ICM_20948_I2C object
#endif

void setup() {

SERIAL_PORT.begin(115200);
while(!SERIAL_PORT){};

pinMode (CS_PIN, OUTPUT);
pinMode (CS_PIN_orange, OUTPUT);
pinMode (CS_PIN_white, OUTPUT);
pinMode (CS_PIN_gray, OUTPUT);

#ifdef USE_SPI
SPI_PORT.begin();
#else
WIRE_PORT.begin();
WIRE_PORT.setClock(400000);
#endif

bool initialized = false;
while( !initialized ){

#ifdef USE_SPI
myICM.begin( CS_PIN, SPI_PORT );
orange.begin( CS_PIN_orange, SPI_PORT );
white.begin( CS_PIN_white, SPI_PORT );
gray.begin( CS_PIN_gray, SPI_PORT );

#else
myICM.begin( WIRE_PORT, AD0_VAL );
#endif

  initialized = true;

}
}

void loop() {

Serial.println("1st Sensor:");
myICM.getAGMT();                // The values are only updated when you call 'getAGMT'
printRawAGMT( myICM.agmt );     // Uncomment this to see the raw values, taken directly from the agmt structure

Serial.println("2nd Sensor:");
orange.getAGMT();                // The values are only updated when you call 'getAGMT'
printRawAGMT( orange.agmt );     // Uncomment this to see the raw values, taken directly from the agmt structure

Serial.println("3rd Sensor:");
white.getAGMT();                // The values are only updated when you call 'getAGMT'
printRawAGMT( white.agmt );     // Uncomment this to see the raw values, taken directly from the agmt structure

Serial.println("4th Sensor:");
gray.getAGMT();                // The values are only updated when you call 'getAGMT'
printRawAGMT( gray.agmt );     // Uncomment this to see the raw values, taken directly from the agmt structure

delay(30);

}`

Expected behaviour

I should expect to receive nonzero values from my serial monitor from each ICM-20948 sensor.

Actual behaviour

Only the first ICM-20948 sensor produces a nonzero reading. My serial monitor data look like this:

1st Sensor:
RAW. Acc [ 02264, -07008, 15064 ], Gyr [ 00167, 00075, 00021 ], Mag [ 00072, -00211, 00299 ], Tmp [ 03232 ]
2nd Sensor:
RAW. Acc [ -00000, -00000, -00000 ], Gyr [ -00000, -00000, -00000 ], Mag [ -00000, -00000, -00000 ], Tmp [ -00000 ]
3rd Sensor:
RAW. Acc [ -00000, -00000, -00000 ], Gyr [ -00000, -00000, -00000 ], Mag [ -00000, -00000, -00000 ], Tmp [ -00000 ]
4th Sensor:
RAW. Acc [ -00000, -00000, -00000 ], Gyr [ -00000, -00000, -00000 ], Mag [ -00000, -00000, -00000 ], Tmp [ -00000 ]

myICM.lowPower() doesn't reduce current consumption

Subject of the issue

Hey @oclyke, I'm trying to place the ICM-20948 into its full-chip sleep mode (8 ΞΌA draw), but the lowPower function doesn't appear to have any effect on current consumption.

Your workbench

  • What platform are you using?
    • SparkFun Qwiic Micro & ICM-20948
  • How is the device wired to your platform?
    • Qwiic connector
  • How is everything being powered?
    • USB. Current measured between 3.3 V
  • Are there any additional details that may help us help you?
    • LED and AUX PU jumpers cut

Steps to reproduce

  • I modified the "Example1_Basics" code to add the myICM.sleep(true) and myICM.lowPower(true) commands.
  • I can observe the myICM.sleep(true) command reducing the ICM-20948 current consumption from 7.4 mA to 3.4 mA.
  • However, myICM.lowPower(true) has no effect on current draw, either on its own, or when paired with the sleep command.
void loop() {

  myICM.sleep(false);
  //myICM.lowPower(false);
  if ( myICM.dataReady() ) {
    myICM.getAGMT();                // The values are only updated when you call 'getAGMT'
    //printRawAGMT( myICM.agmt );     // Uncomment this to see the raw values, taken directly from the agmt structure
    printScaledAGMT( myICM.agmt);   // This function takes into account the sclae settings from when the measurement was made to calculate the values with units
    delay(2000);
  } else {
    Serial.println("Waiting for data");
    delay(500);
  }
  myICM.sleep(true);
  //myICM.lowPower(true);
  delay(2000);
}

Expected behaviour

  • I realize there's going to be some overhead from the level shifting circuity, but I would expect that current consumption should be able to drop significantly lower than 3.4 mA when placed into full-chip sleep/low power mode.

Actual behaviour

  • Current consumption remains excessively high.

Curious if you have any thoughts! In the meantime, I'll delve into the registers to see what could be up.

Cheers,
Adam

DMP examples not architecture agnostic

Hi @PaulZC,

Great work on the ICM-20948 library!

A quick note to let you know that the DMP examples make use of Serial.printf for displaying outputs, which is not supported on all platforms (e.g. SAMD21).

Cheers,
Adam

CMake support required

Could you please add CMakeLists.txt to the library to create compatibility with Π‘Make projects?
And also for compatibility with (ESP-IDF4.0 + arduino-esp32-4.0 as a component) enviroment combination.

I tried the following CMakeLists.txt code and it performed very well:

idf_component_register(SRCS "src/ICM_20948.cpp" 
                            "src/util/ICM_20948_C.c"
                       INCLUDE_DIRS "src" 
                                    "src/util"
                       REQUIRES "arduino")

component_compile_options(-std=c++17)

Several vars defined in header (ICM_20948_DMP.h)

Subject of the issue

Several vars defined in header (ICM_20948_DMP.h).

Your workbench

I am using x86_64 with CJMCU-20948 board connected to PC via i2c_tiny_usb adapter (cheap chinese USBASP v2 reflashed with another firmware to get /dev/i2c-X device in Linux env).

Steps to reproduce

cc util/ICM_20948_C.c ./main.c ./i2c.c -o ./i2c-test
where main.c includes ICM_20948_C.h

Expected behaviour

Compilation should work

Actual behaviour

As several vars define in header (ICM_20948_DMP.h), I have following errors:

/usr/bin/ld: /tmp/ccVjw7df.o:(.rodata+0x0): multiple definition of `inv_androidSensor_to_control_bits'; /tmp/cc5DSmAB.o:(.rodata+0x0): first defined here
/usr/bin/ld: /tmp/ccVjw7df.o:(.rodata+0x60): multiple definition of `DMP_Quat9_Byte_Ordering'; /tmp/cc5DSmAB.o:(.rodata+0x60): first defined here
/usr/bin/ld: /tmp/ccVjw7df.o:(.rodata+0xa0): multiple definition of `DMP_Quat6_Byte_Ordering'; /tmp/cc5DSmAB.o:(.rodata+0xa0): first defined here
/usr/bin/ld: /tmp/ccVjw7df.o:(.rodata+0xd0): multiple definition of `DMP_PQuat6_Byte_Ordering'; /tmp/cc5DSmAB.o:(.rodata+0xd0): first defined here
/usr/bin/ld: /tmp/ccVjw7df.o:(.rodata+0x100): multiple definition of `DMP_Raw_Gyro_Byte_Ordering'; /tmp/cc5DSmAB.o:(.rodata+0x100): first defined here
/usr/bin/ld: /tmp/ccVjw7df.o:(.rodata+0x130): multiple definition of `DMP_Activity_Recognition_Byte_Ordering'; /tmp/cc5DSmAB.o:(.rodata+0x130): first defined here
/usr/bin/ld: /tmp/ccVjw7df.o:(.rodata+0x148): multiple definition of `DMP_Secondary_On_Off_Byte_Ordering'; /tmp/cc5DSmAB.o:(.rodata+0x148): first defined here

I made them static, like this:

// ICM-20948 data is big-endian. We need to make it little-endian when writing into icm_20948_DMP_data_t
const static int DMP_Quat9_Byte_Ordering[icm_20948_DMP_Quat9_Bytes] =
{
        3,2,1,0,7,6,5,4,11,10,9,8,13,12 // Also used for Geomag
};
const static int DMP_Quat6_Byte_Ordering[icm_20948_DMP_Quat6_Bytes] =
{
        3,2,1,0,7,6,5,4,11,10,9,8 // Also used for Gyro_Calibr, Compass_Calibr
};
const static int DMP_PQuat6_Byte_Ordering[icm_20948_DMP_PQuat6_Bytes] =
{
        1,0,3,2,5,4 // Also used for Raw_Accel, Compass
};
const static int DMP_Raw_Gyro_Byte_Ordering[icm_20948_DMP_Raw_Gyro_Bytes + icm_20948_DMP_Gyro_Bias_Bytes] =
{
        1,0,3,2,5,4,7,6,9,8,11,10
};
const static int DMP_Activity_Recognition_Byte_Ordering[icm_20948_DMP_Activity_Recognition_Bytes] =
{
        0,1,5,4,3,2
};
const static int DMP_Secondary_On_Off_Byte_Ordering[icm_20948_DMP_Secondary_On_Off_Bytes] =
{
        1,0
};

It is no problem to patch lib this way, but maybe it is possible to redeclare this vars in source (.c) file, as now several copies of these vars will appear in final binary.

P.S. the problem seems because I use c, not c++.

auxiliary I2C interface to external sensors

Hi, does anybody know how to get data from external sensors connected to the icm-20948?
because ICM-20948 supports an auxiliary I2C interface to external sensors
Thank you!

Problem reading accurate motorbike tilt angle

Hello,

I try to reading motorbike tilt angle and I experiment a problem I also have with MPU-6050 in fact.
These chip seem to work well on desktop but using it on vehicle seem to be a challenge.
As ICM-20948 seems to be usable on drone, I though it was dedicated to give accurate tilt angle but it seems to be more complicated than it appears.

First, I tested it on my desktop, applying the same movements to my Samsung S10+ (embedding a LSM6DSO) and the ICM-20948 breakout.
The result is this one image
as you can see, the waveforms perfectly match.

Here, I did the same mounting both devices on my motorbike. image
Between 547 and 807, I really was in stable turn, with the same tilt angle as given by my S10+. But the ICM-20948 was seriously drifting to 0 and the offset accumulated at 807 seems to appear at 911.
Between 1639 and 1925, I was accelerating as the turn decreases. S10+ gives an understandable value from my S10, but the ICM-20948 dramatically drift to 0, probably while the z accel increases.

I guess the problem could come from the pitch drift correction made with the g acceleration. And as on motorbike, as well as on drone, a turn cause the g acceleration to increase, maybe this algorithm causes the pitch reading to be false.

I hope I was clear enough, do you have an idea about the problem and how to solve it?


Using Sparkfun ICM 20948 v 1.2.7 library and Example7_DMP_Quat6_EulerAngles.ino sketch running on ESP32 FireBeetle, no filter enable.

Initialization of the sensor returned: Data Underflow

Thank you for creating this useful library.

I have just bought a new set of SparkFun ICM-20948 and SparkFun Thing Plus - ESP32 WROOM, after successfully compiling and uploading the Example1_Basics, I got the error on the Serial Monitor:

Initialization of the sensor returned: Data Underflow
Trying again... 

Did I miss out anything?

Thank you for your help.

Not able to read absolute orientation (tilt) using DMP

Hi Paul,

now that the compass data is available to the DMP, I tried to verify the output against a BNO055 board from production.

In modes ORIENTATION and ROTATION_VECTOR the heading (x-axis) will drift to the a magnetic direction, but roll and pitch axis always start at 0Β°. Even if the sensor is kept at a constant 90Β° tilt (vertical), the output stays permanently at the initial ~0Β° value in those modes.

Only the mode GEOMAGNETIC_ROTATION_VECTOR seems to give an absolute orientation and outputs the 90Β° tilt correctly.
However, for some reason this mode is extremely slow to update. A 90Β° change in tilt takes over 10sec to settle, even tough the DMP is supposed to run at 55Hz.

Other 9-axis modes show large rotations instantly + get the heel and pitch axis correct, but do not give absolute orientation. Even worse, if you tilt the sensor by only 45Β° the heading suddenly changes. It should be steady as long as it "points" in the same direction. This makes none of the modes very useful for real world applications where absolute orientation is important.

In summary, the following things do not work for me when using DMP results:

  1. Incorrect magnetic heading. For example +90Β° yaw causes output to go from 80Β° to 170Β° (ok) but then drift to 110Β° (wrong)
  2. Heading is not independent of tilt, in any mode. For example, roll by -45Β° and the heading changes by 160Β° (woah!)
  3. Output is not referenced to absolute orientation (gravity), which should be provided by the Accelerometer

This leads me to believe that at least the axis configuration of of the magnetometer could be wrong.

For testing we have to be able to convert the Quaternion output into Euler angles.
I would like to contribute the following code for that:

#include <cmath>

// heading, roll, pitch in degrees
struct Vector3D { double x, y, z; }

const double RAD2DEG = (180.0 / M_PI);
const double DEG2RAD = (M_PI / 180.0);

Vector3D toEuler( double w, double x, double y, double z)
{
    Vector3D ret;
    double sqw = w*w;
    double sqx = x*x;
    double sqy = y*y;
    double sqz = z*z;

    ret.x = atan2(2.0*(x*y+z*w),(sqx-sqy-sqz+sqw)) * RAD2DEG;
    ret.z = atan2(2.0*(y*z+x*w),(-sqx-sqy+sqz+sqw)) * RAD2DEG;
    double siny = -2.0*(x*z-y*w)/(sqx+sqy+sqz+sqw);

    // prevent NaN and use 90 deg when out of range
    if (fabs(siny) >= 1.0)
        ret.y = copysign(90.0, siny);
    else
        ret.y = asin(siny) * RAD2DEG;

    return ret;
}

Sorry for the bother with these issues, but I would really like to get some "truth" out of this sensor.
I know this IMU is especially difficult to configure, but I have a good reference, some experience, and would like to help :)

Best regards,
Bernhard

License: MIT or GPL?

Hello. In the readme it is stated that the code is released under GPL v3, but in License.md it says that SparkFun code is released under the MIT license. Could you please clarify under which license the code is released?

Thanks for your time and great work :)

Bank change to 0 after reset is omitted

Subject of the issue

This library implements a mechanism to reduce the amount of I2C traffic by caching the previously used register bank and skip the bank change operation when it is not required.

Currently, no initialization method for ICM_20948_Device_t is provided and therefore all members including _last_bank is initialized as 0 (if declared as a global or static variable).

It means that if the first register access uses register bank 0 no bank change operation is performed.

This behavior can be problematic if the MCU is reset while the power to ICM-20948 is kept on.
Suppose the MCU is performing register access using bank 2, for example, and then the MCU resets, and the first register access after the reset is intended to use register bank 0.
Since the register bank change operation is skipped, the register access is recognized as access to the register bank 2.

To prevent this problem, I would suggest implementing an initialization method for ICM_20948_Device_t that sets an invalid value (e.g. 4) to _last_bank so the first register bank change operation is performed 100%.

Your workbench

  • What platform are you using?: Custom board
  • What version of the device are you using? Is there a firmware version?: STM32L4 MCU, FreeRTOS (I only use the underlying C layer of the library)
  • How is the device wired to your platform?: Custom PCB (using I2C)
  • How is everything being powered?: Battery powered, ICM-20948 is always on
  • Are there any additional details that may help us help you?

Steps to reproduce

  • Use the C layer of the library and declare ICM_20948_Device_t as a global variable
  • Keep ICM-20948 always powered on
  • Program MCU so it accesses the bank 0 and then changes to another bank (e.g. bank 2)
  • Reset MCU after it accesses a register bank other than bank 0

Expected behavior

The MCU should access bank 0 after the reset.

Actual behavior

The MCU accesses bank 2 since no bank change operation is performed after the reset.

What exactly does the "Wrong ID" error mean?

Hello ICM-20948 Team,

I am attempting to use the aforementioned sensor in a project I'm working on. I am attempting to run the "Example1_Basics" code provided with the library to get a feel for how the sensor reacts to certain movements. However, every time I upload the code onto the Arduino UNO I've connected to the sensor, the initialization returns "Wrong ID" and then loops infinitely trying to correctly initialize.

I've hooked up the sensor to the UNO using the SPI breakout pins as recommended by the SparkFun Hookup guide (as seen here: https://learn.sparkfun.com/tutorials/sparkfun-9dof-imu-icm-20948-breakout-hookup-guide?_ga=2.24541626.1092070436.1611006899-1783455205.1549928219 ). The only change I have made to the code is adjusting the baud rate to be the same as other devices used o the project. The reason I am using the SPI method is that the UNO I'm using currently has another sensor attached to it that is using I2C. From what I've read on the subject this shouldn't cause an issue with an SPI device (especially since the I2C sensor shouldn't even be transmitting anything when I upload the "Example1_Basics code onto the Arduino). The Arduino IDE I'm using is version 1.8.13 and the ICM-20948 library I'm using is 1.1.2. The sensor is being powered directly from the 3.3V pin and GND pins on the UNO, and everything is connected using hook-up wires and headers (which I have triple checked all the connections are secure.

I've tried to solve the issue myself, but every instance of the "Wrong ID" error found in the code I looked through in the depository does not explain what it means. Even in instances where there are comments explaining certain error codes, no comment exists for the "Wrong ID" error. Hopefully you can provide me with an explanation of what it means so we can solve this problem as quickly as possible.

Digital Motion Processor (DMP) Support

Thank you very much to create this very good and useful lib! This helps a lot to test out the new imu sensor. Will there be a chance to get DMP supported in this library? As the sensor claims to have a better DMP performance and I really want to see how it goes. Thank you so much!

(DMP) Step Counter / Detector appear to not work

Subject of the issue

Enabling either step counter or step detection features on the DMP appear non funcional

Your workbench

  • What platform are you using?
    Custom board w/ nRF52832
  • What version of the device are you using? Is there a firmware version?
    N/A
  • How is the device wired to your platform?
    SPI @ 7MHz using a level shifter
  • How is everything being powered?
    Li-Ion Battery, w/ 3.3V & 1.8V switch-mode regulators
  • Are there any additional details that may help us help you?
    I may just be being a dunce enabling the features :P... But quaternions, accelerometer, gyro and magnetometer are working as intended.... Also, i'm using interrupts instead of polling the data from the FIFO

Steps to reproduce

Using example 10, enable the step counter or step detection feature as below

   // Enable the DMP Game Rotation Vector sensor (Quat6)
  // success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_GAME_ROTATION_VECTOR) == ICM_20948_Stat_Ok);

  // Enable additional sensors / features
  //success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_RAW_GYROSCOPE) == ICM_20948_Stat_Ok);
  // success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_RAW_ACCELEROMETER) == ICM_20948_Stat_Ok);
  //success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_MAGNETIC_FIELD_UNCALIBRATED) == ICM_20948_Stat_Ok);
  success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_STEP_DETECTOR) == ICM_20948_Stat_Ok);
  success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_STEP_COUNTER) == ICM_20948_Stat_Ok);
  success &= (myICM.enableDMPSensorInt(INV_ICM20948_SENSOR_STEP_DETECTOR) == ICM_20948_Stat_Ok);


  // Configuring DMP to output data at multiple ODRs:
  // DMP is capable of outputting multiple sensor data at different rates to FIFO.
  // Setting value can be calculated as follows:
  // Value = (DMP running rate / ODR ) - 1
  // E.g. For a 225Hz ODR rate when DMP is running at 225Hz, value = (225/225) - 1 = 0.
  // success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Quat6, 0) == ICM_20948_Stat_Ok); // Set to 225Hz
  // success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Accel, 0) == ICM_20948_Stat_Ok); // Set to 225Hz
  //success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Gyro, 0) == ICM_20948_Stat_Ok); // Set to 225Hz
  //success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Cpass, 0) == ICM_20948_Stat_Ok); // Set to 225Hz

How i'm processing the data on my loop

    // works
    if ((dmp_data.header & DMP_header_bitmap_Compass_Calibr) > 0) { // Check for Compass
      float scale_div = 1.0f / (1 << 16);
      pout->mag.axes.z = dmp_data.Compass_Calibr.Data.Z * scale_div;
      pout->mag.axes.x = dmp_data.Compass_Calibr.Data.X * scale_div;
      pout->mag.axes.y = dmp_data.Compass_Calibr.Data.Y * scale_div;
    }
    // doesn't work
    if ((dmp_data.header & (DMP_header_bitmap_Step_Detector | DMP_header_bitmap_PQuat6)) > 0) { // Check for Step Detector
      static uint64_t steps = 0;
      steps++;
      printf("step %lld %lu\n", steps, dmp_data.Pedometer_Timestamp);
      nrf_gpio_pin_toggle(LED_BT);
    }

Expected behaviour

I should be able to extract step data ou have an interrupt generated from the IC

Actual behaviour

Very sporadically, i get garbage on the data read from the FIFO relative to the steps, but i can't pinpoint times or movements to trigger it

I know that these features aren't guaranteed to be working as said on the DMP.md, but either a few pointer to something i might be doing that's dumb or a bit of help would be much appreciated...

Also, idk if it's of interest, but, i found this git that claims it has support for the step counting feature, but unfortunately i can't test it cause i don't have any breakout boards with an ICM-20948...

Best regards.
Xavier

FIFO enabled?

I read the ICM 20948 code in the src directory. I can't see if FIFO is enabled by default. Also, I could not find any code that do so.

Example7_DMP_Quat6_EulerAngles pitch and roll error

Hi,
I'm testing the IMU with the Example7_DMP_Quat6_EulerAngles example.
I tried to turn around the yaw axis with IMU put on the table, so that "normaly" the roll and pitch axis needs to be constant during the rotation.
The result is that the yaw axis works perfectly, but I can see angular bias on both pitch and roll axis during the rotation (of about 20Β° max), this bias seems repeatable in function of the yaw angle.

Am I alone with this problem ?

How to handle physical orientation of ICM20948 when calculating Roll and Pitch used for leveling

We are creating a device based on a ESP32 and an ICM20948, using 4 actuators to physically level out platforms.

The actuators are activated based on the Roll and Pitch that is calculated from the output of the ICM20948.
For the calculation of the Roll and Pitch, we "borrowed" code from the internet (https://en.wikipedia.org/w/index.php?title=Conversion_between_quaternions_and_Euler_angles&section=8#Source_code_2 ), incoorporated in the examples by @PaulZC as I understand)

We are technically schooled but no mathematicians and do not really understand what it's doing ... but its working :)

The actuators are on a well known location on the platform, so we know that if i.e. Roll = 10 that we need to extend the forward and backward actuators on the right of the platform to get the Roll to become smaller.

The problem now arrises that the way that our device is mounted on the platform can vary between installations, the ICM will not always be mounted parallel to the top surface of the platform, but can be mounted in any orientation (we can assume that it will only be 90degree rotations, so the Roll or Pitch axis can point forward, left, backwrd, right, up or down in regards to the platform.)

Our question is how can we add a configuration specifiying the mounted orientation, and (more importantly) use that configuration to get the right Roll and Pitch angles of the platform to steer the correct actuators.

Any help or reference to other sources would be welcome.

Thanks!

avr/pgmspace.h incorrectly included

I'm using the C backend of this library on a raspberry pi. When compiling using arm-linux-gnueabihf-gcc the __arm__ macro is defined causing ICM_20948_C.c to attempt to include the avr/pgmspace.h header. I've corrected this in my local copy by changing line 11 from:
#if defined(__AVR__) || defined(__arm__) || defined(__ARDUINO_ARC__)
to
#if defined(__AVR__) || defined(__ARDUINO_ARC__)
I would submit a pull request but I'm not sure whether there was some reason for checking the __arm__ macro?

Gyro Calibrated Data and Bias

Subject of the issue

Hello,
First off, awesome library, thank you very much! I'm integrating it into a project here:
https://github.com/Blueprint-Foundry/Shelly

Your workbench

  • What platform are you using? : Custom Dev board
  • What version of the device are you using? Is there a firmware version? Latest Firmware downloaded from here :)
  • How is the device wired to your platform? I2C line + I2C conditioning circuit, see here for more details: https://workspace.circuitmaker.com/Projects/Details/Ilia-Baranov/Shelly-Dev-Kit
  • How is everything being powered? USB from laptop
  • Are there any additional details that may help us help you? Power and wiring seem just fine. I am using an ESP32, and use wire with pins 25,23

Steps to reproduce

I edited the DMP_RawAccel example to get Raw Gyro data, so replacing where needed:
INV_ICM20948_SENSOR_RAW_GYROSCOPE
DMP_ODR_Reg_Gyro
DMP_header_bitmap_Gyro
etc.
I then read the XYZ values for gyro, and XYZ bias values instead of the original Accel values.

Expected behaviour

I should be able to read both gyro data and bias data

Actual behaviour

I only get gyro data, bias data is always 0.00. Example:
gyro: X:4.00 Y:14.00 Z:5.00 XB:0.00 YB:0.00 ZB:0.00
gyro: X:3.00 Y:5.00 Z:7.00 XB:0.00 YB:0.00 ZB:0.00

This all started in trying to use the calibrated Gyro field, however that never output data of any kind. Hence I though to use raw data + bias and make my own, but the bias is missing.
I assume there is some configuration step missing?

Request to you awesome folks: Perhaps an example .ino file for Gyro calibrated data and Raw data? :)
(note: all other functions I've tried so far work fine: Quat9, Accel, etc. So I think my chip is healthy since the Quat9 values seem sane.)

Will this driver also work with the ICM 20648?

This looks interesting. I have starting working with the ICM 20648 which I understand is similar to the ICM 20948 but without the magnetometer. Do you know if this library will also work with the ICM 20648?

Euler angles & drift

Hi @PaulZC,

I'm testing the ICM-20948 and DMP this morning and have been observing some strange behaviour with Example7_DMP_Quat6_EulerAngles.ino.

When the ICM-20948 is powered up, it appears to drift over several seconds before stabilizing. This can be seen in the graph below. The IMU is not moved while the data is being recorded. The IMU is also on a level surface and the pitch and roll values should be much closer to zero.

Is there any form of calibration that needs to first be performed?

Cheers,
Adam

imu

Using DMP to receive multiple sensor data values -

Many thanks for adding the DMP support for this library.
I followed the recent example Example5_DMP_Quat9_Orientation and was successful getting the quaternion values from the sensor as the example shows. However, I would also want to get multiple data values at the same time, including quaternions and raw accel,gyro,mag data.
To test it out, I added the following lines in the setup;

success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_ACCELEROMETER) == ICM_20948_Stat_Ok);
success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Accel, 200) == ICM_20948_Stat_Ok);

and in the loop

else if ((data.header & DMP_header_bitmap_Accel) > 0)
{

	float acc_x = ((float)data.Raw_Accel.Data.X); 
	float acc_y = ((float)data.Raw_Accel.Data.Y); 
	float acc_z = ((float)data.Raw_Accel.Data.Z); 

	char sensor_string_buff[128];
	sprintf(sensor_string_buff, "{\"accel_x\":%f, \"accel_y\":%f, \"accel_z\":%f}", acc_x,acc_y,acc_z);
	Serial.println(sensor_string_buff);
}

However, I am not getting any data (both quaternion and accel values), and it seems like the fifo is empty.
When reading the data if ((myICM.status == ICM_20948_Stat_Ok) || (myICM.status == ICM_20948_Stat_FIFOMoreDataAvail)) is always false.
Appreciate any help to fix this.

All values are very inaccurate in Example2_Advanced

Subject of the issue

When the advanced example is run (including fix needed, see PR #67) on a stationary board, especially Accellero are far from stationary, even after rotating device on all axis to calibrate.

Magneto values seem pretty stable,
AccX values run from 1 to 31, AccY from 83 to 110, AccZ values from 1041 to 1070
Gyro all directions jump from 0 to 3 degrees per second

Running a espressif32@~3.2.0 with the Arduino framework, using address $68

Scaled. Acc (mg) [ -00011.72, -00083.98, 01050.78 ], Gyr (DPS) [ -00001.27, -00001.08, 00001.19 ], Mag (uT) [ 00013.50, -00006.00, 00083.25 ], Tmp (C) [ 00028.37 ] Scaled. Acc (mg) [ -00001.46, -00096.19, 01068.85 ], Gyr (DPS) [ -00001.02, 00001.76, 00001.42 ], Mag (uT) [ 00013.65, -00005.55, 00084.15 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00014.65, -00088.87, 01050.29 ], Gyr (DPS) [ -00002.46, -00000.62, -00000.85 ], Mag (uT) [ 00014.55, -00006.75, 00083.25 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00031.25, -00084.96, 01056.64 ], Gyr (DPS) [ -00000.56, -00001.31, -00002.40 ], Mag (uT) [ 00014.85, -00005.40, 00084.30 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00026.86, -00084.96, 01057.13 ], Gyr (DPS) [ -00001.39, 00000.26, 00001.07 ], Mag (uT) [ 00014.70, -00005.55, 00083.40 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00008.79, -00100.10, 01067.87 ], Gyr (DPS) [ -00000.09, -00000.11, 00001.72 ], Mag (uT) [ 00014.40, -00005.10, 00084.90 ], Tmp (C) [ 00028.32 ] Scaled. Acc (mg) [ -00016.60, -00097.66, 01065.92 ], Gyr (DPS) [ 00000.03, -00001.97, 00001.38 ], Mag (uT) [ 00014.85, -00006.75, 00084.75 ], Tmp (C) [ 00028.37 ] Scaled. Acc (mg) [ -00030.27, -00090.82, 01060.55 ], Gyr (DPS) [ -00000.85, -00000.98, -00003.08 ], Mag (uT) [ 00014.25, -00005.70, 00085.35 ], Tmp (C) [ 00028.60 ] Scaled. Acc (mg) [ -00012.70, -00091.31, 01051.27 ], Gyr (DPS) [ -00000.93, 00000.76, -00000.29 ], Mag (uT) [ 00014.25, -00005.40, 00083.55 ], Tmp (C) [ 00028.56 ] Scaled. Acc (mg) [ -00017.09, -00089.84, 01058.11 ], Gyr (DPS) [ -00001.10, -00000.85, -00000.27 ], Mag (uT) [ 00014.40, -00005.85, 00084.15 ], Tmp (C) [ 00028.56 ] Scaled. Acc (mg) [ -00023.93, -00093.75, 01055.18 ], Gyr (DPS) [ -00002.36, 00001.12, -00000.37 ], Mag (uT) [ 00013.35, -00005.55, 00084.90 ], Tmp (C) [ 00028.37 ] Scaled. Acc (mg) [ -00011.72, -00082.52, 01056.64 ], Gyr (DPS) [ -00001.34, -00000.69, -00002.05 ], Mag (uT) [ 00013.65, -00005.85, 00083.40 ], Tmp (C) [ 00028.60 ] Scaled. Acc (mg) [ -00018.07, -00082.52, 01064.45 ], Gyr (DPS) [ -00001.95, -00000.92, -00002.27 ], Mag (uT) [ 00014.85, -00006.45, 00084.00 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ 00001.95, -00076.66, 01049.32 ], Gyr (DPS) [ -00003.15, 00000.73, 00000.76 ], Mag (uT) [ 00013.80, -00007.20, 00083.55 ], Tmp (C) [ 00028.22 ] Scaled. Acc (mg) [ -00021.48, -00083.01, 01050.78 ], Gyr (DPS) [ -00001.37, -00000.73, 00000.25 ], Mag (uT) [ 00015.45, -00007.05, 00084.15 ], Tmp (C) [ 00027.98 ] Scaled. Acc (mg) [ -00009.77, -00087.89, 01062.50 ], Gyr (DPS) [ -00004.31, 00002.25, -00001.50 ], Mag (uT) [ 00014.55, -00007.50, 00085.05 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00013.18, -00096.68, 01060.55 ], Gyr (DPS) [ -00000.85, 00000.46, 00001.74 ], Mag (uT) [ 00015.45, -00007.35, 00083.85 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00024.90, -00096.19, 01058.11 ], Gyr (DPS) [ -00002.50, 00000.95, 00001.44 ], Mag (uT) [ 00014.55, -00005.40, 00085.05 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00018.07, -00100.10, 01061.52 ], Gyr (DPS) [ -00002.05, 00000.30, -00000.54 ], Mag (uT) [ 00014.85, -00005.40, 00084.75 ], Tmp (C) [ 00028.56 ] Scaled. Acc (mg) [ -00033.20, -00095.70, 01040.53 ], Gyr (DPS) [ -00000.53, 00000.99, 00001.15 ], Mag (uT) [ 00015.60, -00006.75, 00084.30 ], Tmp (C) [ 00028.37 ] Scaled. Acc (mg) [ -00017.58, -00094.73, 01059.08 ], Gyr (DPS) [ -00002.02, 00002.08, -00000.01 ], Mag (uT) [ 00013.65, -00005.85, 00084.90 ], Tmp (C) [ 00028.17 ] Scaled. Acc (mg) [ -00014.16, -00091.31, 01061.04 ], Gyr (DPS) [ -00001.69, 00001.98, -00001.17 ], Mag (uT) [ 00015.45, -00006.30, 00084.45 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00016.60, -00091.80, 01062.01 ], Gyr (DPS) [ -00001.46, 00001.24, -00001.16 ], Mag (uT) [ 00014.40, -00006.30, 00084.90 ], Tmp (C) [ 00028.56 ] Scaled. Acc (mg) [ -00031.25, -00110.35, 01069.34 ], Gyr (DPS) [ -00001.66, 00000.60, -00003.24 ], Mag (uT) [ 00013.50, -00006.75, 00084.00 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00014.65, -00087.89, 01054.69 ], Gyr (DPS) [ -00002.19, 00000.49, -00000.58 ], Mag (uT) [ 00012.90, -00006.60, 00083.85 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00024.90, -00090.82, 01044.92 ], Gyr (DPS) [ -00000.14, -00000.18, 00001.03 ], Mag (uT) [ 00015.15, -00006.60, 00084.45 ], Tmp (C) [ 00028.60 ] Scaled. Acc (mg) [ -00023.44, -00090.82, 01053.22 ], Gyr (DPS) [ -00002.63, 00000.31, -00002.95 ], Mag (uT) [ 00014.70, -00007.35, 00084.15 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00028.32, -00091.31, 01064.94 ], Gyr (DPS) [ -00001.31, 00001.27, -00002.93 ], Mag (uT) [ 00013.65, -00006.60, 00084.45 ], Tmp (C) [ 00028.56 ] Scaled. Acc (mg) [ -00026.86, -00098.14, 01066.41 ], Gyr (DPS) [ -00002.60, 00000.74, 00001.02 ], Mag (uT) [ 00013.35, -00007.05, 00083.85 ], Tmp (C) [ 00028.17 ] Scaled. Acc (mg) [ -00010.74, -00098.14, 01050.78 ], Gyr (DPS) [ -00001.30, -00000.18, -00002.82 ], Mag (uT) [ 00013.80, -00006.75, 00085.05 ], Tmp (C) [ 00028.56 ] Scaled. Acc (mg) [ -00025.39, -00100.59, 01045.90 ], Gyr (DPS) [ -00002.27, 00001.02, -00000.79 ], Mag (uT) [ 00013.80, -00004.95, 00085.80 ], Tmp (C) [ 00028.60 ] Scaled. Acc (mg) [ -00005.37, -00086.91, 01048.34 ], Gyr (DPS) [ -00001.23, -00000.21, 00000.24 ], Mag (uT) [ 00014.70, -00006.60, 00084.90 ], Tmp (C) [ 00028.37 ] Scaled. Acc (mg) [ -00027.34, -00088.38, 01057.13 ], Gyr (DPS) [ -00001.63, 00001.21, -00002.69 ], Mag (uT) [ 00015.30, -00005.70, 00084.30 ], Tmp (C) [ 00028.60 ] Scaled. Acc (mg) [ -00021.48, -00089.84, 01053.71 ], Gyr (DPS) [ -00002.62, 00001.20, -00000.58 ], Mag (uT) [ 00013.95, -00005.85, 00085.20 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00024.90, -00099.12, 01058.59 ], Gyr (DPS) [ -00001.95, 00000.44, -00001.21 ], Mag (uT) [ 00012.75, -00005.70, 00084.00 ], Tmp (C) [ 00028.56 ] Scaled. Acc (mg) [ -00013.18, -00091.80, 01039.55 ], Gyr (DPS) [ -00001.76, 00001.09, -00001.30 ], Mag (uT) [ 00015.15, -00004.80, 00083.85 ], Tmp (C) [ 00028.08 ] Scaled. Acc (mg) [ -00022.95, -00087.89, 01051.27 ], Gyr (DPS) [ -00001.89, 00000.86, 00000.03 ], Mag (uT) [ 00014.70, -00006.60, 00084.45 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00017.58, -00088.87, 01050.29 ], Gyr (DPS) [ -00000.75, -00000.11, -00000.33 ], Mag (uT) [ 00014.25, -00005.70, 00084.30 ], Tmp (C) [ 00028.37 ] Scaled. Acc (mg) [ -00014.65, -00093.26, 01057.13 ], Gyr (DPS) [ -00001.30, 00002.66, 00001.25 ], Mag (uT) [ 00013.80, -00006.75, 00085.05 ], Tmp (C) [ 00028.37 ] Scaled. Acc (mg) [ -00011.72, -00103.52, 01066.89 ], Gyr (DPS) [ -00000.27, 00002.05, 00000.61 ], Mag (uT) [ 00013.80, -00006.00, 00084.30 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00024.41, -00087.89, 01053.71 ], Gyr (DPS) [ -00000.12, 00000.09, -00000.20 ], Mag (uT) [ 00014.55, -00006.45, 00084.30 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00016.11, -00087.40, 01057.62 ], Gyr (DPS) [ -00003.13, 00000.49, -00001.82 ], Mag (uT) [ 00014.85, -00005.70, 00083.55 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00010.74, -00093.26, 01056.64 ], Gyr (DPS) [ -00001.17, 00001.82, 00000.02 ], Mag (uT) [ 00014.55, -00006.75, 00084.75 ], Tmp (C) [ 00028.32 ] Scaled. Acc (mg) [ -00026.37, -00097.66, 01055.66 ], Gyr (DPS) [ -00003.73, 00000.74, -00002.21 ], Mag (uT) [ 00014.55, -00006.00, 00084.75 ], Tmp (C) [ 00028.22 ] Scaled. Acc (mg) [ -00030.27, -00095.21, 01059.57 ], Gyr (DPS) [ -00001.27, 00000.78, 00000.74 ], Mag (uT) [ 00014.55, -00005.70, 00084.75 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00023.44, -00092.77, 01058.59 ], Gyr (DPS) [ -00001.22, 00000.73, 00002.84 ], Mag (uT) [ 00013.95, -00005.10, 00084.45 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00018.55, -00083.50, 01041.02 ], Gyr (DPS) [ -00002.71, -00000.78, -00000.98 ], Mag (uT) [ 00015.15, -00006.30, 00083.85 ], Tmp (C) [ 00028.51 ] Scaled. Acc (mg) [ -00020.02, -00083.50, 01043.46 ], Gyr (DPS) [ -00002.50, 00000.82, -00001.18 ], Mag (uT) [ 00013.65, -00006.30, 00085.20 ], Tmp (C) [ 00028.41 ] Scaled. Acc (mg) [ -00024.41, -00086.43, 01070.80 ], Gyr (DPS) [ -00000.73, 00000.52, -00003.96 ], Mag (uT) [ 00014.55, -00004.95, 00084.00 ], Tmp (C) [ 00028.51 ]

Question: DMP and FIFO, case when you need to grab data rarely.

In all DMP examples there is following thing:

  if ( myICM.status != ICM_20948_Stat_FIFOMoreDataAvail ) // If more data is available then we should read it right away - and not delay
  {
    delay(10);
  }

As I understand DMP is working following way:
All time it is getting raw values for some rate, perform calculations, finally produce for example Quat and put it to FIFO.
According example code, it is supposed to read FIFO fast enough.

But what if I don`t want to grab data always, In my case I need sometimes get actual data(actual current orientation).
How can I reach this?

How deep is FIFO? Will DMP still push new data to FIFO, when it will be full (deleting oldest data)?
Even yes, I will always get some old data (depending on FIFIO size).

Is it possible to disable FIFO or adjust it`s size?

Calculating ACC_SCALE & ACC_SCALE2 for the DMP

Hi !
First of all, thanks for the tremendous amount of work you've made here !

I have a question about the way you calculate the value that will be store in the DMP in order to scale the raw accelerometer data. By default it's set for 4g as it is written in the ICM_20948.ccp file

Line 1220 :

ICM_20948_fss_t myFSS; // This uses a "Full Scale Settings" structure that can contain values for all configurable sensors
  myFSS.a = gpm4; 

and later Line 1287 :

  // Configure Accel scaling to DMP
  // The DMP scales accel raw data internally to align 1g as 2^25
  // In order to align internal accel raw data 2^25 = 1g write 0x04000000 when FSR is 4g
  const unsigned char accScale[4] = {0x04, 0x00, 0x00, 0x00};
  result = writeDMPmems(ACC_SCALE, 4, &accScale[0]); if (result > worstResult) worstResult = result; // Write accScale to ACC_SCALE DMP register
  // In order to output hardware unit data as configured FSR write 0x00040000 when FSR is 4g
  const unsigned char accScale2[4] = {0x00, 0x04, 0x00, 0x00};
  result = writeDMPmems(ACC_SCALE2, 4, &accScale2[0]); if (result > worstResult) worstResult = result; // Write accScale2 to ACC_SCALE2 DMP register

So, I want to set the full scale setting at +-16g and after I changed the Line 1220 myFSS.a = gpm4; to myFSS.a = gpm16; , I wonder now how to calculate the new values of accScale & accScale2 that will be passed to the DMP.

It states that 1g=2^25 but, for +-4g the value is 0x04000000=2* 2^25 and not 4* 2^25... Same issue for accScale2, I couldn't figure from where 0x00040000 come from and how I can calculate the correct value for my 16g setting.

If you have the way to figured these two values out it would be awesome !

Have a nice day !
Regards

[Feature Request] Please add PROGMEM support for old processors like the ATmega

I'm trying to work on a small visualization application. Using this library along with Madgwick AHRS, I was able to get my Arduino Uno sketch to output it's orientation on the serial communication line (e.g. Yaw, Pitch, Roll in degrees). On my PC, I have a python script setup to rotate a 3D model to match that orientation.

While I was initially successful, there was an unfortunate amount of drift, so say every second the computed orientation would drift about 5 seconds. This isn't acceptable.

I'd really like to use the DMP on the chip. I read the docs and it looks like there are features such as doing the sensor fusion for me, as well as calibrating the chip (in hopes of preventing drift). When I tried to enable the DMP in my Arduino Uno Sketch code, it said that there wasn't enough space on the chip.

Does the DMP require a more powerful micro controller than that of the Arduino Uno?

Unused variables b2sMountMultiplierZero[] and b2sMountMultiplierPlus[]

Hi,

Thank you for this huge effort.

In your example codes Example6 and 9, you are initializing matrix registers of the DMP, but b2sMountMultiplierZero[] and b2sMountMultiplierPlus[] are never used in the initializer. Was that intentional or a bug?

// Configure the B2S Mounting Matrix
  const unsigned char b2sMountMultiplierZero[4] = {0x00, 0x00, 0x00, 0x00};
  const unsigned char b2sMountMultiplierPlus[4] = {0x40, 0x00, 0x00, 0x00}; // Value taken from InvenSense Nucleo example
  success &= (myICM.writeDMPmems(B2S_MTX_00, 4, &mountMultiplierPlus[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_01, 4, &mountMultiplierZero[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_02, 4, &mountMultiplierZero[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_10, 4, &mountMultiplierZero[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_11, 4, &mountMultiplierPlus[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_12, 4, &mountMultiplierZero[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_20, 4, &mountMultiplierZero[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_21, 4, &mountMultiplierZero[0]) == ICM_20948_Stat_Ok);
  success &= (myICM.writeDMPmems(B2S_MTX_22, 4, &mountMultiplierPlus[0]) == ICM_20948_Stat_Ok);

Linking errors from definitions in ICM_20948_DMP.h

When attempting to use the C libraries present in utils, including ICM_20948_C.h will include ICM_20948_DMP.h.

The aforementioned header defines the following

  • inv_androidSensor_to_control_bits
  • DMP_Quat9_Byte_Ordering
  • DMP_Quat6_Byte_Ordering
  • DMP_PQuat6_Byte_Ordering
  • DMP_Raw_Gyro_Byte_Ordering
  • DMP_Activity_Recognition_Byte_Ordering
  • DMP_Secondary_On_Off_Byte_Ordering

Which will cause multiple definition errors on these symbols between ICM_20948_C.c and any other file including ICM_20948_C.h.

The definition and declaration should be separated, and a file ICM_20948_DMP.c should be created, containing the following

#include <stdint.h>

#include "ICM_20948_DMP.h"

const uint16_t inv_androidSensor_to_control_bits[ANDROID_SENSOR_NUM_MAX]=
{
	// Data output control 1 register bit definition
	// 16-bit accel                                0x8000
	// 16-bit gyro                                 0x4000
	// 16-bit compass                              0x2000
	// 16-bit ALS                                  0x1000
	// 32-bit 6-axis quaternion                    0x0800
	// 32-bit 9-axis quaternion + heading accuracy 0x0400
	// 16-bit pedometer quaternion                 0x0200
	// 32-bit Geomag rv + heading accuracy         0x0100
	// 16-bit Pressure                             0x0080
	// 32-bit calibrated gyro                      0x0040
	// 32-bit calibrated compass                   0x0020
	// Pedometer Step Detector                     0x0010
	// Header 2                                    0x0008
	// Pedometer Step Indicator Bit 2              0x0004
	// Pedometer Step Indicator Bit 1              0x0002
	// Pedometer Step Indicator Bit 0              0x0001
	// Unsupported Sensors are 0xFFFF

	0xFFFF, // 0  Meta Data
	0x8008, // 1  Accelerometer
	0x0028, // 2  Magnetic Field
	0x0408, // 3  Orientation
	0x4048, // 4  Gyroscope
	0x1008, // 5  Light
	0x0088, // 6  Pressure
	0xFFFF, // 7  Temperature
	0xFFFF, // 8  Proximity <----------- fixme
	0x0808, // 9  Gravity
	0x8808, // 10 Linear Acceleration
	0x0408, // 11 Rotation Vector
	0xFFFF, // 12 Humidity
	0xFFFF, // 13 Ambient Temperature
	0x2008, // 14 Magnetic Field Uncalibrated
	0x0808, // 15 Game Rotation Vector
	0x4008, // 16 Gyroscope Uncalibrated
	0x0000, // 17 Significant Motion
	0x0018, // 18 Step Detector
	0x0010, // 19 Step Counter <----------- fixme
	0x0108, // 20 Geomagnetic Rotation Vector
	0xFFFF, // 21 ANDROID_SENSOR_HEART_RATE,
	0xFFFF, // 22 ANDROID_SENSOR_PROXIMITY,

	0x8008, // 23 ANDROID_SENSOR_WAKEUP_ACCELEROMETER,
	0x0028, // 24 ANDROID_SENSOR_WAKEUP_MAGNETIC_FIELD,
	0x0408, // 25 ANDROID_SENSOR_WAKEUP_ORIENTATION,
	0x4048, // 26 ANDROID_SENSOR_WAKEUP_GYROSCOPE,
	0x1008, // 27 ANDROID_SENSOR_WAKEUP_LIGHT,
	0x0088, // 28 ANDROID_SENSOR_WAKEUP_PRESSURE,
	0x0808, // 29 ANDROID_SENSOR_WAKEUP_GRAVITY,
	0x8808, // 30 ANDROID_SENSOR_WAKEUP_LINEAR_ACCELERATION,
	0x0408, // 31 ANDROID_SENSOR_WAKEUP_ROTATION_VECTOR,
	0xFFFF,	// 32 ANDROID_SENSOR_WAKEUP_RELATIVE_HUMIDITY,
	0xFFFF,	// 33 ANDROID_SENSOR_WAKEUP_AMBIENT_TEMPERATURE,
	0x2008, // 34 ANDROID_SENSOR_WAKEUP_MAGNETIC_FIELD_UNCALIBRATED,
	0x0808, // 35 ANDROID_SENSOR_WAKEUP_GAME_ROTATION_VECTOR,
	0x4008, // 36 ANDROID_SENSOR_WAKEUP_GYROSCOPE_UNCALIBRATED,
	0x0018, // 37 ANDROID_SENSOR_WAKEUP_STEP_DETECTOR,
	0x0010, // 38 ANDROID_SENSOR_WAKEUP_STEP_COUNTER,
	0x0108, // 39 ANDROID_SENSOR_WAKEUP_GEOMAGNETIC_ROTATION_VECTOR
	0xFFFF,	// 40 ANDROID_SENSOR_WAKEUP_HEART_RATE,
	0x0000,	// 41 ANDROID_SENSOR_WAKEUP_TILT_DETECTOR,
	0x8008, // 42 Raw Acc
	0x4048, // 43 Raw Gyr
};

// ICM-20948 data is big-endian. We need to make it little-endian when writing into icm_20948_DMP_data_t
const int DMP_Quat9_Byte_Ordering[icm_20948_DMP_Quat9_Bytes] =
{
	3,2,1,0,7,6,5,4,11,10,9,8,13,12 // Also used for Geomag
};
const int DMP_Quat6_Byte_Ordering[icm_20948_DMP_Quat6_Bytes] =
{
	3,2,1,0,7,6,5,4,11,10,9,8 // Also used for Gyro_Calibr, Compass_Calibr
};
const int DMP_PQuat6_Byte_Ordering[icm_20948_DMP_PQuat6_Bytes] =
{
	1,0,3,2,5,4 // Also used for Raw_Accel, Compass
};
const int DMP_Raw_Gyro_Byte_Ordering[icm_20948_DMP_Raw_Gyro_Bytes + icm_20948_DMP_Gyro_Bias_Bytes] =
{
	1,0,3,2,5,4,7,6,9,8,11,10
};
const int DMP_Activity_Recognition_Byte_Ordering[icm_20948_DMP_Activity_Recognition_Bytes] =
{
	0,1,5,4,3,2
};
const int DMP_Secondary_On_Off_Byte_Ordering[icm_20948_DMP_Secondary_On_Off_Bytes] =
{
	1,0
};

Compile warning because boolean typedef is deprecated in some Arduino cores

Some Arduino cores have marked the boolean typedef as deprecated (see this issue). This results in a warning on compilation in STM32duino due to the following line:

boolean _printDebug = false; //Flag to print the serial commands we are sending to the Serial port for debug

Do we have to use the boolean alias? Can we change this to bool instead?

I can submit a PR if this change is desired.

Calibration

Subject of the issue

Calibration needed?

Your workbench

I want to ask if the calibration is needed if we are using C code or C++ code? if it is needed then how we can add that automatically in the code?

9DoF Quaternion Values switch signs

Hey Guys,

I have been working on a quaternion project for quite some time and just recently saw the updated library (1.2.7) and have to say great work!!! πŸ‘πŸΌπŸ‘πŸΌπŸ‘πŸΌ

I do have an issue ide like to discuss here:

Using:
SparkFun Pro nrf52840 Mini
ICM - 20948 connected I2C via qwiik
Bootloader - s140 6.1.1 r0
ICM Library - 1.2.7
Used the example 6 - 9DoF Quat.

I have 2 devices located on my left and right leg that transmit the quaternions to a host device via BLE.

I have noticed that the right leg is working perfectly as it is supposed to while kicking forward and sideways, but the left leg is acting weird especially when kicking to the side (to the right side).

When a kick is noticed the Quaternions (Q1 Q2 Q3) switch signs 😲

This Image is the RIGHT leg. (The deltas we see are due to a lag in data coming in.. please ignore). This is what the data should look like.

image

This is the LEFT leg. As you can see the value of Q3 goes from (-0.893) to (0.893) when kicking to the right.

image

This is the Data

Screen Shot 2021-06-17 at 13 21 49

This is when I take my leg down after the kick it goes back to normal

Screen Shot 2021-06-17 at 13 22 53

The code on the Devices is the same:
Initiating the DMP exactly the same as in the Example, and grabbing the DMP data exactly the same as the example.

Any help is appreciated!

Thanks
Almog

Incorrect temperature formula

Hi,

During a recent investigation as to why the ICM-20948 temperature readings are about 5Β°C higher than other sensors (turns out the die temperature just runs hotter), I discovered a small error in the temperature formula used in this library.

float ICM_20948::getTempC(int16_t val)
{
return (((float)val) / 333.87) + 21;
}

According to the ICM-20948 the datasheet, it appears the above formula is missing the RoomTemp_Offset.
image

I believe the formula should end up looking something like:

 float ICM_20948::getTempC(int16_t val) 
 { 
     return (((float)val - 21) / 333.87) + 21; 
 }

Cheers,
Adam

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.