Introduction: Add I2C EEPROM to Arduino
Attaching an EEPROM to the Arduino is quite simple and the easiest way to do that is via the I2C bus. EEPROMs come in many forms but the 24 LS256 or 24LC256 is a good choice as it is easy to use and pretty cheap (85 euro cents at my supplier). The 24LC256 holds 256 kilobits of data (that is 32 kilobytes). The 24LS256 can also run on 3.3V which is handy if one is using a Lilypad or Pro Mini 3.3V. The 24LS256 uses 3 pins for selection of its address, so you can use up to eight at once on the same bus.
The 24LS256 is addressed as follows: 1010A2A1A0. If you are only working with 1 EEPROM, the easiest is to connect A2-A0 with Ground. This gives the address of 1010000 which is 0×50 Hex. In reading and writing to the EEPROM one needs to realize that it has 32 kB (actuall32767) and one byte is not enough to address all the memory.
So when one wants to send read and/or write requests, one needs to send two bytes – one for the MSB or higher end of the address (the 8 bits from left to right), and the next one for the LSB or lower end of the address (the final 8 bits from left to right).
If for example one wants to use address 21000, that goes as follows: In binary, 21000 is 0101001000001000. Split that up into 01010010 and 00001000, then convert the binary values back to numerical bytes to send with Wire.send().
That sounds more complicated than it is, as there are in fact two operands to do that. This first one is >>, also known as 'bitshift right'. This will take the highest (left) part of the byte and drop off the lower end, leaving only the first 8 bits. To get the lower (right) end of the address, one can use operator &, also known as ' bitwise AND'. This operand, when used with 0xFF will give the lower bits.
Writing data to the 24LS256
Writing data is quite easy. First initialize the I2C bus with:
Wire.beginTransmission(0x50); // for pins A0~A2 set to GND
then send some data. The first data to send are the two bytes for the address (25000) were one wants to write to the memory.
Wire.send(21000 >> 8); // send the MSB of the address
Wire.send(21000 & 0xFF); // send the LSB of the address
Subsequently send the byte to store at address 21000 and then close the connection:
Wire.send(15); //just sending ‘15’ as example
Wire.endTransmission();
That concludes the writing. now for reading:
Reading data from the 24LS256
Reading is more or less similar. First initialize the connection and provide the address of the data to read:
Wire.beginTransmission(0x50); // Chosen base address
Wire.send(21000 >> 8); // send MSB of the address
Wire.send(21000 & 0xFF); // send LSB of the address
Wire.endTransmission();
Then, supply the number of data bytes to read starting at the current address:
Wire.beginTransmission(0x50); // base address
Wire.requestFrom(0x50,1); // We want one byte
Wire.receive(inbyte);
Here, 'inbyte' is a byte variable chosen to store the data retrieved from the EEPROM.
The Power of the I2C bus is of course that various devices can be connected to the same lines. The top figure shows such a set up with two EEPROMs. It is key of course that they each have their own address. In the figure I have chosen to use addresses 0×50 and 0×51. One gets that by connecting A0-A2 to ground for one chip, but connecting A0 to Vcc (‘ High’) for the second chip. The resulting address is then 1010001 = 0x51
And that is it.
A print design can be found here
Approx. cost: 2 euro
17 Comments
5 years ago
Could this code and methodbe used to make an I2C EEPROM programmer as well?
Reply 5 years ago
thank you. as the code writes to eeprom, technically that is programming the eeprom.
Obviously you need a bit more code depending on what you' d want to store in EEPROM
Reply 5 years ago
I have data in hex format that I want to load onto an I2C EERPOM. Thanks for the great post.
Reply 5 years ago
That is possible, but you need a program that reads that data and then stores it in EEPROM. If you have that data on say an SD card, it shouldnt be too hard to read it with an arduino and then put it in EEPROM
5 years ago
Hi there, diy_bloke.
I think there is one mistake: you want to write data to address 21000, but in the line above the arduino code for writing data you put 25000 in brackets.
Reply 5 years ago
ah yes, obviously a mistake. thank you
6 years ago
Hi, may I just how can I store a program inside a EEPROM so that when the power is off and turn on again the device will continue where it left off before powering down.
Reply 6 years ago
Well that is not really storing a program :-)
But what you could do is to store all the relevant variables and at the end of your Setup call these variables from EEPROM and assign them. The program will then not start at the same place in was stopped, but at least it will start in the same state as it left off. But here is the problem.......... If you also want to cater for sudden power loss, you need to story any variable the moment it changes. That could amass to many write operations that wear your EEPROM down.
There is maybe a fix for that by having the arduino measure the voltage that it receives and only do the memory store operation when the voltage drops an x%, but your program might just not be fast enough to write everything in a sudden powerloss
8 years ago on Introduction
Thank you so much for explaining the addressing scheme of the eeprom so easily!!!! :D
Reply 8 years ago on Introduction
my pleasure. Glad you liked it
8 years ago on Introduction
Im selling 24lc256 2 wire for $ 0.80 each. Just saying.
Reply 8 years ago on Introduction
http://www.ebay.com/itm/24LC256-I-P-5pcs-256k-bit-400khz-2-wire-EEPROM-for-Arduino-/301373531259?pt=LH_DefaultDomain_0&hash=item462b43247b
8 years ago on Introduction
Cool
If i wanted to just use 1 chip
would i only connect the first one and done or do i need to have something else?
Reply 8 years ago on Introduction
only connect the first one
Reply 8 years ago on Introduction
Thanks
10 years ago on Introduction
what was your motivation for doing this? why will you be using i2c?
Reply 10 years ago on Introduction
Because it is requires less wires and thus leaves more ports for other things. Also easily expandable, without requiring more wires