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!