ESP32 with MPU6500

I have an ESP32, which works fine with some test code. I have some EMU6500 boards. The chip on them is marked as MP65M, which fits with them being 6500s as claimed.

I can't get them to talk. I have tried the FastIMU library which runs through all 47 options before saying "No IMU detected". I tried the MPU9250_WE" library which also supports the 6500 and it says "I2C hardware NACK detected" but then can't connect.

Does anyone have any idea what I'm doing wrong?

I have tried 2 different ESPs and 2 different 6500's with the same results.

Hi! Welcome to the Forum.

There's a good chance that the problem is in your code, that is not shown.
(The first topic that everyone should read is How to get the best out of this Forum)

Without the code and without knowing how you connected everything, people will have to guess. I can be the first. Take a look at the link below and see if it gives you a clue.

https://stackoverflow.com/questions/77502246/esp32-not-connecting-to-mpu9500-6500

My code is just the sample code included with the libraries. I have tried changing Wire.begin() to Wire.begin(21,22) as the link you included sugested with no difference.

If I run the scanning code from ESP32: I2C Scanner (Arduino) | Random Nerd Tutorials it says "No I2C devices found" so at least we can narrow down the issue to being an I2C problem.

Looking at the board the SCL and SDA lines have 10k pullups on them which seems a little high but I can't imagine the supplier woudl sell the board with them if they didn't work, he'd get them all back! I tried the scanning with both boards and neither is found.

Counterfeit ICs and boards are very common. This is a major problem for the industry, as well as for hobby modules. Any module you buy on Amazon, eBay, Aliexpress, etc. has a high probability of being fake or counterfeit.

The entire MPU line of IMU chips (6500, 6050, 9250) was discontinued years ago and is now obsolete. Modern replacements perform much better.

Are you talking about this

Close, but mine is supposed to be a 6500, not a 6050.

Maybe heed post four and get some modern units.

What chipset/module do people recommend for ESP32 use?

All modern IMUs outperform the obsolete MPU series, but buy from a reputable supplier.

I've used and am impressed with this one:

Any other suggestions? At $20 that makes the motion sensor more expensive than the rest of the project put together! I'm only using it as a type of configurable tamper detector.

I tried devices like that one but found them unreliable and inconsistent, and they aren't really configurable, that's why I switched to a cheap 6 axis.

If the sensor isn't working at all, even "cheap" is just wasted money. However, if you insist on less expensive obsolete sensors, Adafruit still sells guaranteed (genuine old stock) MPU-6050 breakouts.

looking at old code I did get some results from MPU6500 and MPU6050 on an ESP32
MPU6500 code

// File>Examples>Bolder_Flight_Systems_InvenSense_IMU>Arduino>impu6500>i2c

/*
* Brian R Taylor
* brian.taylor@bolderflight.com
* 
* Copyright (c) 2021 Bolder Flight Systems Inc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the “Software”), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#include "mpu6500.h"

/* Mpu6500 object */
bfs::Mpu6500 imu;

void setup() {
  /* Serial to display data */
  Serial.begin(115200);
  while(!Serial) {}
  /* Start the I2C bus */
  Wire.begin();
  Wire.setClock(400000);
  /* I2C bus,  0x68 address */
  imu.Config(&Wire, bfs::Mpu6500::I2C_ADDR_PRIM);
  /* Initialize and configure IMU */
  if (!imu.Begin()) {
    Serial.println("Error initializing communication with IMU");
    while(1) {}
  }
  /* Set the sample rate divider */
  if (!imu.ConfigSrd(19)) {
    Serial.println("Error configured SRD");
    while(1) {}
  }
}

void loop() {
  /* Check if data read */
  if (imu.Read()) {
    Serial.print(imu.new_imu_data());
    Serial.print("\t");
    Serial.print(imu.accel_x_mps2());
    Serial.print("\t");
    Serial.print(imu.accel_y_mps2());
    Serial.print("\t");
    Serial.print(imu.accel_z_mps2());
    Serial.print("\t");
    Serial.print(imu.gyro_x_radps());
    Serial.print("\t");
    Serial.print(imu.gyro_y_radps());
    Serial.print("\t");
    Serial.print(imu.gyro_z_radps());
    Serial.print("\t");
    Serial.print(imu.die_temp_c());
    Serial.print("\n");
    delay(1000);
  }
}

serial monitor output

1	-6.94	-25.42	2.60	-0.01	-0.02	0.02	119.04
1	-6.24	-23.77	3.10	-0.02	-0.02	0.02	119.04
1	-4.73	-24.69	3.23	-0.02	-0.02	0.01	119.04
1	-4.73	-24.74	3.17	-0.01	-0.02	0.02	119.04
1	-4.75	-24.78	3.24	-0.02	-0.02	0.01	119.04
1	-4.65	-24.72	3.18	-0.01	-0.02	0.02	119.04
1	-8.50	-31.06	1.55	-0.02	-0.02	0.02	119.04
1	-13.48	-21.20	1.64	-0.02	-0.02	0.02	119.04
1	-15.46	-18.48	-0.96	-0.02	-0.02	0.02	119.04
1	-10.50	-11.50	-2.30	-0.02	-0.02	0.02	119.04
1	0.95	-10.57	3.42	-0.02	-0.02	0.02	119.04
1	0.25	-34.97	-3.89	-0.02	-0.02	0.01	119.04
1	-1.47	-32.12	-5.63	-0.01	-0.02	0.02	119.04

MPU60050 code

// ESP32 Basic demo for accelerometer readings from Adafruit MPU6050

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

Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit MPU6050 test!");
Wire.begin();
  // Try to initialize!
  if (!mpu.begin(0x68)) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case MPU6050_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case MPU6050_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case MPU6050_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    Serial.println("+- 250 deg/s");
    break;
  case MPU6050_RANGE_500_DEG:
    Serial.println("+- 500 deg/s");
    break;
  case MPU6050_RANGE_1000_DEG:
    Serial.println("+- 1000 deg/s");
    break;
  case MPU6050_RANGE_2000_DEG:
    Serial.println("+- 2000 deg/s");
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }

  Serial.println("");
  delay(100);
}

void loop() {

  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(5000);
}
Adafruit MPU6050 test!
MPU6050 Found!
Accelerometer range set to: +-8G
Gyro range set to: +- 500 deg/s
Filter bandwidth set to: 21 Hz

Acceleration X: 0.04, Y: 0.39, Z: 8.35 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.04 degC

Acceleration X: 0.42, Y: 2.15, Z: 7.68 m/s^2
Rotation X: 0.07, Y: -0.65, Z: -0.07 rad/s
Temperature: 22.16 degC

Acceleration X: -3.13, Y: 4.82, Z: 5.66 m/s^2
Rotation X: -0.51, Y: -0.52, Z: -0.24 rad/s
Temperature: 22.23 degC

Acceleration X: 0.91, Y: -0.04, Z: 9.27 m/s^2
Rotation X: 1.01, Y: 0.07, Z: 0.09 rad/s
Temperature: 22.27 degC

Acceleration X: 0.01, Y: -0.51, Z: 8.30 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.01 rad/s
Temperature: 22.31 degC

Acceleration X: 0.03, Y: -0.51, Z: 8.31 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.01 rad/s
Temperature: 22.35 degC

Acceleration X: 0.02, Y: -0.51, Z: 8.30 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.37 degC

not used the MPU6500 or MPU6050 for any serious work

in an industrial project some time back I used the lsm9ds1 9-axis iNEMO inertial module (IMU)
test using a ESP32

// ESP32 SPI to STEVAL MKI159V1 LSM9DS1  9-axis IMU
//  https://www.st.com/en/evaluation-tools/steval-mki159v1.html

/* wiring
	LSM9DS1 --------- ESP32
          CS_AG -------------GPIO5
          CS_M ------------- GPIO17
          SDO_AG ----------- GPIO19 VSPI_MISO
          SDO_M ------------ GPIO19 (tied to SDO_AG)
          SCL -------------- GPIO18 VSPI_CLK
          SDA -------------- GPIO23 VSPI_MOSI
          VDD -------------- 3.3V
          GND -------------- GND
          */

// library https://github.com/sparkfun/LSM9DS1_Breakout
// code File>Examples>SparkFun_LSM9DS1_IMU>LSM9DS1_Basic_SPI.ino

/*****************************************************************
LSM9DS1_Basic_SPI.ino
SFE_LSM9DS1 Library Simple Example Code - SPI Interface
Jim Lindblom @ SparkFun Electronics
Original Creation Date: April 29, 2015
https://github.com/sparkfun/LSM9DS1_Breakout

The LSM9DS1 is a versatile 9DOF sensor. It has a built-in
accelerometer, gyroscope, and magnetometer. Very cool! Plus it
functions over either SPI or I2C.

This Arduino sketch is a demo of the simple side of the
SFE_LSM9DS1 library. It'll demo the following:
* How to create a LSM9DS1 object, using a constructor (global
  variables section).
* How to use the begin() function of the LSM9DS1 class.
* How to read the gyroscope, accelerometer, and magnetometer
  using the readGryo(), readAccel(), readMag() functions and 
  the gx, gy, gz, ax, ay, az, mx, my, and mz variables.
* How to calculate actual acceleration, rotation speed, 
  magnetic field strength using the calcAccel(), calcGyro() 
  and calcMag() functions.
* How to use the data from the LSM9DS1 to calculate 
  orientation and heading.

Hardware setup: This example demonstrates how to use the
LSM9DS1 with an SPI interface. The pin-out is as follows:
	LSM9DS1 --------- Arduino
          CS_AG ------------- 9
          CS_M ------------- 10
          SDO_AG ----------- 12
          SDO_M ------------ 12 (tied to SDO_AG)
          SCL -------------- 13
          SDA -------------- 11
          VDD -------------- 3.3V
          GND -------------- GND


The LSM9DS1 has a maximum voltage of 3.6V. Make sure you power it
off the 3.3V rail! Signals going into the LSM9DS1, at least,
should be level shifted down to 3.3V - that's CSG, CSXM,
SCL, and SDA.

Better yet, use a 3.3V Arduino (e.g. the Pro or Pro Mini)!

Development environment specifics:
	IDE: Arduino 1.6.3
	Hardware Platform: Arduino Pro 3.3V
	LSM9DS1 Breakout Version: 1.0

This code is beerware. If you see me (or any other SparkFun 
employee) at the local, and you've found our code helpful, 
please buy us a round!

Distributed as-is; no warranty is given.
*****************************************************************/
// The SFE_LSM9DS1 library requires both Wire and SPI be
// included BEFORE including the 9DS1 library.
#include <Wire.h>
#include <SPI.h>
#include <SparkFunLSM9DS1.h>

//////////////////////////
// LSM9DS1 Library Init //
//////////////////////////
// Use the LSM9DS1 class to create an object. [imu] can be
// named anything, we'll refer to that throught the sketch.
LSM9DS1 imu;

///////////////////////
// Example SPI Setup //
///////////////////////
// Define the pins used for our SPI chip selects. We're
// using hardware SPI, so other signal pins are set in stone.
#define LSM9DS1_M_CS	17//10 // Can be any digital pin
#define LSM9DS1_AG_CS	5//9  // Can be any other digital pin

////////////////////////////
// Sketch Output Settings //
////////////////////////////
#define PRINT_CALCULATED
//#define PRINT_RAW
#define PRINT_SPEED 1250 // 250 ms between prints

// Earth's magnetic field varies by location. Add or subtract 
// a declination to get a more accurate heading. Calculate 
// your's here:
// http://www.ngdc.noaa.gov/geomag-web/#declination
#define DECLINATION -8.58 // Declination (degrees) in Boulder, CO.

//Function definitions
void printGyro();
void printAccel();
void printMag();
void printAttitude(float ax, float ay, float az, float mx, float my, float mz);

void setup() 
{
  Serial.begin(115200);
 
  // imu.beginSPI(), which verifies communication with the IMU
  // and turns it on.
  if (imu.beginSPI(LSM9DS1_AG_CS, LSM9DS1_M_CS) == false) // note, we need to sent this our CS pins (defined above)
  {
    Serial.println("Failed to communicate with LSM9DS1.");
    Serial.println("Double-check wiring.");
    Serial.println("Default settings in this sketch will " \
                  "work for an out of the box LSM9DS1 " \
                  "Breakout, but may need to be modified " \
                  "if the board jumpers are.");
    while (1)
      ;
  }
}

void loop()
{
  printGyro();  // Print "G: gx, gy, gz"
  printAccel(); // Print "A: ax, ay, az"
  printMag();   // Print "M: mx, my, mz"
  
  // Print the heading and orientation for fun!
  // Call print attitude. The LSM9DS1's magnetometer x and y
  // axes are opposite to the accelerometer, so my and mx are
  // substituted for each other.
  printAttitude(imu.ax, imu.ay, imu.az, -imu.my, -imu.mx, imu.mz);
  Serial.println();
  
  delay(PRINT_SPEED);
}

void printGyro()
{
  // To read from the gyroscope, you must first call the
  // readGyro() function. When this exits, it'll update the
  // gx, gy, and gz variables with the most current data.
  imu.readGyro();
  
  // Now we can use the gx, gy, and gz variables as we please.
  // Either print them as raw ADC values, or calculated in DPS.
  Serial.print("G: ");
#ifdef PRINT_CALCULATED
  // If you want to print calculated values, you can use the
  // calcGyro helper function to convert a raw ADC value to
  // DPS. Give the function the value that you want to convert.
  Serial.print(imu.calcGyro(imu.gx), 2);
  Serial.print(", ");
  Serial.print(imu.calcGyro(imu.gy), 2);
  Serial.print(", ");
  Serial.println(imu.calcGyro(imu.gz), 2);
#elif defined PRINT_RAW
  Serial.print(imu.gx);
  Serial.print(", ");
  Serial.print(imu.gy);
  Serial.print(", ");
  Serial.println(imu.gz);
#endif
}

void printAccel()
{
  // To read from the accelerometer, you must first call the
  // readAccel() function. When this exits, it'll update the
  // ax, ay, and az variables with the most current data.
  imu.readAccel();
  
  // Now we can use the ax, ay, and az variables as we please.
  // Either print them as raw ADC values, or calculated in g's.
  Serial.print("A: ");
#ifdef PRINT_CALCULATED
  // If you want to print calculated values, you can use the
  // calcAccel helper function to convert a raw ADC value to
  // g's. Give the function the value that you want to convert.
  Serial.print(imu.calcAccel(imu.ax), 2);
  Serial.print(", ");
  Serial.print(imu.calcAccel(imu.ay), 2);
  Serial.print(", ");
  Serial.println(imu.calcAccel(imu.az), 2);
#elif defined PRINT_RAW 
  Serial.print(imu.ax);
  Serial.print(", ");
  Serial.print(imu.ay);
  Serial.print(", ");
  Serial.println(imu.az);
#endif

}

void printMag()
{
  // To read from the magnetometer, you must first call the
  // readMag() function. When this exits, it'll update the
  // mx, my, and mz variables with the most current data.
  imu.readMag();
  
  // Now we can use the mx, my, and mz variables as we please.
  // Either print them as raw ADC values, or calculated in Gauss.
  Serial.print("M: ");
#ifdef PRINT_CALCULATED
  // If you want to print calculated values, you can use the
  // calcMag helper function to convert a raw ADC value to
  // Gauss. Give the function the value that you want to convert.
  Serial.print(imu.calcMag(imu.mx), 2);
  Serial.print(", ");
  Serial.print(imu.calcMag(imu.my), 2);
  Serial.print(", ");
  Serial.println(imu.calcMag(imu.mz), 2);
#elif defined PRINT_RAW
  Serial.print(imu.mx);
  Serial.print(", ");
  Serial.print(imu.my);
  Serial.print(", ");
  Serial.println(imu.mz);
#endif
}

// Calculate pitch, roll, and heading.
// Pitch/roll calculations take from this app note:
// http://cache.freescale.com/files/sensors/doc/app_note/AN3461.pdf?fpsp=1
// Heading calculations taken from this app note:
// http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/Magnetic__Literature_Application_notes-documents/AN203_Compass_Heading_Using_Magnetometers.pdf
void printAttitude(float ax, float ay, float az, float mx, float my, float mz)
{
  float roll = atan2(ay, az);
  float pitch = atan2(-ax, sqrt(ay * ay + az * az));
  
  float heading;
  if (my == 0)
    heading = (mx < 0) ? PI : 0;
  else
    heading = atan2(mx, my);
    
  heading -= DECLINATION * PI / 180;
  
  if (heading > PI) heading -= (2 * PI);
  else if (heading < -PI) heading += (2 * PI);
  
  // Convert everything from radians to degrees:
  heading *= 180.0 / PI;
  pitch *= 180.0 / PI;
  roll  *= 180.0 / PI;
  
  Serial.print("Pitch, Roll: ");
  Serial.print(pitch, 2);
  Serial.print(", ");
  Serial.println(roll, 2);
  Serial.print("Heading: "); Serial.println(heading, 2);
}

connections

	LSM9DS1 --------- ESP32
          CS_AG -------------GPIO5
          CS_M ------------- GPIO17
          SDO_AG ----------- GPIO19 VSPI_MISO
          SDO_M ------------ GPIO19 (tied to SDO_AG)
          SCL -------------- GPIO18 VSPI_CLK
          SDA -------------- GPIO23 VSPI_MOSI
          VDD -------------- 3.3V
          GND -------------- GND

test output

G: -14.07, -6.37, -6.42
A: 0.04, 0.11, 0.98
M: -0.27, -0.03, -2.03
Pitch, Roll: -2.19, 6.18
Heading: 15.17

G: -15.28, -1.79, 5.76
A: 0.03, 0.18, 0.96
M: -0.26, -0.05, -2.01
Pitch, Roll: -1.76, 10.61
Heading: 19.80

G: 2.08, -2.61, -2.85
A: -0.05, 0.20, 0.99
M: -0.31, -0.04, -2.01
Pitch, Roll: 2.57, 11.19
Heading: 15.96

G: 1.93, -13.53, -9.34
A: -0.14, -0.15, 0.97
M: -0.34, 0.08, -2.07
Pitch, Roll: 7.97, -8.67
Heading: -3.88

G: -6.40, -8.05, 5.09
A: -0.26, -0.65, 0.66
M: -0.40, 0.32, -2.08
Pitch, Roll: 15.44, -44.84
Heading: -30.03

G: 120.19, -53.47, 7.18
A: -0.24, -0.99, 0.17
M: -0.40, 0.51, -1.94
Pitch, Roll: 13.59, -80.27
Heading: -43.79

G: 4.00, 8.12, -2.55
A: -0.12, -0.87, -0.34
M: -0.38, 0.60, -1.69
Pitch, Roll: 7.58, -111.27
Heading: -49.40

G: -1.35, 9.72, -1.72
A: -0.24, -0.54, -1.01
M: -0.38, 0.55, -1.48
Pitch, Roll: 11.80, -151.78
Heading: -46.52

G: 10.31, -7.27, -0.82
A: -0.12, -0.32, -0.98
M: -0.35, 0.46, -1.34
Pitch, Roll: 6.66, -162.12
Heading: -44.44

G: -17.56, 4.85, -25.63
A: -0.17, -0.09, -1.47
M: -0.33, 0.41, -1.31
Pitch, Roll: 6.47, -176.35
Heading: -42.79

G: -9.35, -1.90, -3.95
A: -0.34, -0.14, -0.96
M: -0.48, 0.42, -1.36
Pitch, Roll: 19.10, -171.67
Heading: -32.93

G: -16.29, 24.10, -11.80
A: -0.78, -0.32, -0.62
M: -0.62, 0.41, -1.48
Pitch, Roll: 48.03, -152.36
Heading: -24.61

G: -12.59, 6.97, 1.13
A: -0.96, -0.25, -0.29
M: -0.71, 0.39, -1.67
Pitch, Roll: 68.42, -139.40
Heading: -20.13

G: 21.15, 13.39, -10.01
A: -0.99, -0.28, -0.18
M: -0.70, 0.38, -1.73
Pitch, Roll: 71.22, -122.63
Heading: -19.80

G: -7.24, -61.29, 29.60
A: -0.95, -0.34, -0.44
M: -0.69, 0.39, -1.64
Pitch, Roll: 59.72, -141.91
Heading: -21.14

G: 1.71, -19.76, 0.35
A: -0.47, -0.33, -0.84
M: -0.48, 0.44, -1.40
Pitch, Roll: 27.49, -158.24
Heading: -34.55

G: 3.75, -34.78, 30.00
A: 0.04, -0.23, -0.98
M: -0.28, 0.44, -1.33
Pitch, Roll: -2.21, -166.73
Heading: -48.78

G: -8.76, 29.02, -3.68
A: 0.23, 0.05, -0.92
M: -0.17, 0.30, -1.29
Pitch, Roll: -14.26, 176.93
Heading: -52.52

G: 17.53, -0.90, -0.28
A: -0.10, 0.63, -0.97
M: -0.32, 0.07, -1.26
Pitch, Roll: 4.73, 147.13
Heading: -4.63

G: 28.59, -16.22, -12.28
A: -0.04, 0.93, -0.61
M: -0.30, -0.07, -1.33
Pitch, Roll: 1.85, 123.19
Heading: 21.66

G: 0.91, -7.70, -2.80
A: -0.02, 0.96, -0.34
M: -0.30, -0.15, -1.40
Pitch, Roll: 1.20, 109.45
Heading: 34.91

G: 11.93, -7.62, -4.58
A: -0.06, 0.99, -0.27
M: -0.30, -0.18, -1.45
Pitch, Roll: 3.21, 105.17
Heading: 39.00

G: -117.07, -12.70, -13.09
A: 0.07, 1.08, -0.50
M: -0.26, -0.11, -1.36
Pitch, Roll: -3.23, 114.84
Heading: 31.03

G: -29.99, -14.36, -3.26
A: -0.04, -0.41, -0.89
M: -0.30, 0.46, -1.38
Pitch, Roll: 2.22, -155.20
Heading: -48.89

G: -20.28, 1.67, -9.07
A: -0.08, -0.85, -0.66
M: -0.33, 0.56, -1.58
Pitch, Roll: 4.18, -127.55
Heading: -51.20

G: -25.65, -3.62, -15.29
A: -0.21, -0.99, -0.26
M: -0.41, 0.56, -1.77
Pitch, Roll: 11.78, -104.75
Heading: -45.58

G: 97.54, -9.90, 75.77
A: -0.29, -1.01, -0.10
M: -0.45, 0.52, -1.87
Pitch, Roll: 16.11, -95.74
Heading: -40.84

G: -26.72, -20.28, 28.00
A: -0.18, -0.94, 0.13
M: -0.37, 0.50, -1.93
Pitch, Roll: 10.57, -82.17
Heading: -45.21

G: -21.45, -2.41, -2.25
A: 0.01, -0.89, 0.48
M: -0.28, 0.35, -2.10
Pitch, Roll: -0.58, -61.42
Heading: -42.798.

the lsm9ds1 is now Obsolete replaced with the lsm6dso 6-axis IMU

Okay, I dug around and found another I2C device (a 16K33 I've had for years but never used), and the I2C scanner couldn't find that either. Is it possible that a previous sketch has changed something in these ESPs that needs changing back? I've never used I2C before, so I don't have any experience to draw on, but it does look like the issue may be the I2C on the ESPs?

never had any particular problems with I2C on ESP32s
which specific ESP32 series do you have, e.g. ESP32, ESP32S3, ESP32C3, etc
I have used this scanner on ESP32s

// ESP32 scan both I2C ports
// from https://wokwi.com/projects/350122233155289684

#include <Wire.h>

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

  Wire.begin(21,22);             // default: 21, 22
  Wire1.begin( 19, 18);     // I don't know the default pins !

  Serial.println("---------- Scanning Wire -------------");
  I2C_ScannerWire();

  Serial.println("---------- Scanning Wire1 ------------");
  I2C_ScannerWire1();
}

void loop() { delay(10); }

void I2C_ScannerWire()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
}

void I2C_ScannerWire1()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    Wire1.beginTransmission(address);
    error = Wire1.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
}

a run on an ESP32 with a LMS9DS1 9-axis iNEMO inertial module on Wire1 and a BMP280 pressure sensor on Wire results

14:44:44.491 -> ---------- Scanning Wire -------------
14:44:44.491 -> Scanning...
14:44:44.525 -> I2C device found at address 0x76  !
14:44:44.525 -> done
14:44:44.525 -> 
14:44:44.525 -> ---------- Scanning Wire1 ------------
14:44:44.525 -> Scanning...
14:44:44.525 -> I2C device found at address 0x1C  !
14:44:44.525 -> I2C device found at address 0x6A  !
14:44:44.525 -> done
14:44:44.525 -> 


MPU6050 and a BME280 on Wire

---------- Scanning Wire -------------
Scanning...
I2C device found at address 0x68  !
I2C device found at address 0x76  !
done

---------- Scanning Wire1 ------------
Scanning...
No I2C devices found

Okay, I just dug out an old Arduino Uno, ran an I2C scanner on that with the 6500 and "I2C device found at address 0x68".

I ran your code, and it found a device at 0x68 as well.

So I reran the scanning code I originally tried, and it now finds the 6500s as well.

I uploaded the IMUIdentifier example from the FastIMU library, and that identified it as a 6500.

I uploaded the Calibrated_sensor_output sketch from the same library, and it's outputting values just fine.

I have no idea what has changed, but they now seem to be working...

you probably had a poor connection
I find jumper wires cause poor connections and intermittent faults all the time, e.g. a test setup does not work - rewire it with different wires and it works!
for real projects use soldered connections or screw connections

It could be that, but it's unlikely. During my initial testing, I had 2xESPs, 2x6500s, different wires, I continuity tested from pin to pin on the devices, not just the wires, and I measured the voltages at the 6500. It's unlikely a poor connection could have survived all that. I think this will just have to go down as a mystery of the universe!