Arduino & 24C256 Serial EEPROM

This is a useful addition to my previous article “Arduino EEPROM”. The article is still available. I have provided a link here for convenience https://www.electroschematics.com/arduino-eeprom-tips-tricks/

Over a year ago I bought an assortment of Serial EEPROM ICs and have been using them in my commercial projects ever since. I decided that for this post I would try sharing a simple Arduino experiment with an external AT24C256 Serial EEPROM module which I have not done before. Okay, let’s start!

AT24C256 Serial EEPROM Module

An EEPROM can store data permanently unless you erase or overwrite it and won’t lose the data when powered off. Some microcontrollers like Arduino have very limited internal storage space, so an external EEPROM will be suitable for a small amount of data storage or for extending the data storage capability of a microcontroller. The above shown compact serial EEPROM module with an AT24C256 at its core has 256k bit capacity. It can communicate with a microcontroller thru the I2C bus, providing much more data storage space easily.

This is the basic schematic of the 24C256 Serial EEPROM module (borrowed from web).

As you can see, apart from the AT24C256 chip (U1), the module holds one power indicator LED (D1) with its series resistor (R1), four 2-way jumper pins (J1-J2-J3-J4), two I2C pull-up resistors (R2-R3), and finally a 4-pin male header (P1) as the interface connector.

Note that when a jumper is placed over the jumper pins, an electrical connection is made between them to activate certain settings accordingly (https://en.wikipedia.org/wiki/Jumper_(computing).

The first jumper (J1) is for write protection (WP) which can enable or disable the microcontroller writing data to the EEPROM chip, while the next three jumpers (J2-J3-J4) are address input pins (A0-A1-A2) for multiple device operation.

Likewise, the SCL pin is the serial clock line and the SDA pin is the serial data line. The clock line is used to synchronize data transfer to and from the device between the microcontroller and the EEPROM chip whereas the data line is used to transfer data bidirectionally between the microcontroller and the EEPROM chip.

Since I2C is an open-drain/open-collector communication, appropriate pullup resistors are crucial to pull the communication lines HIGH when they are not driven LOW by the open-drain interface (https://e2e.ti.com/cfs-file/ __key/communityserver-discussions-components-files/6/I2C-Bus-Pullup-Resistor-Calculation.pdf).

ATMEL AT24C256

The core component of the Serial EEPROM module presented here – AT24C256 – is a 32kx8(256k) Serial CMOS EEPROM 8-pin IC from Atmel (https://ww1.microchip.com/downloads/en/DeviceDoc/doc0670.pdf).

An EEPROM chip is very useful because it’s a non-volatile form of memory. This means that even when the device is powered off, it still retains the program that’s written to it, and when you power it back on, the program that’s written to the EEPROM can be run again!

See the key features of 24C256 below.

  • Low Voltage and Standard-Voltage Operation
  • 2-wire Serial Interface
  • Internally Organized 16,384 x 8 and 32,768 x 8
  • Bi-directional Data Transfer Protocol
  • 100kHz and 400kHz Compatibility
  • Write Protect Pin for Hardware Data Protection
  • 64-byte Page Write Modes
  • Partial Page Writes are Allowed
  • Self-timed Write Cycle (10mS max)
  • High-Reliability, 1 million Write Cycles, 100 Year Data Retention

Here is its pin description table:

Arduino & External EEPROM

Now we have the key hardware handy. Now we can begin an experiment by connecting it with an Arduino board to write to and read from the EEPROM chip. We can write anything we want to it if it’s within 256 kilobits of memory and read from it any time we want.

By using an EEPROM chip instead of an SD card, we save space, power, and complexity. Luckily, connecting the EEPROM module to an Arduino board is simple. Note that the address pins need consideration only if more than one EEPROM modules are going to be used. To write data, the WP (write protect) pin must be connected to GND. A typical interconnection between an Arduino microcontroller and a 24C256 serial EEPROM is shown in the table below.

24C256 EEPROM MODULE ARDUINO UNO
VCC 5V
SCL SCL/A5
SDA SDA/A4
GND GND

As pointed out before, the communication bus consists of a serial clock line and a serial data line. The clock is generated by the bus master and data is transmitted serially on the data line synchronized to the clock.

Here, the Arduino microcontroller serves as the bus master, initiating all data transfers and generating the clock which regulates the flow of data. The serial device 24C256 present on the bus is considered slave, accepting or sending data in response to orders from the master. The bidirectional data transfer protocol utilized by the 24C256 allows a number of

compatible devices to share a common 2-wire bus.

Remember, to set the module’s device address, you only must connect the address pins to VCC or GND through the address selection jumpers J2-J3-J4. If you take a look at the datasheet, you get useful pointers on how to use the address input pins to configure the device address of the 24C256 chip.

Look, the sequence 1010 for the first four MSBs is mandatory for all I2C EEPROMs from Atmel. This control byte (consists of a 4-bit control code) is the first byte received following the start condition from the master device. As you already noticed, the control byte is set as 1010 binary for read and write operations.

The next three bits (A2-A1-A0) allow you to connect up to 8 devices on the same I2C Bus. The last bit (LSB) is the READ or WRITE operation selection bit. If this is 1, then the read operation is selected and if this bit is 0, then the write operation is selected.

Following the start condition, the 24C256 monitors the SDA bus checking the control byte being transmitted. Upon receiving a 1010 code and appropriate device select bits, the slave device outputs an acknowledge signal on the SDA line. Depending on the state of

the R/W bit, the 24C256 will select a read or write operation.

So, by default (A0+A1+A2 = GND) the device address will be:

For WRITEoperations: 1010 (control code) + 000 (A2, A1, A0 value) + 0 (write) → 0xA0

For READoperations: 1010 (control code) + 000 (A2, A1, A0 value) + 1 (read) → 0xA1

NOTE: We can ignore the LSB of the device address while writing the code as the “Arduino Wire” Library takes care of it depending on the operation. So, we can declare the device address as 0x50. Remember, now you’re going to play with a 24C256 (256 kbit) EEPROM chip which has 32kbytes of space (262,144 bits/8 bits in a byte = 32,768 bytes). That’s 62 times the Arduino’s built-in storage!

(https://www.flightpedia.org/convert/256-kilobytes-to-bytes.html).

Now all we need is a quick test code. So, let’s get to that!

[code]

#include
“at24c256.h”

at24c256
eeprom(0x50); // 0x50 = A1(GND), A0(GND)

//————————————————–

void
setup() {

Serial.begin(57600);

eeprom.init();

eeprom.write(30000, 0xAA);

Serial.println(eeprom.read(30000), HEX);

}

//————————————————–

void
loop() {

}

[/code]

The above simplistic code can be used for a quick test of the functionality of the EEPROM chip. Note that the loop contains nothing because a for loop repeats itself over and over again. We don’t need that as we want the microcontroller writing to the chip once, not repetitiously. Therefore, we put all the functions in the setup() function.

Arduino Library used here can be downloaded through its documentation page (Bulgarian) https://www.kn34pc.com/spr/arduino_24c256.html

If you do not wish to rely on a third-party library for a quick test, this code is for you. No changes to the hardware settings are required.

[code]

#include

#define M1
0x50 // Device Address

void
setup() {

Serial.begin(9600);

wire.begin();

unsigned int address = 1;

writeEEPROM(M1, address, 0x18);

readEEPROM(M1, address);

}

void loop()
{}

void
writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {

Wire.beginTransmission(deviceaddress);

Wire.write((int)(eeaddress >> 8)); // MSB

Wire.write((int)(eeaddress & 0xFF))); //
LSB

Wire.write(data);

Serial.println(Wire.endTransmission());

delay(20);

}

void
readEEPROM(int deviceaddress, unsigned int eeaddress ) {

Wire.beginTransmission(deviceaddress);

Wire.write((int)(eeaddress >> 8)); // MSB

Wire.write((int)(eeaddress & 0xFF))); //
LSB

Serial.println(Wire.endTransmission());

delay(5);

Wire.requestFrom(deviceaddress, 1);

if (Wire.available() > 0) {

Serial.println(Wire.read(), HEX);

} else {

Serial.println(“NO DATA!”);

}

}

[/code]

If all goes well, you will get a serial monitor readout like this:

For a detailed reading, go through this post https://www.hobbytronics.co.uk/arduino-external-eeprom

NOTE: VCC range of 24C256 is 4.5V-5.5V and the maximum clock frequency is 400kHz. But a low-voltage version is also available, that is 24LC256. The 24LC256 has a VCC range of 2.5V-5.5V (https://www.futurlec.com/Memory/24LC256a.shtml).

And You’re Done!

That’s all you need to know in order to use and external serial EEPROM chip with your Arduino. As mentioned before, this is basically a dirty experiment with the 24C256 module. So, if you plan to use it more seriously, I highly recommend to dig deeper into the possibilities of the module. It’s not that hard when you like to do it 💛

Leave a Comment