Nell'esempio viene utilizzato 0x50 come codice DEVICE ma io so che
il codice delle EEPROM I2C è 0xA0.
Li ho utilizzati entrambi sempre con lo stesso risultato.
Le 2 routine ricavate dall'indirizzo di cui sopra e che ho utlizzato sono queste:
#include <Wire.h> //I2C library
//---Scrive un byte su EEprom I2C----------------------------------------------
void i2C_Scrive_B(int ind_dev, unsigned int ind, byte data ) {
int rdata = data;
Wire.beginTransmission(ind_dev);
Wire.send((int)(ind >> 8)); // MSB
Wire.send((int)(ind & 0xFF)); // LSB
Wire.send(rdata);
Wire.endTransmission();
}
//---Legge un byte da EEprom I2C-----------------------------------------------
byte i2C_Legge_B( int ind_dev, unsigned int ind ) {
byte rdata = 0xFF;
Wire.beginTransmission(ind_dev);
Wire.send((int)(ind >> 8)); // MSB
Wire.send((int)(ind & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(ind_dev,1);
if (Wire.available()) rdata = Wire.receive();
return rdata;
}
E per lettura e scrittura ho utilizzato questo codice:
int ind_dev=0xA0;
unsigned int ind=3;
byte data=12;
byte dato;
//-------------------------------------------------------------
//---Predisposizione-------------------------------------------
void setup() {
Serial.begin(9600); //Velocità porta seriale.
i2C_Scrive_B(ind_dev,ind,data);
}
//---Ciclo principale------------------------------------------
void loop() {
dato=i2C_Legge_B(ind_dev,ind);
Serial.println(dato,DEC);
delay(3000);
}
Grazie Leo72 per l'interessamento, allego lo schema, è un classico che tra l'altro
ho già utilizzato altre volte con i PIC, con Arduino (ATMEL) sono nuovo.
Ho una scheda mega 2560 R2.
Sto provando un pò di cose, proverò poi anche la tua libreria swRTC.
Lo schemino è giusto, l'indirizzo base è 0x50, come segnato sul datasheet.
L'unica cosa sono le R di pull-up: per il bus I2C servono tra 1K5 e 2K2, non più alte, altrimenti abbassi troppo la corrente.
Con il sketch che trovi a I2CScanner: Arduino as I2C bus scanner – todbot blog puoi scannerizzare il bus I2C e ottieni gli indirizzi dei dispositivi collegati.
se cambi la riga
byte end_address = 100;
in
byte end_address = 128;
scanna tutti gli indirizzi possibili.
leo72 - Ho sostituito le resistenze di pull-up, le ho messe da 1k8 e non è cambiato niente.
Ho provato a vedere i segnali con oscilloscopio ma niente.
uwefed - Ho provato a caricare quel file (I2CScanner.pde) che mi hai suggerito.
Mi restituisce una tabella con i 128 indirizzi, ne ha trovato 1, il numero 80.
A questo punto ho inserito il numero 80 come "control byte" anzichè il numero 0XA0,
ma il risultato è sempre lo stesso. Non è cambiato niente.
E' poi il numero da utilizzare come "control byte" della EEprom?
Ma 8010=A016
Quindi l'indirizzo è giusto che sia A016, ma anch'io te l'avevo detto dato che da datasheet, l'indirizzo è composto dalla parte fissa 10102 a cui si somma la parte variabile composta dallo stato dei pin A0-A2, nel tuo caso mettendoli a massa tutti hai 0002 per cui 10102-0002=10100002 da cui si ottiene 8010/0xA016
Ho provato con una EEprom 24C32 e poi con una 24C65
ma il risultatto è sempre lo stesso.
Scrivo il n° 12 e leggo 255 cioè vuoto.
Sono nuovo di Arduino e quindi non ho dimestichezza con i principi, funzioni ecc.
Anche se programmo microcontrollori PIC da un decennio e scrivere e leggere
le EEprom non era un problema.
Qualcuno ha mai utilizzato queste routine?
Magari non sono funzionanti.
Qui di seguito tutto il codice con le librerie che ho copiato dal sito.
Grazie per ulteriori consigli.
#include <Wire.h> //I2C library
//-------------------------------------------------------------
int ind_dev=0XA0;
unsigned int ind=3;
byte invia=12;
byte riceve;
//---Predisposizione-------------------------------------------
void setup() {
Wire.begin(); //Inizializza il bus I2C.
Serial.begin(9600); //Velocità porta seriale.
i2c_eeprom_write_byte(ind_dev,ind,invia);
delay(200);
Serial.print("Scrittura n° : ");
Serial.println(invia,DEC);
}
//---Ciclo principale------------------------------------------
void loop() {
riceve=i2c_eeprom_read_byte(ind_dev,ind);
delay(200);
Serial.print("Lettura n° : ");
Serial.println(riceve,DEC);
delay(3000);
}
//-----------------------------------------------------------------------------
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();
}
//-----------------------------------------------------------------------------
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;
}
//-----------------------------------------------------------------------------
// 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
);
Wire.endTransmission();
}
//-----------------------------------------------------------------------------
// 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();
}
I pin SDA e SCL sono fissi perché mappati in HW per cui non puoi cambiarli.
Io ho la UNO ma non credo c'entri molto.
Prova questo sketch:
/*
Example 21.2 Reading and writing data to Microchip 24LC256 EEPROMS over I2C
tronixstuff.com/tutorials > Chapter 21 CC by-sa v3.0
*/
#include "Wire.h" // for I2C
#define chip1 0x50 // device address for left-hand chip on our breadboard
#define chip2 0x51 // and the right
// always have your values in variables
unsigned int pointer = 69; // we need this to be unsigned, as you may have an address > 32767
byte d=0; // example variable to handle data going in and out of EERPROMS
void setup() {
delay(5000);
Serial.begin(9600); // for screen output
Wire.begin(); // wake up, I2C!
}
void writeData(int device, unsigned int add, byte data) {
// writes a byte of data 'data' to the chip at I2C address 'device', in memory location 'add'
Wire.beginTransmission(device);
Wire.send((int)(add >> 8)); // left-part of pointer address
Wire.send((int)(add & 0xFF)); // and the right
Wire.send(data);
Wire.endTransmission();
delay(10);
}
byte readData(int device, unsigned int add) {
// reads a byte of data from memory location 'add' in chip at I2C address 'device'
byte result; // returned value
Wire.beginTransmission(device); // these three lines set the pointer position in the EEPROM
Wire.send((int)(add >> 8)); // left-part of pointer address
Wire.send((int)(add & 0xFF)); // and the right
Wire.endTransmission();
Wire.requestFrom(device,1); // now get the byte of data...
result = Wire.receive(); return result; // and return it as a result of the function readData
}
void loop() {
Serial.println("Writing data...");
for (int a=0; a<20; a++) {
writeData(chip1,a,a);
writeData(chip2,a,a); // looks like a tiny EEPROM RAID solution!
}
Serial.println("Reading data...");
for (int a=0; a<20; a++) {
Serial.print("chip1 pointer ");
Serial.print(a);
Serial.print(" holds ");
d=readData(chip1,a);
Serial.println(d, DEC);
}
for (int a=0; a<20; a++) {
Serial.print("chip2 pointer ");
Serial.print(a);
Serial.print(" holds ");
d=readData(chip2,a);
Serial.println(d, DEC);
}
delay(500);
}
E' per 2 chip EEPROM, togli il codice che legge/scrive sul secondo e provalo.
leo72:
L'indirizzo di una EEPROM è composto da una parte fissa, riportata sul datasheet, poi c'è anche la parte assegnata dall'utente tramite alcuni pin.
leo72:
Ma 8010=A016
Quindi l'indirizzo è giusto che sia A016, ma anch'io te l'avevo detto dato che da datasheet, l'indirizzo è composto dalla parte fissa 10102 a cui si somma la parte variabile composta dallo stato dei pin A0-A2, nel tuo caso mettendoli a massa tutti hai 0002 per cui 10102-0002=10100002 da cui si ottiene 8010/0xA016