I2C Scanner not working

Hello,

I am trying to run the i2c scanner example, and I do not get a scan. I either get "Scanning...." or "No I2C Device Found".

Here is the Code:

/*
   This sketch will be used as an I2C Scanner
*/

#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for (address = 1; address < 127; address++);
  {
    // The I2C scanner uses the return value of
    // the Write.endTransmission to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
  }

  if (error == 0);
  {
    Serial.println("I2C Device found at address 0x");
    if (address < 16)
    {
      Serial.print("0");
      Serial.print(address, HEX);
      Serial.println(" !");

      nDevices++;
    }
  }
  if (error == 4)
  {
    Serial.print("Unknown error at address 0x");
    if (address < 16);
    {
      Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
  {
    Serial.println("No I2C Devices Found\n");
  }
  else
  {
    Serial.println("done\n");
  }
  delay(5000);
}

Here is what Serial Monitor says:

Here is my setup:

None of my I2C devices are getting scanned

Please help Thank you

Which pins are the yellow an black wires connected to and which way round ?
image

My bad

Yellow is SCL and Blue is SDA

Try this Scanner Program:

#include <Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin();      //Edit (D4, D3);
  Serial.println("I2C search");
  Serial.println("-------------------------");

  Wire.begin();
  int i2c = 0b0000000;
  for (int i = 0; i < 127; i++)
  {
    Serial.print("Search at [");
    Serial.print(i2c, HEX);
    Serial.print("]: ");
    Wire.beginTransmission(i2c);
    byte busStatus = Wire.endTransmission();
    if (busStatus == 0)
    {
      Serial.println("FOUND!");
      while(1);
    }
    else
    {
      Serial.println("not found");
    }
    i2c++;
  }
}

void loop() {}
1 Like

Why the resistors in series with the I2C lines? That will work as a voltage divider with the pull-up resistors.

1 Like

I tried without the resistors. I still don't get a scan.

The sensor is a 3.3V device whilst the Uno is a 5V device. I know that you are powering the sensor with 3.3V but the GPIO pins of the Uno will still be using 5V

Could this be a factor here ?

Which other devices have you tried ?

What is the purpose of "D4 and D3" ?

Carefully follow the Sparkfun guide for connecting that sensor: Qwiic Pressure Sensor (BMP581) Hookup Guide - SparkFun Learn

That code is for ESP8266. For UNO, the code will be simply:

Wire.begin();

Sorry for the inconvenience!

I tried both pins with no success. However, I figured a slightly larger voltage wouldn't make much of a difference. In fact, I would think a slightly bigger voltage would help.

When you say devices do you mean Arduinos or sensors?

Sensors I am using a SparkFun BMP581 and a Honeywell SEK001 to test.
Arduinos I have an Uno and a Mega.

I did. I used the exact code, and it is not working. Suggestions for this are also welcome.

Your picture clearly shows the wrong wiring, so take a closer look at that tutorial.

It is a 3.3V sensor, and you may have already destroyed it by connecting it to a 5V Arduino without using level shifters.

The bigger voltage is not always better. A sensor designed to work at 3.3V may not be able to survive a connection to 5V! Fortunately, I2C doesn't actively drive the signal lines. Both ends can pull the signals down to zero volts, but depend on the pullup resistors to make the lines go high whenever nothing is driving the line.

You might need to use a voltage level shifter to convert the 3.3V signals from your sensors into the 5V signals needed by the Arduino.

What pullup resistors are you using ? 10K would be suitable for this circuit.

No idea why you are bothering with series resistors as these will just add to the pullup resistor value and never allow the Voltage to reach its low value required for I2C operation.

Just remember that with I2C, lines are pulled low, not driven low.

If the Arduino is trying to read this sensor, it will never happen, given that the input is tied to a Voltage above 0V by the divider chain.

You're probably right.

Do I need the voltage level shifter? The hookup guide for the BMP581 doesn't mention it. However, it seems like an important piece of hardware. If I just send the proper supply voltage to the sensor it should work right?
But...
You're saying that the voltage shifter is needed bc the voltage of the signals coming from both the Arduino and the sensor is cancelling each other out.

When either side of the I2C link wants to send a zero, it pulls the line down to zero volts. To send a one, the device disconnects from the line and lets the pull-up resistor pull the line up to the power supply voltage. The problem is that the Arduino expects close to 5V for a one, but the sensor can only tolerate 3.3V. This may not be enough for the Arduino to reliably detect that the signal is a one.

You can try by connecting one sensor as a test. Connect the SDA pin of the sensor to the SDA pin of the Arduino, and also connect a resistor from the SDA pin to +3.3V. Similarly, the SCL signal of the sensor connects directly to the SCL signal of the Arduino, then connect a resistor from SCL to 3.3V. The resistors can be anything from about 2K to 10K or so. The value isn't that critical.

The level shifter is built into the Qwicc interface. If you do not use the Qwicc interface, as instructed in the hookup guide, you need a separate level shifter.

The above proposition is not right exactly. The data sheet of ATmega328P MCU of the UNO Board says the following; where, an input voltage as low as 3.0V (VIH) will be detected by Arduino UNO as Logic HIGH.

logicLevelofUNO