Problem with writing to I2C EEPROM

Hi All

I’ve got some code which reads data that’s coming down the serial port, it is comma delimited and then written to the internal EEPROM, this code works fine and I’m not having any issues with it.

However I’d like to use an external EEPROM for storing the data, the main reason being that I plan of having the program loaded into the Arduino and just update the data in the EEPROM, I’ll be doing this a lot though and my thinking is that if the EEPROM fails I can just replace this part instead of the whole Arduino.
When I replace EEPROM.write with “i2c_eeprom_write_byte” and EEPROM.read with “i2c_eeprom_read_byte” in my code I don’t get the same values returned as before. I’m sure that this is a simple fix but I can’t work it out??
The IC2 EEPROM that I’m using is a ‘24AA32A’

#include <Wire.h> //I2C library
#include <string.h>

void 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(rdata);
    Wire.endTransmission();
  }

  // WARNING: address is a page address, 6-bit end will wrap around
  // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
  void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddresspage >> 8)); // MSB
    Wire.write((int)(eeaddresspage & 0xFF)); // LSB
    byte c;
    for ( c = 0; c < length; c++)
      Wire.write(data[c]);
    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();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
  }

  // maybe let's not read more than 30 or 32 bytes at a time!
  void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
      if (Wire.available()) buffer[c] = Wire.read();
  }



const int ledPin1 = 2;
const int ledPin2 = 3;
const int enablePin = 8;
const int startPin = 9;

int enableState = 0;
int startState = 0;
int inPos = 0;
int counter = 0;
int eeepromAddress =0x50;
char inData[30]; // Create array and adjust the size as needed
int eepromArray[7]; // Initialise array for store eeprom data

void setup()
  {
     pinMode (ledPin1, OUTPUT);
     pinMode (ledPin2, OUTPUT);
     pinMode (enablePin, INPUT);
     pinMode (startPin, INPUT);
     Wire.begin(); // initialise the connection
     Serial.begin(9600);
     readEepromData;
  }

void readSerial(){
  while(Serial.available() > 0){
     char aChar = Serial.read();  // Read a character
     inData[inPos] = aChar;	  // Add it to the array
     inPos++;			  // Move the index forwar
     inData[inPos] = '\0';	  // Add a NULL terminator
     if(inPos == 29) break;	  // Make sure there is still room
  }
  if(inPos >= 0){
    delay (200);
    char *p =  inData;            // Array that needs splitting
    char *str;                    // Output of from Splitting sequence
    while ((str = strtok_r(p, ",", &p)) != NULL){ // delimiter is the comma
      int count = counter;        // Counter for programing EEPROM Position
      int newStr = atoi(str);     // Convert data for storing in EEPROM
      byte newStrLow = lowByte(newStr);    // Split data into lowbyte (for storing large numbers in EEPROM)
      byte newStrHigh = highByte(newStr);  // Split data into highbyte (for storing large numbers in EEPROM)
      counter ++;                 // Shift EEPROM address position
      //EEPROM.write(count, newStrLow);   // Store lowbyte data
      i2c_eeprom_write_byte(eeepromAddress, count, newStrLow);   // Store lowbyte data   
      count = counter;           // Shift EEPROM address position  
      //EEPROM.write(count, newStrHigh);  // Store highbyte data 
      i2c_eeprom_write_byte(eeepromAddress, count, newStrHigh);   // Store highbyte data 
      counter ++;                // Shift EEPROM address position
      digitalWrite (ledPin1, HIGH);
      digitalWrite (ledPin2, HIGH);
      delay(500);
      digitalWrite (ledPin1, LOW);
      digitalWrite (ledPin2, LOW);
    }
  }
  inPos = 0;
  counter = 0;
  inData[inPos] = '\0';
 // readEepromData ();
}

void readEepromData (){
  int p=0;
  for(int i=0; i<2; i++){
    Serial.print("i= ");
    Serial.println(i);
    //int valLow = EEPROM.read(i);  //Read low value from EEPROM
    int valLow = i2c_eeprom_read_byte(eeepromAddress,i);
    Serial.print("varlow " );
    Serial.println(valLow);
    i++;
    Serial.print("i= ");
    Serial.println(i);
    int valHigh = EEPROM.read(i); //Read low value from EEPROM
    int valHigh = i2c_eeprom_read_byte(eeepromAddress,i);
    Serial.print("varHigh =" );
    Serial.println(valHigh);
    int eepromData = (((valHigh)<<8)+valLow);
    eepromArray[p] = (eepromData);
    Serial.print("p =");
    Serial.println(p);    
    Serial.print("eeprom value =");
    Serial.println(eepromArray[p]);
    p++;
  }
  delay(1000);
}

void loop(){
  enableState = digitalRead(enablePin);
  startState = digitalRead(startPin);
  if (enableState == HIGH && startState == LOW){
    readEepromData ();
  }
  else if (enableState == LOW && startState == HIGH){ 
    readEepromData ();
  }
  else if (enableState == LOW && startState == LOW){
    digitalWrite (ledPin1, LOW);
    digitalWrite (ledPin2, LOW);
    readSerial ();
  }
}

Has anyone got any ideas?

Thanks

Dan

can you post a link to your actual device, please
I have found that some smaller EEPROMs only want one byte of address not two!

Hi mmcp42

I brought the device from RS Components, here is the link http://uk.rs-online.com/web/p/eeprom/6879158/
Do you think that I'm using the wrong component, I don't need a huge EEPROM, I'm storing around 80 values ranging from 0-3000.

Thanks

Dan

well it looks like you're doing the right thing

try commenting out the high-order address part see if it works :slight_smile:

mmcp42:
try commenting out the high-order address part see if it works :slight_smile:

I've tried all sorts of permutations like that, I think that when I write numbers lower than 255 and comment out the highByte everything works. I say I think because I've been over and over the code to try and make it work? :~

say againn?
you can only write bytes of data!
if it works it works!

It’s not working the way that I want it to or perhaps I’m doing it wrong

from writing to the internal EEPROM my code looks like this:

      byte newStrLow = lowByte(newStr);    // Split data into lowbyte (for storing large numbers in EEPROM)
      byte newStrHigh = highByte(newStr);  // Split data into highbyte (for storing large numbers in EEPROM)
      counter ++;                 // Shift EEPROM address position
      EEPROM.write(count, newStrLow);   // Store lowbyte data
      count = counter;           // Shift EEPROM address position  
      EEPROM.write(count, newStrHigh);  // Store highbyte data 
      counter ++;                // Shift EEPROM address position

and reading out of the EEPROM my code looks like this:

    int valLow = EEPROM.read(i);
    i++;
    int valHigh = EEPROM.read(i); //Read low value from EEPROM
    int eepromData = (((valHigh)<<8)+valLow);

This code works and I can read back what I write i.e if I write 4032 that’s what I get back.

But when I substitute EEPROM.write and EEPROM.read I don’t get the correct data back:

For Writing to the I2C EEPROM my code is like this:

      byte newStrLow = lowByte(newStr);    // Split data into lowbyte (for storing large numbers in EEPROM)
      byte newStrHigh = highByte(newStr);  // Split data into highbyte (for storing large numbers in EEPROM)
      counter ++;                 // Shift EEPROM address position
      i2c_eeprom_write_byte(eeepromAddress, count, newStrLow);   // Store lowbyte data   
      count = counter;           // Shift EEPROM address position  
      i2c_eeprom_write_byte(eeepromAddress, count, newStrHigh);   // Store highbyte data 
      counter ++;                // Shift EEPROM address position

And for reading from the I2C EEPROM my code looks like this:

    int valLow = i2c_eeprom_read_byte(eeepromAddress,i);
    i++;
    int valHigh = i2c_eeprom_read_byte(eeepromAddress,i);
    int eepromData = (((valHigh)<<8)+valLow);

Am I using the incorrect methods?

have you tried commenting out the high byte address part

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    // Wire.write((int)(eeaddress >> 8)); // MSB I removed this line for it to work with my EEPROM
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(rdata);
    Wire.endTransmission();
  }

and same for reading

Ohh okay, I've played with that but I can't remember what happend, I'll give it another go right now :slight_smile:

I seem to recall there is a sample EEPROM sketch
that's what I used to get started

(still had to patch the high address out though)

Okay thanks.

Although I'm not getting anything out of my eeprom now, just 255 :frowning:
I'm think that my breadboard is faulty of my chip has died, I'll re-wire it tomorrow............ Can you suggest a different eeprom in case I have to buy another?

I've had success with 24LC04 from rs