EEPROM (esterne) non vanno...

ecco il codice

#include <Wire.h> 

#define EERPOM_1_ADDRESS 80
#define EERPOM_2_ADDRESS 87

void connectPage(int address, int page){
  Wire.beginTransmission(address);
  Wire.send((int)((page) >> 8));
  Wire.send((int)((page) & 0xFF));
}

void request(int address, int nData){
  Wire.endTransmission();
  Wire.requestFrom(address, nData);  
}

void sendRandomData(){
  int j = 0;
  Wire.endTransmission();
  for(int i = 0; i < 10; i++){
    Wire.send((byte) (j = (byte) random()));
    Serial.println(j);
  }
  Serial.println("fine invio dati");
}

void setup(){
  Serial.begin(9600);
  
  Wire.begin(EERPOM_1_ADDRESS);  
  connectPage(EERPOM_1_ADDRESS, 150);
  sendRandomData();
  connectPage(EERPOM_1_ADDRESS, 150);
  request(EERPOM_1_ADDRESS, 10);
  while(Wire.available())
    Serial.println((int) Wire.receive());
  
  Serial.println("Turno 2");
    
  Wire.begin(EERPOM_2_ADDRESS);
  connectPage(EERPOM_2_ADDRESS, 200);
  sendRandomData();
  connectPage(EERPOM_2_ADDRESS, 200);
  request(EERPOM_2_ADDRESS, 10);
  while(Wire.available())
    Serial.println((int) Wire.receive());
}

void loop(){
}

ed ecco i risultati

167
241
217
42
130
200
216
254
67
77
fine invio dati
255
255
255
255
255
255
255
255
255
255
Turno 2
152
85
140
226
179
71
23
17
152
84
fine invio dati
255
255
255
255
255
255
255
255
255
255

come si vede non "recupero" quello che salvo...
però non succede che si blocca la Wire.endTransmission(), cosa che succedeva tempo fa...

Pubblica anche il circuito perché altrimenti non capiamo come hai collegato il tutto.
Inoltre, che Eeprom usi?

premetto che io non ho fatto ne il circuito, ne lo ho stampato, ne ho fatto saldature...

allora... il circuito è questo (che comprende anche il chip RTC (alla dx del cerchio, che in realtà è l'alloggiamento della batteria), e quindi c'è da vedere i due chip sopra)

il modello di EEPROM (entrambi) dovrebbe essere questo
24LC512

Mi sono espresso male, per "circuito" intendevo lo schema del circuito, non il PCB, scusami... :sweat_smile:

PS:
il codice 255 significa 11111111b, ossia tutti bit ad 1, che, nelle Eeprom, significa non programmati. Per cui l'operazione di salvataggio non va a buon fine.

Ti do un link da controllare:
http://arduino.cc/playground/Code/I2CEEPROM24LC512
Trovi delle chiamata di lettura/scrittura che funzionano.
In linea di massima una lettura è:
Wire.beginTransmission(CHIPEEPROM);
Wire.send((byte)(highByte(INDIRIZZO));
Wire.send((byte)(lowByte(INDIRIZZO));
Wire.endTransmission();

Per scrivere si usa:
Wire.beginTransmission(CHIPEEPROM);
Wire.send((byte)(lowByte(INDIRIZZO));
Wire.send((byte)(highByte(INDIRIZZO));
Wire.send(BYTEDATO);
Wire.endTransmission();
delay(5);

(PS: se non mi ricordo male...)

quindi se un eeprom è vuota non ci trovo 0 ma 255? (lo so che dovrei verificare io... però ]:D)

è una pesata inviare dati uno alla volta... sarebbe stato più comodo inviare tanti dati consecutivamente, una volta connesso all'indirizzo... però non ci si può fare molto... e quindi ci si mette l'anima in pace...

però vorrei sapere come mai, copiando il codice sul link che hai postato, la prima volta che apro il serial monitor, dopo l'upload dello sketch compare all'inizio questo testo

cmq ora modifico il mio codice originario

Scrivere su un EEPROM é una cosa lenta.

Devi spedire un Byte alla volta e memorizzarle chiudendo con Wire.endTransmission();

Oppure c'é la possibilitá di scrivere una pagina (nel caso di questi EEPROM 128 Byte). Per farlo basta aprire la trasmissione, mandare l' indirizzo di partenza e poi spedire 128 dati. Esempio di Leo:

Wire.beginTransmission(CHIPEEPROM);
Wire.send((byte)(lowByte(INDIRIZZO));
Wire.send((byte)(highByte(INDIRIZZO));
for (int i=0;i>128; i++)
{
Wire.send(BYTEDATO);
}
Wire.endTransmission();
delay(5);

Ciao Uwe

Forse quei byte casuali dipendono da problemi di sincronizzazioni. Magari tu hai il serial monitor impostato a 57600 (che è la velocità di default) e lo metti a 9600 dopo che la trasmissione dei dati è iniziata.
Inoltre confermo quanto detto da Uwe: la scrittura su una EEPROM è lenta. Un chip 24LC512 che ho io specifica sul datasheet di impiegare 3,3ms per la scrittura di 1 byte. Ecco spiegato il delay(5) dopo l'operazione di scrittura, per esser certo che il valore venga effettivamente salvato prima di spedire il successivo.

Inoltre la trasmissione può anche avvenire per gruppi di byte, io ti ho messo un codice molto semplice.

PS:
fidati che una EEPROM inizializzata contiene tutti i bit impostati ad 1 e non a 0. Non figurarti nella tua mente l'equazione "erase" = cancellazione = impostare a 0. Anche l'EEPROM interna al micro se piallata, contiene 255 in ogni byte (ossia 11111111b).

ok... ecco il codice che invia i dati (uno alla volta) ma ne riceve a blocchi... che da quanto ho capito un blocco di ricezione è limitato a 32 byte (dato che SIZE_2 == 100, ma il loop viene eseguito 32 volte)

#include <Wire.h> 

#define EERPOM_1_ADDRESS 80
#define EERPOM_2_ADDRESS 87

#define SIZE_1 10
#define SIZE_2 100  

#define PAGE_1 100
#define PAGE_2 0

void connectPage(int address, int page){
  Wire.beginTransmission(address);
  Wire.send((byte)((page) >> 8));
  Wire.send((byte)((page) & 0xFF));
}

void requestData(int address, int page, int nData){
  connectPage(address, page);
  Wire.endTransmission();
  Wire.requestFrom(address, sizeof(byte) * nData);  
}

void sendData(int address, int page, byte data){
  connectPage(address, page);
  Wire.send(data);
  Wire.endTransmission();
  delay(5);
}

void sendRandomData(int address, int page, int size){
  int j = 0;
  for(int i = 0; i < size; i++){
    sendData(address, page + i, (j = (byte) random()));
    Serial.print(j);
    Serial.print(", ");
  }
  Serial.println();
}

void setup(){
  Serial.begin(9600);
  
  Wire.begin(EERPOM_1_ADDRESS);  
  sendRandomData(EERPOM_1_ADDRESS, PAGE_1, SIZE_1);
  requestData(EERPOM_1_ADDRESS, PAGE_1, SIZE_1);
  while(Wire.available()){
    Serial.print((int) Wire.receive());
    Serial.print(", ");
  }
  
  Serial.println();
  Serial.println("Turno EEPROM2");
    
  Wire.begin(EERPOM_2_ADDRESS);  
  sendRandomData(EERPOM_2_ADDRESS, PAGE_2, SIZE_2);
  requestData(EERPOM_2_ADDRESS, PAGE_2, SIZE_2);
  while(Wire.available()){
    Serial.print((int) Wire.receive());
    Serial.print(", ");
  }
}

void loop(){
}

edit:
aggiungo la stampa di prova

167, 241, 217, 42, 130, 200, 216, 254, 67, 77, 
167, 241, 217, 42, 130, 200, 216, 254, 67, 77, 
Turno EEPROM2
152, 85, 140, 226, 179, 71, 23, 17, 152, 84, 47, 17, 45, 5, 88, 245, 107, 214, 136, 7, 153, 146, 72, 51, 98, 65, 243, 13, 35, 229, 95, 48, 209, 200, 237, 97, 12, 75, 2, 53, 57, 129, 132, 184, 20, 162, 156, 180, 90, 103, 42, 202, 229, 72, 233, 197, 241, 176, 196, 21, 138, 229, 155, 77, 57, 246, 247, 232, 161, 5, 211, 254, 237, 165, 213, 243, 217, 228, 91, 250, 108, 195, 81, 226, 32, 174, 12, 225, 6, 152, 109, 97, 255, 52, 161, 30, 25, 253, 54, 80, 
152, 85, 140, 226, 179, 71, 23, 17, 152, 84, 47, 17, 45, 5, 88, 245, 107, 214, 136, 7, 153, 146, 72, 51, 98, 65, 243, 13, 35, 229, 95, 48,

ok... quindi c'è una spiegazione logica anche a quelle stampe misteriose, che ogni tanto compaiono...
cmq ho risolto il "mistero" EEPROM... peccato che tutto il resto del progetto non funziona assolutamente XD

buono a sapersi che un eeprom vuota contiene 255 e non 0!

nell'ultimo messaggio ho postato un codice che funziona;
lo ho leggermente modificato (o per meglio dire ho modificato una cosa che avevo fatto precedentemente) e ovviamente non funziona...
(ovviamente se carico il codice postato sopra funziona, e gli indirizzi sono gli stessi)

si blocca a Wire.endTransmission();

C:\Documents and Settings\User\Desktop\arduino-0019\libraries\Sockets\Sockets.cpp: 131
C:\Documents and Settings\User\Desktop\arduino-0019\libraries\Sockets\Sockets.cpp: 136
#define EEPROM_ADDRESS 80
void Sockets::eepromConnectPage(int page){
	Wire.beginTransmission((int) EEPROM_ADDRESS);
	Wire.send((byte)((page) >> 8));
	Wire.send((byte)((page) & 0xFF));
}

byte Sockets::eepromReadData(int page){
Serial.print(__FILE__);
Serial.print(": ");
Serial.print(__LINE__); //riga 131
Serial.println();
	eepromConnectPage(page);
Serial.print(__FILE__);
Serial.print(": ");
Serial.print(__LINE__); //riga 136
Serial.println();
	Wire.endTransmission();
Serial.print(__FILE__);
Serial.print(": ");
Serial.print(__LINE__); //riga 141 e qui non stampa...
Serial.println();
	Wire.requestFrom((int) EEPROM_ADDRESS, sizeof(byte));
Serial.print(__FILE__);
Serial.print(": ");
Serial.print(__LINE__);
Serial.println();
	return Wire.receive();
}

La scrittura é limitata a blocchi di 128 Byte consecutivi, ma la lettura non dovrebbe essere limitata.
È limitato lo spazio RAM per memorizzare i dati provenienti dal EEPROM percui non si possono scaricare troppi alla volta (che non vale se si stampa subito il dato sulla seriale).
Ciao Uwe

il fatto è che non arrivo a "scaricare dati dall'eeprom" in quanto si ferma all'endTransmission.... quindi prima di fare requestFrom...

Ma forse hai modificato anche le funzioni che non si vedono?

non si vedono nel senso che non ho postato il codice?

beh... si puo' dire ni... quello che non va si trova in una libreria abbastanza grossa... e ho postato solo la parte "critica"...

anche perche' questa libreria crea da sola un oggetto di se stessa, che blocca subito tutto, quindi non viene invocata nessuna funzione prima...

postare tutta la libreria non e' comodissimo perche' e' circa sulle 1400 righe...

Ho provato a modificare tutte le altre funzioni della libreria (in modo che la prima (ed unica) riga fosse return false o similari)...

e ovviamente continua a bloccarsi alla endTransmission.... eppure l'altro codice continua ad andare anche con questa modifica... (che chiede tutti i dati dell'eeprom...)

  for(int i = 0, j = 0; i < 65534; i += 30){
    requestData(EERPOM_1_ADDRESS, i, 30);
    while(Wire.available()){
      Serial.print(j++);
      Serial.print(": ");     
      Serial.print((int) Wire.receive());
      Serial.print(", ");
    }
    Serial.println();
  }

edit:
l'unica cosa che mi viene in mente è che la libreria è in c++ e non vorrei che il compilatore trattasse int in modo diverso da come lo tratti per arduino... (visto che in c++ il new c'è ma in arduino no...)
però mi sembra una gran cavolata... io comunque provo a modificare...

ovviamente ho fallito nella modifica... il compilatore non accettava un uint16_t...
non so proprio dove mettere le mani...

Non capisco una cosa. Ma perché non vuoi/puoi usare quel codice che ti funziona? Se devi passare più byte, basta tu metta un semplice ciclo for e scrivere byte per byte.

Quel codice che funziona è nello sketch di una prova.
Io sto realizzando un'altro progetto che fa uso di diverse librerie, tra cui "Sockets" che utilizza appunto le funzioni postate precedentemente.

Mi va bene chiedere/scrivere un dato alla volta (non uso for perché almeno si capisce meglio dove voglio scrivere i dati, dato che hanno indirizzi "precisi"

in sostanza la libreria deve scrivere sulla eeprom, non lo sketch, per questo motivo devo mettere il codice nella libreria...
e mi sembra identico... soprattutto viene invocata solo "connectPage" e endTransmission... e qui si pianta tutto...

idee sul come risolvere?