Pages: [1] 2   Go Down
Author Topic: Why am I having so much trouble working with I2C EEPROMs?  (Read 1679 times)
0 Members and 1 Guest are viewing this topic.
France
Offline Offline
Jr. Member
**
Karma: 1
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: April 01, 2013, 11:44:14 am by AWOL » Logged

Offline Offline
Edison Member
*
Karma: 58
Posts: 2078
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 158
Posts: 2882
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

France
Offline Offline
Jr. Member
**
Karma: 1
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
don't confuse the I2C eeprom with the
eeprom inside the Arduino chips
i'm really talking about external I2C Eeprom.

Quote
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.



Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 158
Posts: 2882
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17259
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 158
Posts: 2882
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

France
Offline Offline
Jr. Member
**
Karma: 1
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 :
Code:
#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.

Code:
#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()
{
}
« Last Edit: April 02, 2013, 03:15:23 am by hary » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

What is that doing?

Read this: http://www.gammon.com.au/i2c-summary
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25706
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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...
Code:
void writeData(unsigned int addr, byte data)
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

France
Offline Offline
Jr. Member
**
Karma: 1
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Nick.

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

Concerning this part of code :

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.

Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

http://www.gammon.com.au/i2c
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25706
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
for (int i=0; i<258; i++)
  {
    writeData(i,i);
  }
What value do you think gets written to locations 256 and 257?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1] 2   Go Up
Jump to: