Atmel 24C256 showing up at wrong I2C address

I took an Atmel 24C256 (8-pin SOIC, I2C EEPROM) from an old Nokia 5120, and soldered it to a protoshield (with SMD pads), properly connecting it to SCA, SCL, GND, +5V.

All the 2 address pins are tied to GND, and so is the "write protect" and NC pin. This should have made the EEPROM appear at address 0x50, but it is not.

Using a sketch called i2cScanner (see below), I was able to see it is in address 0xE8. the problem is that writes to that address always return "success", but nothing is read afterwards.

I've tried writing/reading at address 0x50, 0x51 but nothing works. I am using the common I2C EEPROM routines found in the "Playground" and several other sites.

Any tips on what I shoud do next or how to fix that?

i2cScanner.ino:

// --------------------------------------
 // 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
 //
 // June 2012
 // Using Arduino 1.0.1
 //
 
#include <Wire.h>
 

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

void loop()
 {
   byte error, address;
   int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
   for(address = 0; address <= 254; address++ ) 
  {
     // The i2c_scanner uses the return value of
     // the Write.endTransmisstion to see if
     // a device did acknowledge to the address.
     Wire.beginTransmission(address);
     error = Wire.endTransmission();
 
    if (error == 0)
     {
       Serial.print("I2C device found at address 0x");
       if (address<16) 
        Serial.print("0");
       Serial.print(address,HEX);
       Serial.println(" !");
 
      nDevices++;
     }
     else if (error==4) 
    {
       Serial.print("Unknow 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(8000);           // wait 8 seconds for next scan
 }

and so is the ... NC pin.

Why did you ground the NC pin?

Showing the scanner code is useless. That's not the code you are having trouble with, is it?

PaulS:

and so is the ... NC pin.

Why did you ground the NC pin?

Showing the scanner code is useless. That's not the code you are having trouble with, is it?

I grounded it because it was grounded in the board I took it from.

Here is a pic of the chip in its original circuit:

About the code, I posted because that code is the one detecting the chip's address. Besides, this i2c scanner code might be useful for somebody else, like it's been to me so many times.

The point is: like the code shows, "something" gives an ACK on address 0xE8, which is the supposed 7-bit address of the EEPROM (0x50) shifted right 1 bit.

Besides, this i2c scanner code might be useful for somebody else, like it's been to me so many times.

That's a good enough reason.

The point is: like the code shows, "something" gives an ACK on address 0xE8, which is the supposed 7-bit address of the EEPROM (0x50) shifted right 1 bit.

And, you've presumably modified your code to write and read using that address, and you had problems. I thought it was that code you wanted help with.

PaulS:
And, you've presumably modified your code to write and read using that address, and you had problems. I thought it was that code you wanted help with.

Yes, I've modified my code to read/write one byte at a time at 0xE8.

Here is the code I am using:

#include <Wire.h> //I2C library

byte DEV_ADDR = 0xE8;


  uint8_t i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write((byte)rdata);
    return Wire.endTransmission();
  }


  byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    delay(25);
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
  }

  void setup() 
  {
    Wire.begin(); // initialise the connection
    Serial.begin(115200);
   
    // write from A..Z in addresses 0..25
    for (byte i=0;i<=25;i++) 
        if (i2c_eeprom_write_byte(DEV_ADDR, i, i+65) == 0) {
          Serial.print("W:0x");     
          Serial.print(i, HEX);   
          Serial.print(" = > ");
          Serial.println((char)(i+65)); // byte written
          delay(1000);
        }


   Serial.println("\n\nMemory written ------------------ \n\n");
   
  }

  void loop() 
  {
   Serial.println("\n\n ------------------ Reading memory");
    byte b = '-'; // just to make sure it's not gibberish
    for (int addr = 0; addr <= 25; addr++) 
    {
        b = i2c_eeprom_read_byte(DEV_ADDR, addr);
        Serial.print("R:0x");
        Serial.print(addr, HEX);
        Serial.print(" = > ");
        Serial.println((char)b); //print content to serial port
        b = '-';
        delay(1);
    }
    Serial.println(" ");
    delay(200000);

  }

In the setup, it just appears to be doing the writing successfully, but actually nothing is done.

The problem is that when reading, it only reads 'Z' all the time, because that's the last byte that was written, so I guess it is something that was left in some buffer, but not actually written to the EEPROM.

I run that code once. Bytes from 0..25 should be A..Z, right? Because it wsa written in the previous run. However, if I comment the writting code and just leave the reading code, nothing is read. Literally, it reads blanks.

I am sure that the WP pin is grounded, so writing should be enabled.

So that are 2 things that are weird.

BTW, I am feeding this IC with 5V. According to its marking, it is the 2.7V version, so it can go up to 5.5V (and 6.5V absolute maximum according to the datasheet).

Thanks a lot for your help, PaulS.

You pass the data into the i2c_eeprom_write_byte function as a byte. You store the byte in an int. Then, you cast the int to a byte to actually write it. Why?

You are converting the address to two bytes, then casting the bytes as ints to specify the two byte address. Why?

I basically copied those functions from Arduino Playground - I2CEEPROM and changed here and there to make it work somehow, but nothing writes to the memory.

This is how the code is currently standing:

uint8_t i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((byte)(eeaddress >> 8)); // MSB
    Wire.write((byte)(eeaddress & 0xFF)); // LSB
    Wire.write(data);
    return Wire.endTransmission();
}

  
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((byte)(eeaddress >> 8)); // MSB
    Wire.write((byte)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    delay(25);
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
	Wire.endTransmission();
    return rdata;
}

For what they cost I'd bin it and get a new one! Even if they had a batch especially made that had a different bus address you would still expect to be able to write and read the device.

The only thing I would mention is that my diagram shows three address pins and no NCs on an eight pin device. But you grounded the NC in any case.

HI,

Can you see if it works with a smaller serial data rate. I think some of the I2C eeprom parts support frequencies from 10kHz to 100kHz and then at 400khz

vj1953:
HI,

Can you see if it works with a smaller serial data rate. I think some of the I2C eeprom parts support frequencies from 10kHz to 100kHz and then at 400khz

How do I do that?

HW or SW?