Usando una memoria EEPROM con Arduino

Arduino tiene una memoria no volátil de tan sólo 512 bytes, que puede ser insuficiente en algunos casos.

Pero podemos usar una EEPROM externa, en mi caso he usado una EEPROM serie 24LC256 que tiene una capacidad de 256 Kbit (32K x 8 bytes) y un precio de 2.88 euros. Os dejo el enlace a

la hoja de especificaciones.

La comunicación entre Arduino y la EEPROM se realiza mediante el bus I2C , que se trata de un bus de comunicaciones serie formado por dos lineas: una para los datos y otra para el reloj.

La librería Wire  permite manejar un bus I2C desde nuestro Arduino, y en este artículo del wiki encontramos 4 funciones que usando la librería anterior implementan la lectura/escritura en la EEPROM.

El parámetro deviceaddress al que hacen referencia estas funciones en el caso de esta memoria se trata del 0x50.

No debemos olvidarnos de inicializar la conexión antes de usar estas funciones:

Wire.begin();

En cuanto a las conexiones de los pines: el pin 5 de la EEPROM (SDA) lo conectamos a la entrada analógica 4 de nuestro Arduino, el pin 6 (SCL) a la entrada analógica 5 (observar en la foto que los cables de color naranja se cruzan), el pin 8 a 5V y todos los demás a tierra.

Los pines analógicos 4 y 5 de Arduino son los que usa la librería Wire.

En cuanto al sketch, os pongo el ejemplo con el que lo probé: se trata de escribir una cadena de caracteres cuando enciende nuestro Arduino y de leerla y enviarla al ordenador repetidamente.

  1. /* Ejemplo EEPROM
  2.  * Autor: kans
  3.  * Fecha: 05/03/2008
  4.  */
  5.  
  6. #include <Wire.h> //libreria I2C
  7.  
  8. //Las siguientes funciones para lectura y escritura en una EEPROM se encuentran en el wiki de Arduino: http://www.arduino.cc/playground/Code/I2CEEPROM
  9.  
  10. void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
  11.   int rdata = data;
  12.   Wire.beginTransmission(deviceaddress);
  13.   Wire.send((int)(eeaddress >> 8)); // MSB
  14.   Wire.send((int)(eeaddress & 0xFF)); // LSB
  15.   Wire.send(rdata);
  16.   Wire.endTransmission();
  17. }
  18.  
  19. // WARNING: address is a page address, 6-bit end will wrap around
  20. // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
  21. void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
  22.   Wire.beginTransmission(deviceaddress);
  23.   Wire.send((int)(eeaddresspage >> 8)); // MSB
  24.   Wire.send((int)(eeaddresspage & 0xFF)); // LSB
  25.   byte c;
  26.   for ( c = 0; c < length; c++)
  27.     Wire.send(data[c]);
  28.   Wire.endTransmission();
  29. }
  30.  
  31. byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
  32.   byte rdata = 0xFF;
  33.   Wire.beginTransmission(deviceaddress);
  34.   Wire.send((int)(eeaddress >> 8)); // MSB
  35.   Wire.send((int)(eeaddress & 0xFF)); // LSB
  36.   Wire.endTransmission();
  37.   Wire.requestFrom(deviceaddress,1);
  38.   if (Wire.available()) rdata = Wire.receive();
  39.   return rdata;
  40. }
  41.  
  42. // maybe let's not read more than 30 or 32 bytes at a time!
  43. void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
  44.   Wire.beginTransmission(deviceaddress);
  45.   Wire.send((int)(eeaddress >> 8)); // MSB
  46.   Wire.send((int)(eeaddress & 0xFF)); // LSB
  47.   Wire.endTransmission();
  48.   Wire.requestFrom(deviceaddress,length);
  49.   int c = 0;
  50.   for ( c = 0; c < length; c++ )
  51.     if (Wire.available()) buffer[c] = Wire.receive();
  52. }
  53.  
  54.  
  55. void setup() {
  56.   char cadena[] = "hola mundo desde una eeprom"; //cadena a escribir
  57.   Wire.begin(); //es obligatorio inicializar la conexion
  58.   Serial.begin(9600);
  59.   i2c_eeprom_write_page(0x50, 0, (byte *)cadena, sizeof(cadena)); //escribir la cadena al principio de la EEPROM; comentar esta linea para probar que la memoria es no volatil
  60.   delay(10); //peque�a pausa despues de escribir en la memoria
  61. }
  62.  
  63. void loop() {
  64.   int addr=0; //direccion a leer
  65.   byte b = i2c_eeprom_read_byte(0x50, 0); //acceso a la primera posicion de memoria
  66.  
  67.   while (b!=0) {
  68.     Serial.print((char)b); //enviar al ordenador
  69.     addr++; //siguiente direccion
  70.     b = i2c_eeprom_read_byte(0x50, addr); //acceso a posicion de memoria
  71.   }
  72.   Serial.println();
  73.   delay(2000);
  74. }

Al tratarse de una memoria no volátil, podemos comentar la escritura (línea 59) para comprobar que permanecen los datos guardados con anterioridad.

 

Related Articles

Este espacio lo he creado pensando en los entusiastas como tú, para compartir y centralizar documentación sobre temas que me apasionan: Arduino, impresoras 3D, Raspberry Pi, y mucho más.

Además, he querido fusionarlo con mi canal de YouTube, donde exploramos retro-informática, Raspberry Pi, consolas retro, electrónica y otras maravillas del mundo tecnológico. Este es tu sitio si disfrutas aprendiendo, creando y reviviendo lo mejor de la tecnología de ayer y hoy.

¡Bienvenido!