1
\$\begingroup\$

I have a Raspberry Pi 4B connected to a 9 DOF Razor IMU M0 (equipped with a MPU9250 IMU and a SAMD21 microprocessor).

I am trying to echo bytes back to the RPi, however, I seem to be getting corrupted data and I am unable to figure out what might be the cause of the problem.

My setup:

Wiring:

RPi IMU
GPIO 2 SDA
GPIO 3 SCL
GND (pin 9) GND
3.3V 3V3

Below, you can also find the attached picture of the wiring.

Image of the wiring setup

Code:

First, the sensor I2C-slave code:

#include <Wire.h>
#define SLAVE_ADDRESS 0x68
uint8_t data_to_echo = 0;

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

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);
}

And the RPi, I2C master code in Python:

#!/usr/bin/env python3

import time
import smbus2 as smbus

DEVICE_BUS = 1
ADDRESS =0x68

number = 1
def main():
      bus = smbus.SMBus(DEVICE_BUS)
      data = 4
      bus.write_byte(ADDRESS, data)
      print("I sent: ", data)
      number = bus.read_byte(ADDRESS)
      print("I received: ", number)

if __name__=="__main_":
     main()

Expected behavior:

I am sending one byte from the RPi to the sensor and echoing the value back. So the expected behavior is that after sending the value "4", the same value should be received.

Real behavior:

However, after running the RPi code, this is the output:

I sent: 4
I received: 3

What I have tried:

First thing that I tried was to check whether the IMU is getting the correct data. I was sending the values of data_to_echo to the serial port and the data was correct.

The same code with the same wiring worked with an Arduino Nano acting as a slave and therefore I assume that the wiring and jumper cables themselves shouldn't be the cause of the problem.

I even examined the communication using an oscilloscope and it seems like the IMU is really sending 0x03, instead of 0x04 (See the attached oscilloscope screen capture).

Screen capture of the oscilloscope

I also believe that the IMU board is faulty, as other IMU boards I tried exhibit the same behavior.

Any ideas or suggestions on what might be wrong and why I am receiving wrong data are welcome. Also, I would be grateful for any tips on what to check next because I am running out of ideas.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

The IMU and MCU are on the same bus.

You are telling the MCU to be at the same slave address as the IMU already is.

Therefore both the MCU and IMU get the first byte, 0x04.

Then you try to read from both devices. Usually MCUs support multimaster communication and arbitration, so as long as the IMU and MCU try to send identical bits, everything is fine, but when MCU would try to set the 0x04 bit high on the bus, the IMU still pulls the wire low, and you don't get 0x04 high. The MCU detects that it has lost the bus so it gives up and releases the bus. The IMU may continue sending high bits.

So in short, set the MCU slave address to be different from the IMU address. You can't communicate with either of them, if they are at the same address.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the reply! Yes, this indeed seems like the cause of the problem. I got mixed up with "who" I am communicating - I thought that the MPU's fixed I2C address somehow means the address of the "whole" device. So after changing #define SLAVE_ADDRESS to some other unused value I started receiving correct values. Thank you once more for the insight and quick response. \$\endgroup\$
    – domiinio
    Feb 21, 2023 at 7:57
0
\$\begingroup\$

If it were me, I'd try and see if I could get more information about how it goes wrong.

For instance, try replacing the send data on the client with the fixed value of 0xFF, and then try 0x00. Do either get sent correctly? If both are incorrect, are they the same incorrect value or different? Is there a pattern?

If the pattern isn't clear, maybe try incrementing the value you return each time (0, 1, 2, etc).

Hopefully this will give greater insight on possible causes.

You might also want to check the pullups on the I2C lines (as I've often seen corruption issues when these are too weak) and try a slower clock speed.

(As others have noted, you must have unique I2C addresses for all devices. Ensure the slave device isn't using the same address as another device on the module. See the addressing section of the hookup guide 9dof-razor )

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the quick reply. Yes, the problem was, as both @Justme and you have pointed out that I was addressing two devices with the same I2C address - changing the #define SLAVE_ADDRESS fixed the issue. Thank you for your tips! \$\endgroup\$
    – domiinio
    Feb 21, 2023 at 8:00

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.