# Determining I2C Address without Datasheet

When setting up I2C communications, I know that it is certainly ideal to have the devices' datasheet(s), and find the I2C address of the device(s) that way. However, in some reverse-engineering applications, you don't have a datasheet available. (Or, you may just not be able to find it...)

Without the datasheet, how do you determine the default I2C address of a device? Also, what tool(s)/equipment do you need? (e.g. is a microcontroller with I2C support enough, or do you need an oscilloscope?)

• Same way as finding the IP address of an arbitrary host: The hard way. – Ignacio Vazquez-Abrams Jul 21 '13 at 19:09
• Are you trying to do this once to then write it down, or determine i2c addresses for new devices every time the device powers on? – crasic Jul 21 '13 at 19:11
• The address is only a tiny bit of an i2c device. Without a datasheet, how will you know what commands to send? – Passerby Jul 21 '13 at 19:24
• The Bus Pirate has a command ("1") for searching I2C addresses: dangerousprototypes.com/bus-pirate-manual/i2c-guide – starblue Jul 22 '13 at 7:44
• @Passerby Getting the addresses can help you figure out what devices are present by type, after which a datasheet search can be more fruitful. (I'm assuming OP isn't able to determine by physical inspection what devices are present on the bus.) – Adam Lawrence Jul 22 '13 at 12:54

It's fairly easy to write an I2C "ping" utility for a microcontroller. All you need to do is scan through the ~128 addresses and for each one:

1. Send I2C Start condition
2. Send a single byte representing the address, and get the ACK/NAK
3. Send the stop condition.

If there is an ACK (the data line held low on the 9th clock cycle) then a device with that address is present on the I2C bus. If there is no ACK then no device is present.

Don't forget that I2C addresses are in the upper 7 bits of the byte (the last bit is for read/write). Also, don't forget to ignore the special I2C addresses in your scan: http://www.i2c-bus.org/addressing/

As for hardware almost anything will work. Even if your device doesn't have I2C support it's a simple enough (and slow enough) protocol where you can bit bang it. Just make sure that whatever you use never drives the I2C lines high, only low (as per spec).

• Just a side note, knowing what the i2c device does would also help. For example, i2c Eeproms can ack multiple addresses. – Passerby Jul 21 '13 at 19:22
• @Passerby Good point. Many I2C devices have at least one hardware selectable address bit, and some such as EEPROMs have more. The EEPROMs that I have worked with have 4. With any sort of hardware scan you'll only be able to get the currently set address, not all possible addresses for that device. – srlm Jul 21 '13 at 19:46
• Well, yes, that too, but bigger i2c eeproms work like multiple smaller i2c eeproms, with the same address. A 4kb eeprom responds to only one address, but a 32kb eeprom responds to multiple addresses, including the same address that the 4kb eeprom would, because the page is part of the address. – Passerby Jul 21 '13 at 19:58

If you don't want to do it manually:

• Hook up a Raspberry Pi
• Run sudo i2cdetect -y 0
• If Run sudo i2cdetect -y 0 does not work, Run sudo i2cdetect -y 1
• Wow. This just solved my problem. Thank you. – Sudarshan Kadam Aug 20 '19 at 4:57

Here's a snippet of Arduino code that I use:

for (int address=1; address <= 126; address++) {
if (!Wire.endTransmission()) Serial.printf("Found device at: %02Xh\n", address);
}


You can connect SCL/SDA to an Arduino board, power the I2C device up then run on the Arduino board this code:

// i2c_scanner
//
// This program (or code that looks like it)
// can be found in many places.
// For example on the Arduino.cc forum.
// The original author is not know.
//
// This sketch tests the standard 7-bit addresses
// from 0 to 127. Devices with higher bit address
// might not be seen properly.
//
// Adapted to be as simple as possible by Arduino.cc user Krodal

#include <Wire.h>

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

void loop()
{
int nDevices;

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

nDevices = 0;
{
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
Serial.print("0");
Serial.println(" !");
nDevices++;
}
else if (error==4)
{