Estou tentando utilizar um módulo de memória EEPROM modelo "AT24C02 Mini". Sua conexão é bem simples, já que ele é I2C, mas esse modelo não tem jumper para configurar o endereço I2C. Quando rodo o scanner I2C ele mostra vários endereços, como a seguir (só a EEPROM está conectada):
I2C Scanner
Scanning...
I2C device found at address 0x50 !
I2C device found at address 0x51 !
I2C device found at address 0x52 !
I2C device found at address 0x53 !
I2C device found at address 0x54 !
I2C device found at address 0x55 !
I2C device found at address 0x56 !
I2C device found at address 0x57 !
done
Isso já me parece estranho pois acredito que ele deveria ter apenas um endereço. Estou tentando usar um código que rola muito pela internet e que, inclusive, eu vi no canal do WR Kits que é esse:
writeEEPROM(disk1, address, 20);
Serial.print("Eco da EEPROM 24C02 para o endereco 0x00: ");
Serial.print(readEEPROM(disk1, address), DEC);
}
void loop(){}
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // Byte mais significativo
Wire.write((int)(eeaddress & 0xFF)); // Byte menos significativo
Wire.write(data);
Wire.endTransmission();
delay(5);
}
Mas, o resultado do eco é sempre 255, ou seja, a gravação não está funcionando. Já tentei mudar o endereço I2C para os outros que apareceu no scanner, já tentei gravar outros valores, mas sempre retorna 255.
Qual o Arduino? Uno? Como ligaste o módulo ao Arduino? Como alimentaste o módulo?
Pelo datasheet dessa EEPROM o endereço por omissão é 0xA0. Não parece fazer sentido usar o endereço 0x50. Interessante que 0x50 é o valor 0xA0 deslocado 1 bit para a direita.
Geralmente na função setup() não começo logo a escrever ou a ler nos periféricos, apenas faço a inicialização. Leitura/escrita fica no loop(). Ou pelo menos dou um delay entre a inicialização e a leitura/escrita. Não sei se isso tem alguma influência neste caso específico...
Nesse caso foi melhor o setup() pois bastava rodar apenas uma vez. A ligação dele é simples, pois é uma " Breakout Board". Os pinos são VCC, GND, SDA e SCL e são conectados nesses mesmos pinos no Arduino. No meu caso eu estou usando o Arduino Nano. Hoje testei com outro Arduino Nano e com outra Breakout Board, mas o erro continua. Detalhe é que eu testei com o WP (write protect) ligado e desligado. Com relação aos endereços, vi na internet que os endereços normalmente são esses mesmo, mas, logo que eu puder eu vou testar com esse outro endereço que você informou.
Tentei com esse endereço AXA0. Também não funcionou. Estou começando a ficar cansado. Não é possível que eu comprei dois módulos e os dois estão com problema. O datasheet diz que os pinos A0, A1 e A2 determinam o endereço no barramento I2C e, dependendo de como ligar esses tres pinos (entre Vcc e GND) configuramos o endereço entre 0x50 e 0x57. O problema é que, idependende de como eu ligue esse pinos, o scanner continua mostrando todos os endereços.
OK, a biblioteca Wire do Arduino usa endereços de 7 bits. Depois dependendo da função pretendida desloca "automaticamente" o endereço para a esquerda colocando "zero" ou "um" no bit menos significativo, dependendo se é uma função de escrita ou leitura.
Portanto 0x50 é o endereço correcto para usar essa EEPROM com a biblioteca Wire.
Para a escrita na memória o terminal WP tem de ficar ligado ao GND.
Se o módulo já vem com as duas resistências pullup para as linhas SDA e SCL e tem os terminais de endereço (A0,A1,A2) ligados ao GND, deveria funcionar correctamente com o i2c_scanner (mostrando apenas o endereço 0x50).
Verifica qual a tensão directamente nos terminais de alimentação da EEPROM.
Poderá também eventualmente ser um problema dos cabos ou conectores, ligações soltas?
Consegui resolver. Era o código que estava errado. Vou colocar os detalhes aqui para quem passar pela mesma dificuldade:
apesar de os pinos A0, A1 e A2 definir, teoricamente, o endereço na EEPROM, o módulo que eu tenho responde a todos os endereços. Acredito que são várias paginas, ou algo assim, por isso o I2C scanner mostra todos os endereços. Testei com todos os endereços (de 0x50 até 0x57) e deu certo com todos, então fiquei com 0x50;
O WP (proteção contra escrita) já estava em GND, ou seja, a escrita está liberada;
O código que funciou é este abaixo:
#include <Wire.h> //bliblioteca do barramento I2C #define disk1 0x50 //endereço da EEPROM no barramento I2C #define address 0 //endereço da célula onde será gravado/lido o byte
byte valor1, valor2;
void setup() {
//gravar um inteiro
valor1 = 20;
Wire.beginTransmission(disk1); //iniciar trasmissão, via I2C, para a EEPROM
Wire.write(address); //endereço onde será gravado o valor 20
Wire.write(valor1); //gravar o valor 20
Wire.endTransmission(); //finalizar transmissão
delay(5);
// ler valor gravado
Wire.beginTransmission(disk1); //iniciar trasmissão, via I2C, para a EEPROM
Wire.write(address); //endereço onde está gravado o valor 20
Wire.endTransmission(false); // end the writing part but don't stop transmission
Wire.requestFrom(disk1, 1); //Apontar para 1 byte no endereço determinado
valor2 = Wire.read(); //Ler o byte
}
void loop() {
}
Notem que esse código só grava/recupera valores que ocupa até um byte (0 a 255). Para mais que isso, o valor deve ser dividido em vários bytes e a gravação/recuperação deve ser feita byte a byte.