Tras realizar varias pruebas con diferentes dispositivos, me he encontrado con un problema con el bus I2C, que ya no se por donde agarrar.
A ver si algún gurú de estos temas me puede echar una mano.
En mi proyecto pretendo utilizar un teclado matricial con el expansor i2c PCF8574P, u Una memoria eeprom i2c 24LC515 y un reloj i2c PCF8583P-F4.
El caso es que cuando conecto el reloj, no me funciona bien la lectura de la memoria. Individualmente todo funciona de forma correcta, incluso la memoria al mismo tiempo que el teclado. Es más, cuando está conectado el reloj al bus la memoria escribe correctamente, pero al leer los datos devuelve bytes erróneos. Si desconecto el reloj y vuelvo a leer la memoria, me devuelve los valores que había escrito de forma correcta.
He probado con valores de las resistencias PulUp del bus de 10K y 4,7K pero no parece que el problema sea ese. Aunque probaré con 1K que que he visto en algún esquema.
Para leer y escribir la memoria utilizo estas funciones:
//Las siguientes funciones para lectura y escritura en una EEPROM se encuentran en el wiki de Arduino: http://www.arduino.cc/playground/Code/I2CEEPROM
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.send(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.send((int)(eeaddresspage >> 8)); // MSB
Wire.send((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.send(data[c]);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
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;
}
// 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.send((int)(eeaddress >> 8)); // MSB
Wire.send((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.receive();
}
En este hilo explico la implementación que he hecho del reloj:
RTC PCF8533 i2c con centésimas de segundo
Estos son los esquemas de lo que he implementado: