arduino-eeprom-externa-i2c-at24c256

Más memoria para Arduino con la EEPROM externa AT24C256

¿Qué es una EEPROM externa AT24C256?

El AT24C256 es un integrado que incorpora una memoria EEPROM (Electrically Erasable and Programmable Read Only Memory) que puede ser accedida a través del bus I2C.

Podemos conectar esta EEPROM externa a procesadores como Arduino para almacenar variables que persistan entre reinicios o cuando se pierda la alimentación.

La EEPROM AT24C256 dispone de 256 Kb, organizados en 32.768 celdas de un byte. Se pueden conectar hasta 4 dispositivos en el mismo bus I2C para conseguir para un total de 1 Mbit (128 KBytes)

El AT24C256 forma parte de una familia de EEPROM externa fabricadas por Atmel que incluye los modelos AT24C256 (256 Kb), AT24C512 (512 Kb) y AT24C1024 (1024 Kb). Todos los modelos se incorporan en forma de integrado de 8 pines.

Una de las ventajas del AT24C256 frente al resto de módulos de la familia existen módulos comerciales que integran esta EEPROM, diseñadas para conectar de forma sencilla con Arduino. Estos módulos incorporan un socket en el que podemos montar fácilmente cualquier integrado de la familia.

Como todas las EEPROM, el AT24C256 tiene un vida útil que depende del número de ciclo de escrituras. En el AT24C256 esta vida es muy alta, con 1.000.000 de ciclos de escritura garantizados (frente a 100.000 de la EEPROM intentar de Arduino). El tiempo de escritura es de 5ms.

La EEPROM AT24C256 es un dispositivo de bajo consumo. El consumo de durante la escritura es de 3mA, durante la escritura de 400 µA, y de 500 nA en Standby. Existen dos modelos con diferentes tensiones de alimentación, uno de 2.7 a 5.5V, y otro de 1.8V a 3.6V.

Podemos emplear el AT24C256 para almacenar variables que necesitamos que persistan entre reinicios, como valores de calibración, detectar cuando Arduino ha perdido alimentación, guardar un contador, o hacer un datalogger.

Recordamos que Arduino dispone de su propia memoria EEPROM integrada. Para más información consultar la entrada Guardar variables en la memoria EEPROM no volátil de Arduino

Precio

La EEPROM externa AT24C256 es un dispositivo barato. Podemos encontrarlo integrado en el módulo para conectarlo de forma sencilla a Arduino por 0.75€, buscando en vendedores internacionales de eBay o AliExpress.

arduino-eeprom-externa-i2c-at24c256-componente

Si en lugar de adquirir el módulo queremos adquirir el integrado independiente, podemos encontrar el AT24C256 por 0.20€, el AT24C512 por 0.40€ y el AT24C1024 por 1.15€.

Esquema montaje

La conexión es sencilla, simplemente alimentamos el módulo desde Arduino mediante GND y 5V y conectamos el pin SDA y SCL de Arduino con los pines correspondientes del sensor.

arduino-eeprom-externa-i2c-at24c256-esquema

Mientras que la conexión vista desde el lado de Arduino quedaría así.

arduino-eeprom-externa-i2c-AT24C256-conexion

En Arduino Uno, Nano y Mini Pro, SDA es el pin A4 y el SCK el pin A5. Para otros modelos de Arduino consultar el esquema patillaje correspondiente.

Verificar que vuestra modelo de EEPROM es compatible con 5V antes de conectarla a Arduino. Si no, tendréis que usar un adaptador de nivel lógico.

Ejemplos de código

El siguiente ejemplo muestra el proceso de lectura y escritura de la EEPROM externa AT24C256 a través del bus I2C.

//Vcc - 5V
//GND - GND
//SDA - A4
//SCL - A5

#include <Wire.h>
const int eepromAddress = 0x50;

// Funciones de lectura basadas en el trabajo de 
// Author: hkhijhe
// Date : 01 / 10 / 2010
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();
}

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

  // Datos de ejemplo
  char somedata[] = "datos grabados en la EEPROM";

  // Escribir ejemplo en memoria
  i2c_eeprom_write_page(eepromAddress, 0, (byte *)somedata, sizeof(somedata)); 
  delay(10);

  Serial.println(F("Escritura inicial completada"));
}

void loop()
{
  // Leer el primer byte de la memoria
  int addr = 0;
  byte value = i2c_eeprom_read_byte(eepromAddress, addr);

  // Leer e imprimir el caracter mientras sea distinto de '0'
  while (value != 0)
  {
    Serial.print((char)value);
    addr++;
    value = i2c_eeprom_read_byte(0x50, addr);
  }
  Serial.println(" ");
  delay(20000);
}

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github. github-full