BMI160 I2C address not found

I have been individually checking every connection carefully with a multimeter, very carefuly avoided shorting due to soldering, and looked over my design and code thoroughly. Despite this, I cannot seem to get my IMU and Arduino Nano to speak to eachother.

I will upload my code and circuit diagram below (on the stripboard, all ICs have holes cut inbetween each pin - it's just not covered in the diagram).

Circuit diagram:


Code (just looking for address first - to make sure device works):

 #include <Wire.h>

void setup() {
  Serial.begin(115200);
  while (!Serial) ;
  Wire.begin(); // for Nano: uses A4/A5
  Serial.println("\n--- I2C Scanner + BMI160 WHO_AM_I test ---");
  delay(200);
}

void loop() {
  // 1) Generic scanner
  Serial.println("I2C scan:");
  int devices = 0;
  for (uint8_t addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    uint8_t err = Wire.endTransmission();
    if (err == 0) {
      Serial.print("  Device found at 0x");
      if (addr < 16) Serial.print("0");
      Serial.print(addr, HEX);
      Serial.println();
      devices++;
    }
    delay(2);
  }
  if (devices == 0) Serial.println("  No I2C devices found");
  Serial.println();

  // 2) Read BMI160 WHO_AM_I (chip id) from 0x68 and 0x69
  uint8_t regs[] = {0x00}; // BMI160 CHIP_ID register
  uint8_t addrs[] = {0x68, 0x69};
  for (uint8_t i = 0; i < 2; i++) {
    uint8_t a = addrs[i];
    Serial.print("Trying BMI160 at 0x");
    Serial.print(a, HEX);
    Serial.print(" ... ");
    // write register address
    Wire.beginTransmission(a);
    Wire.write(regs[0]);
    uint8_t err = Wire.endTransmission(false); // repeated start
    if (err != 0) {
      Serial.print("no ACK (err ");
      Serial.print(err);
      Serial.println(")");
      delay(10);
      continue;
    }
    // request one byte
    Wire.requestFrom((int)a, 1);
    if (Wire.available()) {
      uint8_t val = Wire.read();
      Serial.print("read 0x");
      if (val < 16) Serial.print("0");
      Serial.print(val, HEX);
      Serial.println();
    } else {
      Serial.println("no data");
    }
    delay(10);
  }

  Serial.println("\n--- end test ---\n");
  delay(2000);
}

I'm missing pullup resistors on all SDA and SCL lines.

Does the level converter not account for that?

I'm not sure I understand the purpose of pullup resistors - sorry for my ignorance!

To quote Google: “Pull-Up Resistors:

Both the SCL and SDA lines are pulled high by external pull-up resistors. Devices on the bus "pull" the lines low to transmit a logical '0'. “.

I found this in my notes:

It seems like there’s a misunderstanding or over generalization regarding the use of the I2C bus. While I2C is not suitable for every application, it remains widely used and reliable for many purposes, particularly for short-distance communication between multiple peripherals and microcontrollers.

Key Points About I2C:

  1. Intended Use: I2C is designed for communication over short distances within the same circuit board or between closely placed modules. It’s ideal for connecting sensors, EEPROMs, RTCs, and other peripheral devices to microcontrollers.

  2. Common Misapplications:

  • Long Distances: I2C is not well-suited for communication over long cables or between devices far apart due to signal degradation and noise susceptibility.

  • High-Speed Requirements: I2C's speed (typically up to 400 kHz for standard applications) may not be sufficient for high-speed data transfer needs, such as video signals or high-frequency data streams.

  1. Challenges with I2C:
  • Pull-up Resistors: Proper pull-up resistors are crucial for stable communication. Incorrect values or missing resistors can lead to signal integrity issues. Be careful of the build up of parallel pull up resistors on modules.

  • Bus Conflicts: Because I2C is a shared bus, miscommunication or conflicts can arise if not properly managed, especially with multiple devices.

  • Noise Sensitivity: I2C lines are susceptible to electromagnetic interference (EMI), which can cause errors in noisy environments.

  1. When I2C is a Good Choice:
  • Small Systems with Close Components: I2C excels in small projects where sensors and microcontrollers are close together.

  • Low-Speed Sensor Integration: It’s great for interfacing sensors, displays, and other low-speed peripherals that don’t require long communication lines.

Conclusion:

There’s no need to abandon I2C altogether; it’s a valuable tool when used in the right context. The key is to understand its limitations and use it appropriately. For applications where I2C might not be the best fit, consider alternatives like SPI (for faster communication) or UART, CAN, RS485, RS232, etc (for longer-distance serial connections). The I2C bus interface does not source any current, it requires external pull up resistors of the appropriate value.

2 Likes

Thank you for the detailed explanation. As a self-taught hobbyist this helps clarify some confusion I had.

I will try to add a pullup resistor and update the forum how it worked!

I agree, most level converters would have components to pull-up the i2c lines. Not a very strong pull-up, but should be fine for a single i2c slave and short wires like you have.

So I don't know what the problem is but I suspect adding more external pull-up resistors may not fix anything.

In your schematic, the GND pin on the HV side of the level converter is not connected. I suspect this may not matter because it is probably internally connected to the GND pin on the LV side. But may be worth trying connecting both GND pins. I think they should really both be connected anyway.

¿What is the part number of that level shifter?

Thanks for the suggestion, I gave this a shot but nothing changed

It is a generic chip I found on aliexpress: 4 channel IIC I2C Logic Level Converter

While using a multimeter, I find that even the unused channels on the level converter read the same voltage - is this normal?

I read 3.3V on LV3 and LV4,
and 5V on HV3 and HV4

I know it will not work without them. Measure the pins and see if they are at the appropriate VCC, if not the pull up resistors are probably not there. Without a schematic of your level converter I an only guess. I have several types, some discrete and some with a IC, neither has a pull up resistors installed.

Yes. As I said before, the most common type of level converter, the bi-directional type designed for i2c, has pull-up resistors on all the signal pins.

That's strange, the discrete type always have them as far as I am aware.

Each channel is like this

That is what I now have but the originals had no resistors. I purchased them from an online biding/sales outfit about 8 years ago, no record of whom I purchased from. Thanks for catching that. I now just use the ones with the IC, they work very well.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.