I am trying to read an EEPROM chip that supports the I2C protocol (cannot tell the IC model number as it is not printed). For sure it supports the I2C protocol, since I wrote a code to detect it using the I2C library and the device address I got it return is 0x51. Now I am trying to write a code that reads data from this IC chip. The code is as follows:

#include <Wire.h>

int addr = 0;

void setup() {
    Wire.begin(); // initialise the connection
    while (!Serial) {}

void loop() {
  byte deviceAddress = 0x51;
  byte data = readData(addr, deviceAddress);
  Serial.print(data, HEX);
  Serial.print(" ");
  if(addr%16 == 0) {
  // check for 1Kbits first
  if (addr%128 == 0) {
     Serial.println("round complete");
     addr = 0;

byte readData(int address, int deviceAddress) {
  // sending device address
  Wire.requestFrom((short int)deviceAddress, 1);
  if(Wire.available()) {
    byte data = Wire.read();
    return data;  
  return 0xAA; // random data

The problem I am facing is, I get back the address (from which I want to read the data) as the data itself (For e.g. read(0) returns 0, read(1) returns 1 and so on). I even tried to debug the I2C communication using the logic analyzer (Saleae logic in this case). A screenshot is shown below.

enter image description here

The screenshot shows the logic for a read operation from a single address (0x78), but the story holds for each and every address i.e. I get back the address instead of the data from the address.

The output of the above code is as follows:

0 1 2 3 4 5 6 7 8 9 A B C D E F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
round complete

Can you help me identifying what possibly I am doing wrong here?


  • How about using a 16-bit address? Here is a link to a driver that I have written for Cosa; github.com/mikaelpatel/Cosa/blob/master/libraries/AT24CXX/… Commented Mar 11, 2016 at 23:07
  • How many legs (pins) does the chip have?
    – Nick Gammon
    Commented Mar 12, 2016 at 5:05
  • I agree with Mikael too, you could try sending a 16-bit address. For example, send a zero first, then an address. In any case, can you be certain that the chip does not happen to have 0x00, 0x01, etc. inside its memory?
    – Nick Gammon
    Commented Mar 12, 2016 at 5:08
  • @MikaelPatel: I will give a try with 16-bit address and let you know what the results are.
    – MayankTUM
    Commented Mar 13, 2016 at 20:43
  • @NickGammon: Just to make sure that the contents are not 0x00, 0x01, etc. I tried to perform a write operation to the chip. But the result for reading after a write, remains the same. Maybe I have to try using 16-bit addresses as you suggested as well.
    – MayankTUM
    Commented Mar 13, 2016 at 20:45

3 Answers 3


You need to pass the address as two bytes, one by one.

Do not do:


Rather, do:

Wire.write((uint8_t)(address >> 8)); // MSB
Wire.write((uint8_t)(address & 0xFF)); // LSB

In short, you should split



Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB

I am working on a similar project right now. I have searched through many different codes and libraries and found the following to work the best: https://playground.arduino.cc/Code/I2CEEPROM

I am using the 24LC1025 who's datasheet can be found here: http://www.microchip.com/datasheet/24LC1025

I am using the 1Mb version and it uses 0x51 and 0x50 becuase it has two pages. I suspect you will find your chip to at least be similar because of the I2C Address you listed. You may have a smaller version of the same chip that only uses the one address.


Without the specific chip info this will be difficult.

However, my experience with EEPROMs and I2C is that the first action is to write a command, then write the parameter(s) for that command, then read the response.

Often, there is a status register in the EEPROM that needs to be read (by writing a command, then reading the response) to determine if the EEPROM is ready to receive a different command, like writing to set the address for a read/or/write, then the actual read command.

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.