I am trying to debug why the magnetic sensor of my MPU9250/6500 9-Axis 9 DOF 16 Bit Gyroscope Acceleration Magnetic Sensor IIC/SPI won't connect to my Raspberry Pi 4+, but all the other sensors will. I am using the MPU-9250-Sensors-Data-Collect API which is a wrapper for the SMBUS2 package. Given that there seems to be only one master address and only two wires connecting things, I would think that if the problem was something physical, it would either work or not work, except that this sensor is a multi-chip module consisting of two dies integrated into a single QFN package. I did a bad soldering job on my first one of these sensors and it just wouldn't connect. I got a new one and it is detected by my RPi and works except for the magnetic sensor (the most relevant part of my project).
So. my question is, is this a hardware thing after all, or is there the possibility of it being a software problem?
I can't see any problems with the physical unit:
Code
    import sys
    sys.path.append('/home/tor/robot/MPU-9250-Sensors-Data-Collect/MPU-9250-Sensors-Data-Collect/mpu9250_jmdev')
    from registers import *
    from mpu_9250 import MPU9250
    import time
    import logging
    ##################################################
    # Create                                         #
    ##################################################
    mpu = MPU9250(
        address_ak=AK8963_ADDRESS, 
        address_mpu_master=MPU9050_ADDRESS_68, # In 0x68 Address
        address_mpu_slave=None, 
        bus=1, 
        gfs=GFS_1000, 
        afs=AFS_8G, 
        mfs=AK8963_BIT_16, 
        mode=AK8963_MODE_C8HZ)
    ##################################################
    # Configure                                      #
    ##################################################
    mpu.configure() # Apply the settings to the registers.
    ##################################################
    # Show Values                                    #
    ##################################################
    while True:
        print("|.....MPU9250 in 0x68 Address.....|")
        print("Accelerometer", mpu.readAccelerometerMaster())
        print("Gyroscope", mpu.readGyroscopeMaster())
        print("Magnetometer", mpu.readMagnetometerMaster())
        print("Temperature", mpu.readTemperatureMaster())
        print("\n")
        time.sleep(1)
Results
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 97, in configure
    self.configureAK8963(self.mfs, self.mode)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 233, in configureAK8963
    self.writeAK(AK8963_CNTL1, 0x00, 0.1)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 1013, in writeAK
    self.bus.write_byte_data(self.address_ak, register, value)
  File "/usr/local/lib/python3.8/dist-packages/smbus2/smbus2.py", line 458, in write_byte_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 97, in configure
    self.configureAK8963(self.mfs, self.mode)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 233, in configureAK8963
    self.writeAK(AK8963_CNTL1, 0x00, 0.1)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 1013, in writeAK
    self.bus.write_byte_data(self.address_ak, register, value)
  File "/usr/local/lib/python3.8/dist-packages/smbus2/smbus2.py", line 458, in write_byte_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "sensorTest.py", line 13, in <module>
    mpu.configure() # Apply the settings to the registers.
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 102, in configure
    self.configure(retry - 1)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 102, in configure
    self.configure(retry - 1)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 105, in configure
    raise err
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 97, in configure
    self.configureAK8963(self.mfs, self.mode)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 233, in configureAK8963
    self.writeAK(AK8963_CNTL1, 0x00, 0.1)
  File "/usr/local/lib/python3.8/dist-packages/mpu9250_jmdev/mpu_9250.py", line 1013, in writeAK
    self.bus.write_byte_data(self.address_ak, register, value)
  File "/usr/local/lib/python3.8/dist-packages/smbus2/smbus2.py", line 458, in write_byte_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error
If I put try/except blocks around smbus2.py (ioctl(self.fd, I2C_SMBUS, msg)), I can get data for the other three sensors:
|.....MPU9250 in 0x68 Address.....|
Accelerometer [-1.210205078125, -8.0, -8.0]
Gyroscope [43.9453125, -1.373291015625, -21.270751953125]
[OSError(121, 'Remote I/O error'),
 <smbus2d.SMBus object at 0xffff8d0f20a0>,
 12,
 3,
 7,
 None]
Magnetometer [0.0, 0.0, 0.0]
Temperature 24.258753407014705
What the offending function looks like:
    def read_i2c_block_data(self, i2c_addr, register, length, force=None):
        """
        Read a block of byte data from a given register.
    :param i2c_addr: i2c address
    :type i2c_addr: int
    :param register: Start register
    :type register: int
    :param length: Desired block length
    :type length: int
    :param force:
    :type force: Boolean
    :return: List of bytes
    :rtype: list
    """
    if length > I2C_SMBUS_BLOCK_MAX:
        raise ValueError("Desired block length over %d bytes" % I2C_SMBUS_BLOCK_MAX)
    self._set_address(i2c_addr, force=force)
    msg = i2c_smbus_ioctl_data.create(
        read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_I2C_BLOCK_DATA
    )
    msg.data.contents.byte = length
    try:
        ioctl(self.fd, I2C_SMBUS, msg)
    except Exception as e:
        if hasattr(e, 'message'):
            print(e.message)
        pprint([e, self, i2c_addr, register, length, force])
    return msg.data.contents.block[1:length + 1]
The sensor is readable, however:
tor@tor:~/robot$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --        
Thanks!

i2cdetect -y 1, it is #68. – SomeoneElse May 04 '21 at 17:53