eeprom i2c [solucionado]

Pues resulta que tengo una memoria eeprom como esta

en el arduino he cargado el siguiente código y no va, me devuelve FF. Creo que no está en write protected y que escribe bien, no se si igual esta el circuito mal o el codigo tiene error, pero en principio no se me ocurre que puede ser... igual es por muerte de sueño o algo, el circuito esta tal que asi

circuito corregido (explicacion de pullup abajo)

y el código es este:
IMPORTANTE EL DELAY

#include <Wire.h>         //  EEPROM 24LC256, bibliotecas i2c
#define eeprom 0x50    // direccion de la eeprom shift

void setup(void){
  Wire.begin();           // Iniciar i2c
  Serial.begin(9600); // serial

  unsigned int address = 0;
  Serial.println("escribimos 33 en los 10 primeros bytes!");
  for(address = 0; address<10; address++) writeEEPROM(eeprom, address, '3');   // escribimos los 10 primeros bytes con 33
  Serial.println("Vamos leer si esta todo ok, debes ver 33, 33, 33, 33... 10 veces 33");

  for(address = 0; address<10; address++) {
  Serial.print(readEEPROM(eeprom, address), HEX); //aqui me falla y da FF
     Serial.print(", ");
  }
}

void loop(){
}



void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
  delay(5);
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.send(data);
  Wire.endTransmission();
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  delay(5);
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  return rdata;
}

editado:

La resistencia correcta para el pullup en un bus I2C depende de la capacitancia del bus y de la frecuencia de operación del mismo.

la formula extraida del datasheet del ATmega168 (no se si deriva de las especificaciones de I2C) es

Freq < 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 1000nS / Cbus

Freq > 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 300nS / Cbus

La EEPROM "Microchip 24LC256" specifica una capacitancia máxima por pin de 10pF .

Si utilizas alimentación por baterias es preferible utilizar resistencias que se aproximen a lo mas alto del rango. Si no existen limitaciones de consumo es preferible usar las más bajas.

parece ser que una configuración típica es 10 k? para 100 kHz, 2 k? para 400 kHz y 1 MHz.

que memoria tienes ?

una 24lc16 no se lee y escribe igual que una 24lc32

un saludo

for(address = 0; address<10; address++) writeEEPROM(eeprom, address, '3');

creo que le estás pasando 3 como string, quitale las comillas

Edit: me he colado, es un char.

SrDonGato:
que memoria tienes ?

una 24lc16 no se lee y escribe igual que una 24lc32

un saludo

es una 24LC256

revisa el montaje, creo que has cogido los pines 4 y 5 de los digitales, el BUS I2C son el 4 y el 5 analógicos, A4 (SDA) y A5 (SCL)

Un saludo ¡

ala que mal! muchas gracias, en cuanto vuelva a casa lo miro, pero va a ser eso seguro. Muchas gracias!

Hola buenos dias, una cosa a tomar en cuenta es que en el protocolo I2C hay que colocar resistencias pull-up.
Revisa eso y nos comentas.

Saludos.

cierto, no tenia conocimiento, para los que lean esto en un futuro, esto he podido averiguar:

La resistencia correcta para el pullup en un bus I2C depende de la capacitancia del bus y de la frecuencia de operación del mismo.

la formula extraida del datasheet del ATmega168 (no se si deriva de las especificaciones de I2C) es

Freq < 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 1000nS / Cbus

Freq > 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 300nS / Cbus

La EEPROM "Microchip 24LC256" specifica una capacitancia máxima por pin de 10pF .

Si utilizas alimentación por baterias es preferible utilizar resistencias que se aproximen a lo mas alto del rango. Si no existen limitaciones de consumo es preferible usar las más bajas.

parece ser que una configuración típica es 10 k? para 100 kHz, 2 k? para 400 kHz y 1 MHz.

sigue fallando ahora el output es:

escribimos 33 en los 10 primeros bytes!
Vamos leer si esta todo ok, debes ver 33, 33, 33, 33... 10 veces 33
33, FF, FF, FF, FF, FF, FF, FF, FF, FF,

segun la que utilizo yo hay un delay de 5 milis antes de leer de la memoria

te pongo el codigo que he utilizado yo hasta ahroa

un saludo

24LC512 I2C EEPROM Driver

A simple example of interfacing with the 24LC512 I2C EEPROM.

With just two pins, 3.3V and ground and no other electronics, the following sketch will interface with an I2C EEPROM, reading and writing bytes and ints.

It builds on the work of others (wayoda and JohnZero) whilst cutting the cruft. (It was my experience that the paging didn't work as hoped and that, without the delays, reading & writing was unreliable.) More details and data types to follow.

#include <Wire.h>

const int theDeviceAddress = 80;

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

void loop(void) {
  for (unsigned int theMemoryAddress = 0; theMemoryAddress < 256; theMemoryAddress++) {
    WireEepromWriteByte(theDeviceAddress, theMemoryAddress, (byte)theMemoryAddress);
  }
  for (unsigned int theMemoryAddress = 0; theMemoryAddress < 256; theMemoryAddress++) {
    Serial.print("Byte: ");
    Serial.print(theMemoryAddress);
    Serial.print(", ");
    Serial.print((int)WireEepromReadByte(theDeviceAddress, theMemoryAddress));
    Serial.println(".");
  }
  for (unsigned int theMemoryAddress = 0; theMemoryAddress < 1024; theMemoryAddress++) {
   WireEepromWriteInt(theDeviceAddress, theMemoryAddress * 2, (int)theMemoryAddress);
   }
   for (unsigned int theMemoryAddress = 0; theMemoryAddress < 1024; theMemoryAddress++) {
   Serial.print("Int: ");
   Serial.print(theMemoryAddress);
   Serial.print(", ");
   Serial.print(WireEepromReadInt(theDeviceAddress, theMemoryAddress * 2));
   Serial.println(".");
   }
}

void WireEepromRead(int theDeviceAddress, unsigned int theMemoryAddress, int theByteCount, byte* theByteArray) {
  for (int theByteIndex = 0; theByteIndex < theByteCount; theByteIndex++) {
    Wire.beginTransmission(theDeviceAddress);
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 8));
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 0));
    Wire.endTransmission();
    delay(5);
    Wire.requestFrom(theDeviceAddress, sizeof(byte));
    theByteArray[theByteIndex] = Wire.receive();
  }
}

byte WireEepromReadByte(int theDeviceAddress, unsigned int theMemoryAddress) {
  byte theByteArray[sizeof(byte)];
  WireEepromRead(theDeviceAddress, theMemoryAddress, sizeof(byte), theByteArray);
  return (byte)(((theByteArray[0] << 0)));
}

int WireEepromReadInt(int theDeviceAddress, unsigned int theMemoryAddress) {
  byte theByteArray[sizeof(int)];
  WireEepromRead(theDeviceAddress, theMemoryAddress, sizeof(int), theByteArray);
  return (int)(((theByteArray[0] << 8)) | (int)((theByteArray[1] << 0)));
}

void WireEepromWrite(int theDeviceAddress, unsigned int theMemoryAddress, int theByteCount, byte* theByteArray) {
  for (int theByteIndex = 0; theByteIndex < theByteCount; theByteIndex++) {
    Wire.beginTransmission(theDeviceAddress);
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 8));
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 0));
    Wire.send(theByteArray[theByteIndex]);
    Wire.endTransmission();
    delay(5);
  }
}

void WireEepromWriteByte(int theDeviceAddress, unsigned int theMemoryAddress, byte theByte) {
  byte theByteArray[sizeof(byte)] = {(byte)(theByte >> 0)};
  WireEepromWrite(theDeviceAddress, theMemoryAddress, sizeof(byte), theByteArray);
}

void WireEepromWriteInt(int theDeviceAddress, unsigned int theMemoryAddress, int theInt) {
  byte theByteArray[sizeof(int)] = {(byte)(theInt >> 8), (byte)(theInt >> 0)};
  WireEepromWrite(theDeviceAddress, theMemoryAddress, sizeof(int), theByteArray);
}

Modifico para que se vea el código bien.

Un saludo, me alegro que se solucione.

Mil gracias! le he introducido el delay y ahora va perfecto, actualizo el código.