Why am I having so much trouble working with I2C EEPROMs?

Hi.

I'm a beginer with Arduino and coding.
Till now, I've done some small thing copying and modifying some part of code from different place.
I moreless understood what I was doing and at least, acting this way I was learning.

But now I want to work with I2C EEPROM, I'm facing so many trouble !
I wonder why ? I already used library for LCD and it was quite easy and evident.

But for the EEPROM, I'm stuck, stuck, stuck !
I'm trying to read example but no way it becomes clear to me. There is always a lack of comment to me.

I was given this link to help :
http://playground.arduino.cc/Main/LibraryForI2CEEPROM

So I understand that we can write or read Byte by Byte or also with big bunch of data like "page" or maybe bit by bit if needed.
All of this is surely very interesting but doesn't unstuck me.
I think the coding comment are way to light for me.
There is a too big step with my coding experience and using the wire.h library.

I feel so sorry already asking so much help on the forum, but the situation makes me depressed.
I don't want to give up with my project.
I don't even know precisely what to ask for help. On top of that, I'm facing problem writing (eratic writing) to the Eeprom, so it doesn't help to progress !

Moderator edit: thread title toned down.

I had also trouble with it, and I also used the library by Rob Tillaart.

First of all, the 24C?? EEPROMs are not all the same. Which one do you have ?

You can start by reading and writing a byte to a certain location in the EEPROM.
Next thing is the 'page'. The EEPROM has pages inside, and you can't write beyond the page.
To be able to write any length of data to any location, you need to split the writing according to the pages. That is why that library contains all that code.
If you can read and write a single byte with your own sketch, you can use the library, even if you don't understand all of it.

As Erdin indicates, there are at least 3 different addressing schemes, depending upon
the particular 24LCxx chip being used. Also, don't confuse the I2C eeprom with the
eeprom inside the Arduino chips. Also, for external I2C eeprom, you need to use
pullup resistors.

don't confuse the I2C eeprom with the
eeprom inside the Arduino chips

i'm really talking about external I2C Eeprom.

Also, for external I2C eeprom, you need to use
pullup resistors.

I was having trouble with external pull up resistor, so I took them off and now it seems to work fine without ! I thought the code of the wire.h library configured the Arduino's internal pull up resistor ! But in any case, now I'm thinking, even whether I put external pull up resistor, it should not disturb it ! The problem is that I've been doing so many manipulation and trying so many code without really understanding what I was doing, I'm making a real mess !

The link that made me thinking I may not need the external pull up resistor is :
http://playground.arduino.cc/Code/I2CEEPROM

I'm using a 24C02_6. I think the 5 of 256 is missing. So it must be a 24C0256.
I'm also using a 24C0.. unreadeable value but I can write from 0 to 255, 256 is otherwriten with the first value so I guess it's a 24C0256 also.

The project is to copy the data from an Eeprom to a new one.

If I got my code working for writing and reading now, I don't know how to do this.
Now I stored the good Eeprom's data in a Excel spreadsheet but have no idea how to program the new chip.

I've seen dozens of I2C eeproms, but have no idea what a 24C0256 is. [why can't anyone
ever have something standard?]

http://www.digikey.com/product-search/en/integrated-circuits-ics/memory/2556980?k=24c02

Note - as mentioned earlier, 24C02 and 24C256 have very different addressing schemes.
First off, you really really need to know what you really have.

Also, you really really need the pullup Rs with I2C devices, despite what may "seem" to
work. As I understand it, the I2C pins on the standard Arduino chips are both open-drain,
so I've no idea why your chip should be working without the pullups.

oric_dan:
I've seen dozens of I2C eeproms, but have no idea what a 24C0256 is. [why can't anyone
ever have something standard?]

http://www.digikey.com/product-search/en?x=-867&y=-71&lang=en&site=us&KeyWords=24c0256

http://www.digikey.com/scripts/dksearch/dksus.dll?vendor=0&keywords=24c256
http://www.digikey.com/product-search/en/integrated-circuits-ics/memory/2556980?k=24c02

Note - as mentioned earlier, 24C02 and 24C256 have very different addressing schemes.
First off, you really really need to know what you really have.

Also, you really really need the pullup Rs with I2C devices, despite what may "seem" to
work. As I understand it, the I2C pins on the standard Arduino chips are both open-drain,
so I've no idea why your chip should be working without the pullups.

They are open drain when I2C mode is enabled. The standard arduino I2C library enables 'weak' pull-ups to the boards Vcc voltage for the two I2C control signals, something like 40K ohms. I have a 1307 RTC module that has on-board pull-ups that can be disabled with jumper clips and I have noted that my RTC works with or without them, most likely because of the weak pull-ups and the fact that my module is using very short path as it plugs into the shield connector.

However the correct way is to use external 4.7K ohm pull-up resistors, especially if you are attaching more then one I2C device to the bus or running any length of wire.

Lefty

They are open drain when I2C mode is enabled. The standard arduino I2C library enables 'weak' pull-ups to the boards Vcc voltage for the two I2C control signals, something like 40K ohms.

Well that would explain it.

Ok, so I put back the 5kOhm pull up resistor and now it still works fine.
I don’t know what I’ve done, maybe using a wrong piece of code.

The Eeprom’s reference I’m using are hard to read.

I’ve one :
ST CHN F
24C02 6
K0C828

I can write and read till 256 value in it. If I write, then read more than 256 value, the #256 store the same value as #0 and so on.

The second one I’m using is :
24C04
BL116
But the reference is very hard to see, so there might be something after the 4.
It behaves the same way as the first one despite it should be double size in memory !!!

Here is the code I’m using :

#include <Wire.h>     // for I2C
#define i2caddr 0x50    // device address 
byte d=0; // data to store in or read from the EEPROM

void setup()
{
  Serial.begin(9600); // Initialize the serial line
  Wire.begin();         // wake up the I2C
 
  Serial.println("Writing data...");
  for (int i=0; i<258; i++)
  {
    writeData(i,i);
  }
  Serial.println("DONE");
  Serial.println("Reading data...");
  for (int i=0; i<258; i++)
  {
    Serial.print(i);
    Serial.print(" : ");
    d=readData(i);
    Serial.println(d, DEC);
  }
  Serial.println("DONE");

}

// writes a byte of data in memory location addr
void writeData(unsigned int addr, byte data) 
{
  Wire.beginTransmission(i2caddr);
  // set the pointer position
  //Wire.write((int)(addr >> 8));
  Wire.write((int)(addr & 0xFF));
  Wire.write(data);
  Wire.endTransmission();
  while(1) {
      Wire.beginTransmission(i2caddr);
      if(Wire.endTransmission() == 0)break;
    }
}

// reads a byte of data from memory location addr
byte readData(unsigned int addr) 
{
  byte result;
  Wire.beginTransmission(i2caddr);
  // set the pointer position
  //Wire.write((int)(addr >> 8));
  Wire.write((int)(addr & 0xFF));
  Wire.endTransmission(1);
  Wire.requestFrom(i2caddr,1); // get the byte of data
  result = Wire.read();
  return result;
}

void loop()
{
}

Both Eeprom work the same with this code.
If I change the code to this, (concerning the way of addressing) I’ve got only 255 in all the bytes.

#include <Wire.h>     // for I2C
#define i2caddr 0x50    // device address 
byte d=0; // data to store in or read from the EEPROM

void setup()
{
  Serial.begin(9600); // Initialize the serial line
  Wire.begin();         // wake up the I2C
 
  Serial.println("Writing data...");
  for (int i=0; i<258; i++)
  {
    writeData(i,i);
  }
  Serial.println("DONE");
  Serial.println("Reading data...");
  for (int i=0; i<258; i++)
  {
    Serial.print(i);
    Serial.print(" : ");
    d=readData(i);
    Serial.println(d, DEC);
  }
  Serial.println("DONE");

}

// writes a byte of data in memory location addr
void writeData(unsigned int addr, byte data) 
{
  Wire.beginTransmission(i2caddr);
  // set the pointer position
  Wire.write((int)(addr >> 8));
  Wire.write((int)(addr & 0xFF));
  Wire.write(data);
  Wire.endTransmission();
  while(1) {
      Wire.beginTransmission(i2caddr);
      if(Wire.endTransmission() == 0)break;
    }
}

// reads a byte of data from memory location addr
byte readData(unsigned int addr) 
{
  byte result;
  Wire.beginTransmission(i2caddr);
  // set the pointer position
  Wire.write((int)(addr >> 8));
  Wire.write((int)(addr & 0xFF));
  Wire.endTransmission(1);
  Wire.requestFrom(i2caddr,1); // get the byte of data
  result = Wire.read();
  return result;
}

void loop()
{
}

See the smiley faces in your code? Don’t use quote tags.

Please edit your post, select the code, and put it between [code][/code] tags.

You can do that by hitting the # button above the posting area.

 while(1) {
      Wire.beginTransmission(i2caddr);
      if(Wire.endTransmission() == 0)break;
    }

What is that doing?

Read this: Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino

If I write, then read more than 256 value, the #256 store the same value as #0 and so on.

I wonder why that might be...

void writeData(unsigned int addr, byte data)

EEPROMs are typically organised into pages. You have to "commit" a write after the page size or it wraps. Better read the datasheet.

Hello Nick.

Unfortunately, the Smiley faces disappeared when I modified the quote tag to code tags.

Concerning this part of code :

while(1) {
      Wire.beginTransmission(i2caddr);
      if(Wire.endTransmission() == 0)break;
    }

It is (I think) to be sure "the job has been done". Before, I used a Delay(), but as I had problem, somebody told me to use this code instead. The problem I was facing was not from here, but I thought it clever to check if the job was done instead of waiting a certain amount of time between each writing.

AWOL, I don't understand what you mean. Sorry.

It's not necessary, whatever you think it is doing. Omit it.

 for (int i=0; i<258; i++)
  {
    writeData(i,i);
  }

What value do you think gets written to locations 256 and 257?

If the chip in question has a time that has to elapse before you can read back the data, you need to read the datasheet and see what that recommends.

hary:
I can write and read till 256 value in it. If I write, then read more than 256 value, the #256 store the same value as #0 and so on.

AWOL is telling you, you aren't going to write more than 255 into one byte, whatever system you use.

This is nothing to do with I2C, or EEPROM, by the way.

The number after the 24C02 and 24C04 can be ignored.

This one is "24C02 6", Serielles EEPROM 24C02 (hard to read, but it is there).
This one is "24C026", CMOSfold: ST 24C02
This one is "24C02 6", ST24C02_SERIAL_2K_256_x_8

So you have a 24C02 and a 24C04.

Let's start with the 24C02. Take a look at the datasheet, it has a "MODE" pin for Multibyte (4 bytes) or page select (8 bytes) to write more bytes.
But if you read and write single bytes, you don't have to use that.
It uses a single byte for the register address of 0...255.

I'm sorry to say, but I'm not happy with your code.
Could you show a function to read a single byte and a function to write a single byte. So I can comment on that.

The 24C04 has twice the memory. You can read the datasheet how they did that.
The register address is still with a single byte, but the I2C device address selects the missing address bit.
It's a dirty trick, it seems as if there are two I2C devices, each with 256 byte.

24C02, M24C02-W - 2 Kbit serial I2C bus EEPROM - STMicroelectronics
24C04, M24C04-W - 4 Kbit serial I2C bus EEPROM - STMicroelectronics

Erdin:
So you have a 24C02 and a 24C04.

Right, I'm quite sure of that now. Thank s for confirming the fact.

Erdin:
Let's start with the 24C02. Take a look at the datasheet, it has a "MODE" pin for Multibyte (4 bytes) or page select (8 bytes) to write more bytes.
But if you read and write single bytes, you don't have to use that.
It uses a single byte for the register address of 0...255.

From the datasheet link you sent me I can read §5.1.1 and §5.1.2 it is possible to write byte by byte or by pages up to 16 Bytes !
What I understand from the datasheet is that there is no difference between writting by Byte or writting by Pages till 16 Bytes. What makes the difference is whether or not, the master send the Stop condition after the ACK condition of the last Data (see figure 5 on datasheet)

For instance :
if the Byte address is 0000 0000, I can write up to 16 Bytes of data. Data1 will be written at block address 0000 0000, Data2 at block address 0000 0001......Data 16 at block address 0000 1111. Must end with the Stop condition after the last ACK condition.

If the Byte address is 0000 0100, I can write up to only 12 Bytes of data. Data1 will be written at block address 0000 0100, Data2 at block address 0000 0101......Data 12 at block address 0000 1111. Must end with the Stop condition after the last ACK condition.

if the Byte address is 0000 0100, I can write up to 12 Bytes of data, but I can also write only 1 or 2 data. Data1 will be written at block address 0000 0100, Data2 at block address 0000 0101 and I end with a Stop condition.

So I don't see any "MODE" pin.
Am I right ?

Erdin:
I'm sorry to say, but I'm not happy with your code.
Could you show a function to read a single byte and a function to write a single byte. So I can comment on that.

You don't have to feel sorry, just say it. I'm beginner and am ready to ear all kind of constructive criticism.
As I said somewhere, I'm new at coding and have specific difficulties with the I2C library to understand what I'm doing. In fact till now, I've been copying piece of code found in different places.

Erdin:
The 24C04 has twice the memory. You can read the datasheet how they did that.
The register address is still with a single byte, but the I2C device address selects the missing address bit.
It's a dirty trick, it seems as if there are two I2C devices, each with 256 byte.

24C04, M24C04-W - 4 Kbit serial I2C bus EEPROM - STMicroelectronics

Sorry I didn't find anything concerning how "they did that"