0
\$\begingroup\$

I have an MPU9250 IMU sensor (namely this board: 9DOF Razor IMU M0) that I am using to measure orientation.

I want to use the MPU's Digital Motion Processor (DMP) to compute the orientation based on its measurements. Now I need to transfer the computed data to the Raspberry Pi over I2C, and this is where I am having difficulties.

9DOF Razor IMU M0 Code:

#include <Wire.h>
#include <SparkFunMPU9250-DMP.h>
#define SerialPort SerialUSB

#define SLAVE_ADDRESS 0x08
uint8_t data_to_echo = 0;

MPU9250_DMP imu;

bool run_imu = true;

void setup() 
{
  SerialPort.begin(9600);
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  if(run_imu){
    if (imu.begin() != INV_SUCCESS)
    {
      while (1)
      {
        SerialPort.println("Unable to communicate with MPU-9250");
        SerialPort.println("Check connections, and try again.");
        SerialPort.println();
        delay(5000);
      }
    }
    imu.dmpBegin(DMP_FEATURE_6X_LP_QUAT | // Enable 6-axis quat
               DMP_FEATURE_GYRO_CAL, // Use gyro calibration
              100); 
  }
}

void loop()
{ }

void receiveData(int bytecount)
{
  for (int i = 0; i < bytecount; i++) {
    data_to_echo = Wire.read();
  }
}

void sendData()
{
  Wire.write(data_to_echo);
}

Behaviour:

When run_imu = false, the i2cdetect -y 1 detects two devices on the I2C bus - 0x08 and 0x68 and I am able to echo bytes back and I would hope that the same will keep happening when I turn the IMU and DMP on. However, after setting run_imu=true, the only device on the I2C bus seems to be the MPU9250 and I cannot send bytes to the MCU. (I get the OSError: [Errno 121] Remote I/O error as the device with the address 0x08 is not present on the bus)

Problem:

I was able to send bytes back and forth between the SAMD21 processor (which is on the 9DOF Razor IMU M0 board) and the RPi. However, when I turn the imu on (by calling imu.begin()) I am no longer able to communicate with the MCU, and the only I2C address shown by i2cdetect -y 1 is the MPU's 0x68.

I am guessing it has to do something with the fact that the MCU and MPU9250 also communicate using an I2C bus and imu.begin() registers the MCU as a master wrt. to the MPU and therefore it cannot serve as a slave to the RPi - am I right?

Question:

Is there a way how the 9DOF Razor IMU M0's MCU can send data from the DMP over I2C to the Raspberry Pi? Ideally I would like to be able to something like:

.
.
.
void loop() 
{
  // Check for new data in the FIFO
  if ( imu.fifoAvailable() )
  {
    // Use dmpUpdateFifo to update the ax, gx, mx, etc. values
    if ( imu.dmpUpdateFifo() == INV_SUCCESS)
    {
      // computeEulerAngles can be used -- after updating the
      // quaternion values -- to estimate roll, pitch, and yaw
      imu.computeEulerAngles();
      
      // Sending the orientation to the RPi using I2C, something like:
      Wire.write(imu.roll);
      Wire.write(imu.pitch);
      Wire.write(imu.yaw);
    }
  }
}
.
.
.

Any tips or ideas on how I might go about transferring the data from the DMP over I2C to the Raspberry Pi are highly appreciated - Thanks!

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

To be precise, if a device supports being a master and a slave, it will not be a master and a slave simultaneously, as there can never be more than one master communicating on the bus at one given time.

But yes, most MCUs have I2C peripherals that allow them to become a master and communicate with a slave, and also be the slave to which another master can communicate. This is called multimaster support. M0 likely supports it. No clue if the RPi supports it, or if the drivers or software libraries you are using do support or allow it.

If you want that to happen, you have two masters on the bus, the RPi and M0, that can both become masters on the bus, and they must both support the fact that another device is allowed to become master while bus is free.

So even if M0 could be the master for IMU, and slave for RPi, both the RPi and M0 need multimaster support.

It might be easier for the RPi to be the slave for M0, so M0 polls for IMU data and polls for RPi if it wants to receive processed IMU data. Or just forger M0 and access IMU directly with RPi.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.