Using external EEPROM

Hi,

I have been trying to get external EEPROM chips to work with arduino now for several days without luck. I have been crawling arduino.cc with google and tried without success dronebotworkshops tutorial, Gammon I2C, HobbyTronics and several others for guidance but nothing seems to work. Using Unoes internal EEMPROM works well.

I have tried My-MS 24C01, 24LC025 and 24AA02 chips but none seems to work as wanted. With 24LC025 I have tried multiple different chips with no apparent results.

I have tried several different code bases (all based on wire.h for I2C communication) from straightforward examples to self made code. Several version of the code is tried two Unoes and one Leonardo to rule out burned boards/pins. I think Leonardo might have some problem with fried pins but the Unoes seems to be fine running other I2C project that utilizes DTS22, OLED display and an RTC clock which still seems to work.

Pins on the left (A0-A2, Vss) are grounded, Vcc is connected to power, RW has been tried in power, ground and with digital high and low. In Unoes SCL is connected to A5 and SDA to A4 and are using 4,5kOhm resistors.

Currently my simplest test code is:

#include <Wire.h>

int mem_cell_num = 100;
const int devadress = 0x50;

void setup()
{
  Wire.begin();
  Serial.begin(9600);


  Serial.println("Start");

  byte val = 6;

  Wire.beginTransmission(devadress);
  Wire.write((int)highByte(mem_cell_num));
  Wire.write((int)lowByte(mem_cell_num));
  Wire.write(val);
  Wire.endTransmission();
  delay(50);

  Wire.beginTransmission(devadress);
  Wire.write((int)highByte(mem_cell_num));
  Wire.write((int)lowByte(mem_cell_num));
  Wire.endTransmission();
  Wire.requestFrom(devadress, 1);
  delay(50);

  // while(Wire.available()==0);
  val = Wire.read();
  Serial.print("Memcell: ");;
  Serial.print(mem_cell_num);
  Serial.print(" Value ");
  Serial.println(val);

  Serial.println("End");

}

void loop()
{
  delay(1000);
}

And the result on console:

Start
Memcell: 100 Value 255
End

Any help would be greatly appreciated as I'm running completely out of ideas and probably sanity :smiley:

I wrote this serval years ago written to test the AT24C1024B 128K bytes EEPROM:-

/*
  Memory test by Mike Cook Feb 2012
 Test my hacked Master I2C library
 added I2c.write2(address, reg 1, reg 2, *data, number of bytes)
 added reg 2 and changed number of bytes from a byte to a int
 
 I2c.setSpeed(n)  now takes 2 for 800 KHz and 3 for 1MHz
 
 Written to test the AT24C1024B 128K bytes EEPROM
 This code will handle up to four devices on the same bus
 */

// include the library code:
 #include <I2C.h>
 int memoryAddresBase = 0x50;

void setup() {
  // there are 512 pages per chip and a maximum of 4 chips on the bus at the same time
  // the top bit of the chip's page address is the lowest bit of the I2C device address
  // the next two bits of the I2C device address define what chip is addressed
  // thereore with four chips you have 512 * 4 = 2048 pages of 256 bytes per page giving 512K bytes of memory
  int page = 2;     // the 256 byte page of memory to write a test pattern to
  
  Serial.begin(9600);
  I2c.begin();
  I2c.setSpeed(2);   // I can only get my hardware to work at 800KHz but the data sheet says it should work at 1MHz
  testPage(page);    // write data to the selected page
  displayPage(page); // display data to see it arrived correctly
}

void loop() {  // nothing to do it is all in the setup()
}

void testPage(int pg){  // write a page of data to the EEPROM
   int address;
   long int time;
   uint8_t buffer[255];
   // test data - the inverse of the byte count
   for(int i= 0; i<256; i++) buffer[i] = 255 - i;  // fill up the buffer used for the page write
  Serial.print(" writing memory page ");
  Serial.println(pg, HEX);
  address = memoryAddresBase | ( pg >> 8);
  time = millis(); // make a note of the time now
  while(I2c.write2(address, pg & 0xff, 0, buffer, 256) != 0 ) { } // repeat until command is taken
  while(I2c.write(address,pg & 0xff, 0) != 0) { } // repeat until it is free - for timing purpouses only
  time = millis() - time; // work out how long it took
  Serial.print(" this took ");
  Serial.print(time);
  Serial.println("mS ");
   }

void displayPage(int pg){  // display a page of data from the EEPROM
  int c, address;
    Serial.print(" reading memory page ");
    Serial.println(pg, HEX);
    address = memoryAddresBase | ( pg >> 8); // create the I2C address of the chip to use
  for(int i=0; i<16; i++){
      while(I2c.write(address,pg & 0xff, i<<4) != 0) { }  // set up start of read
    Serial.print(i, HEX);          // print most significant nibble of address
    Serial.print("   ");
    I2c.read(address, 16);      // request 16 bytes from memory device ( note maximum buffer size is 32 bytes )
    for(int j=0; j<16; j++){   // now get the bytes one at a time
      c =  I2c.receive();     // receive a byte
      if(c < 0x10) Serial.print("0"); // print leading zero if needed
      Serial.print(c, HEX);          // print the byte
      Serial.print(" ");         
     }
     Serial.println(" ");  // new line
 }
}

Is I2C.h general Arduino library? My IDE gave an error about not finding it and I cannot find that header from my Arduino paths. Only from general kernel / raspian paths like /usr/include/linux/i2c.h

No.
The notes in the code says:-
Test my hacked Master I2C library.
So you need to find the "Master I2C library". The problem with the standard one is the limited size of the buffer. The Master I2C library has a buffer limit set at 255 so I hacked to make it 256.

Ok, got too exited to test something new that might work :smiley: Need to find that library then.

Gave now also a shot with [Sparkfun's EEPROM library](https://github.com/sparkfun/SparkFun_External_EEPROM_Arduino_Library) but it also gives false results.

Do you have a chip or a module?

You are using code with a two byte memory address used with a larger eeprom, but you have a small eeprom with only 256 bytes of memory. The device is organized as a single block of 256 x 8-bit memory.

Use

//Wire.write((int)highByte(mem_cell_num));
// Wire.write((int)lowByte(mem_cell_num));
Wire.write(mem_cell_num);

That was it!!

I'm like 95,6% sure I did try that before but apparently I messed something :sob:

Thank you both so much for the help and have a wonderful weekend! :partying_face: