For general object control, a 6DOF is the most useful IMU, having 3 axises of Accelerometer and Gyroscope. While 9DOF adds a 3 axis magnetometer, those are generally not used for most projects unless you need absolute tracking of magnetic North, and are prepared to have noise filtering from any Electro-Motive Fields near the sensor.

The IMU

For this example, we are using the LSM6DSOX from Adafruit ( https://www.adafruit.com/product/4438 ). Any generic board using the STMicroelectronics LSM6DSOX chip ( https://www.st.com/en/mems-and-sensors/lsm6dsox.html ) will apply to this article in the majority.

Datasheet: https://www.st.com/resource/en/datasheet/lsm6dsox.pdf

Pinout

For this guide, we are only going to use the I2C interface. While the module is capable of SPI, I2C is much easier to work with and requires less wires when you get into daisy-chaining or multiplexing.

An item to note, while these modules have the ability to be internally daisy-chained using the SCX and SDX pins, the Adafruit and Arduino libraries do not seem to have the support built in (yet).

One edge of the board has 9 pins, the other has 5.
The side with 5 pins is available for daisy-chaining. For the sake of this document, we are focusing on the side with 9 pins.

VIN: Voltage In, not to exceed 5 volts
3Vo: Bypasses the onboard regulator if your controller has a clean 3V3 output
GND: Ground
SCL & SDA: I2C bus
D0: Used as an SPI data line OR changes the module address for I2C from 0x6A (default) to 0x6B (pulled up). NOTE: The 2 solder pads on bottom can be jumped, rather than using a through-hole jumper wire. One pad is the D0 pin (with a pulldown resistor), the other is 3.3 volts.
I1 & I2: Interrupts 1 and 2 can be configured on an as-needed basis.

Adding the library to Arduino IDE

Within the IDE, go to Tools > Manage Libraries.

When the left sidebar opens, search for “Adafruit LSM6DS” and install the library.

Note: Both the “Adafruit LSM6DS” and “Arduino LSM6DSOX” libraries function similarly, however, the Adafruit is more generic (covering the whole 6DS series) while the Arduino is more specifically written for the Arduino Nano RP2040 Connect ( https://docs.arduino.cc/hardware/nano-rp2040-connect/ ).

Component Diagram

Dual LSM6DSOX connection diagram

Communicating with the 6DOF

Because we are working with two modules on the same I2C bus, we need to begin communication with both devices separately.

Adafruit_LSM6DSOX soxA;
Adafruit_LSM6DSOX soxB;

...
 
if (!soxA.begin_I2C(0x6A)) {
    while (!soxA.begin_I2C(0x6A)) {
      delay(10);
    }
  } else {
    Serial.println("LSM6DSOX Unit A found");
  }

  if (!soxB.begin_I2C(0x6B)) {
    while (!soxB.begin_I2C(0x6B)) {
      delay(10);
    }
  } else {
    Serial.println("LSM6DSOX Unit B found");
  }

Getting values from the 6DOF

Using a custom datatype established by the library, we assign variables to memory addresses, then pass those pointers to the getEvent function. Those variables are then modified by the getEvent function such that we may reference them in loop().

Note: while Temperature is likely not useful to us, it is useful to the library in regards to normalizing output to compensate for environmental variables (like thermal expansion).

Through experimentation, it looks like the first time that a getEvent call is made, the values tend to be erroneous. As such, I found it beneficial to make “throwaway” calls during setup() as part of the sensor initialization process.

sensors_event_t accelA;
sensors_event_t gyroA;
sensors_event_t tempA;
sensors_event_t accelB;
sensors_event_t gyroB;
sensors_event_t tempB;

...

/* Get a new normalized sensor event */
soxA.getEvent(&accelA, &gyroA, &tempA);
soxB.getEvent(&accelB, &gyroB, &tempB);

/* Display the results (acceleration is measured in m/s^2, gyro is measured in rad/s converted to deg/s) */
Serial.print(millis());
Serial.print(",");
Serial.print(accelA.acceleration.x);
Serial.print(",");
Serial.print(accelA.acceleration.y);
Serial.print(",");
Serial.print(accelA.acceleration.z);
Serial.print(",");
Serial.print((gyroA.gyro.x)*57.29);
Serial.print(",");
Serial.print((gyroA.gyro.y)*57.29);
Serial.print(",");
Serial.print((gyroA.gyro.z)*57.29);
Serial.print(",");
Serial.print(accelB.acceleration.x);
Serial.print(",");
Serial.print(accelB.acceleration.y);
Serial.print(",");
Serial.print(accelB.acceleration.z);
Serial.print(",");
Serial.print((gyroB.gyro.x)*57.29);
Serial.print(",");
Serial.print((gyroB.gyro.y)*57.29);
Serial.print(",");
Serial.print((gyroB.gyro.z)*57.29);
Serial.println();

Example code