No me lee bien por I2C una EEPROM

Llevo peleandome con el I2C de Arduino unos días y no consigo que haga lo que quiero. He conseguido escribir correctamente en una memoria EEPROM por I2c, concretamente en la 24LC256. Pero al leer los datos que he metido en la EEPROM la primera lectura la hace mal, las siguientes las hace bien. Podría ignorar la primera lectura siempre y mirar la segunda pero me da rabia porque tengo la sensación que se me escapa algo del I2C.

El esquema es este:

El programa que he escrito escribe 0 en las primeros 256 registros, luego escribe del registro 00 al 3F números progresivos del 14 en adelante. Esto lo hace bien, el problema biene al leer. Ahora tendría que leer desde el último registro en el que escribió hacia atrás. La primera lectura del último registro me da mal siempre, las siguientes lecturas las hace correctamente. Las pruebas las estoy haciendo en el IDE1.0 y simulando en proteus.
El código es:

#include <Wire.h>

void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial communication at 9600bps
}

int direccionmbs=0;
int direccionlsb=0;
int val = 0;

void loop()
{
//Vamos a escribir 00 en la memoria I2C
for(;direccionlsb<=255;direccionlsb++)
{
Wire.beginTransmission(80); //4 primeros bits son e la dirección de la eeprom 24lc256 1010hex los 3 bits siguientes son como configuramos las patas de la eeprom, 000 hex. ulimo bit 0 porque vamos a escribir datos en la eeprom
Wire.write(byte(direccionmbs)); //Primer byte del bus de direccion eeprom
Wire.write(byte(direccionlsb)); //Segundo byte del bus de direccion eeprom, dirección 0000H
Wire.write(val); //Valor que se guarda en la memoria eeprom
delay(70); // datasheet suggests at least 65 milliseconds
Wire.endTransmission(); // stop transmitting
}

int direccionmbs=0;
int direccionlsb=0;
val=20;

//Vamos a escribir datos en la memoria mediante I2C. Meteremos datos incrementales en la memoria 0000H hasta 00FEH
for(;direccionlsb<=63;direccionlsb++)
{
Wire.beginTransmission(80); //4 primeros bits son e la dirección de la eeprom 24lc256 1010hex los 3 bits siguientes son como configuramos las patas de la eeprom, 000 hex. ulimo bit 0 porque vamos a escribir datos en la eeprom
Wire.write(byte(direccionmbs)); //Primer byte del bus de direccion eeprom
Wire.write(byte(direccionlsb)); //Segundo byte del bus de direccion eeprom, dirección 0000H
Wire.write(val); //Valor que se guarda en la memoria eeprom
val++; // incrementamos en 1 el valor que hay que guardar en la dirección de memoria
delay(70); // datasheet suggests at least 65 milliseconds
Wire.endTransmission(); // stop transmitting
}

direccionlsb--;

//Vamos a leer datos en la memoria mediante I2C
for(;direccionlsb>=00;direccionlsb--)
{
Serial.println("direccionlsb de la 24LC256:");
Serial.println(direccionlsb,HEX);
Wire.beginTransmission(80); //4 primeros bits son e la dirección de la eeprom 24lc256 1010hex los 3 bits siguientes son como configuramos las patas de la eeprom, 000 hex. ulimo bit 1 porque vamos a leer datos en la eeprom
Wire.write(byte(direccionmbs)); //Primer byte del bus de direccion eeprom
Wire.write(byte(direccionlsb)); //Segundo byte del bus de direccion eeprom, dirección 0000H
Wire.endTransmission();

delay(70); // datasheet suggests at least 65 milliseconds

Wire.requestFrom(80,1);
if (Wire.available()>0)
{
val=(Wire.read());
Serial.println("el valor almacenado en 24LC256:");
Serial.println(val);
}
delay(70); // datasheet suggests at least 65 milliseconds
}

}

Por los resultados del terminal y el I2C debugger deduzco que el dato que sale el la del registro 00 en vez del 3F porque el dato que lee el 20 y corresponde al valor que hay almacenado en el registro 00. Encima en el I2C debugger desde el comando stop transmision

S A0 N P

el siguiente dato es el dato que lee cuando debería de ser la dirección donde está el dato. Si se mira las siguientes lecturas primero envia la direccion a leer y luego lee el dato. Haber si alguien se le ocurre que puede estar mal del código porque creo que es cosa del código. Salu2

si quieres puedes escribir varios datos seguidos a partir de una direccion de memoria sin tener que hacer la condicion de start stop para cada byte que quieres leer o escribir, esto te ahorra mucho tiempo

hace mucho estuve liado tambien con este tema y en el playground encontre que ya lo tenian hecho :slight_smile:

http://arduino.cc/playground/Code/I2CEEPROM

no valen para todas las memorias I2C, hay unas que no tienes que enviar las 2 partes de la memoria ( alta y baja) por la capacidad de la misma.

a ver si hago lo que tu y me lio con el proteus ... esta bastante bien pero nunca saco tiempo para investigar, ultimamente estoy muy dejado :smiley:

un saludo

Ese link no lo había visto, ha ver si mañana lo hecho un vistazo más a fondo.

En esta memoria hace falta las 2 partes de la memoria porque es de 256K y sino no hay manera de poder direccionar semejante memoria.

Lo de proteus te lo recomiendo, a mi me suele dar pereza montar los circuitos para hacer pruebas porque luego hay que recoger y volver a montar... y si el circuito no acaba de funcionar es una lata. De esta manera lo guardo en el pc y lo abro cuando y donde quiera y encima tardo muy poco en probar cada modificación. Se ha pasado 2 años dándome la chapa un compañero, hasta que me he puesto y es una maravilla. Si tengo tiempo intentaré subir algún otro video para ver su funcionamiento. Pero con la información que puse en el otro post http://arduino.cc/forum/index.php/topic,92250.0.html es fácil de hacer. Salu2