scrittura eeprom (non capisco)

Ciao,
sto tentando di utilizzare una eeprom esterna 24C64, utilizzo la libreria dell'esempio (wire); la cosa funziona, ovvero scrivo e leggo un valore in una cella della eprom, ma non capisco come viene utilizzata la variabile eeaddress e eeaddresspage, e nemmeno queste righe:

Wire.write((int)(eeaddresspage >> 8)); // MSB
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.requestFrom(deviceaddress, 1);

Quà sotto il codice completo:

#include <Wire.h>               // libreria I2C

byte dato = 129;                // valore da scrivere su eeprom
byte datric = 255;              // variabile per dato letto da eprom
int deviceaddress = 0x50;       // indirizzo eeprom
unsigned int eeaddresspage = 0; // pagina della eeprom?
unsigned int eeaddress = 0;     // cella che voglio leggere?

void setup() {

  Serial.begin(38400);          // imposto velocità seriale

  Wire.begin();                 // inizializza la connessione
  delay(500);

  scrivi();                     // chiamo la funzione per scrivere
  delay(10);
  
  Serial.println("Memora scritta");
  delay(500);
  
  leggi();                      // chiamo la funzione per leggere
  Serial.println (datric);      // scrivo nella seriale il dato letto
}

void loop()
{
}

void scrivi()
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddresspage >> 8)); // MSB
  Wire.write((int)(eeaddresspage & 0xFF)); // LSB
  Wire.write(dato);
  Serial.println("scrittura");
  Serial.println(Wire.endTransmission());
  Wire.endTransmission();
}

void leggi()
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Serial.println(Wire.endTransmission());
  Wire.endTransmission();

  Wire.requestFrom(deviceaddress, 1);
  if (Wire.available())
    datric = Wire.read();
  return datric;
}

Se qualcuno avesse voglia di darmi delucidazioni, lo ringrazio :slight_smile:

Se la EEPROM è più grande di 256 byte, per poter esprimere tutti gli indirizzi possibili servono più di un byte.

Ma sul bus i2c viaggia un byte alla volta, per cui bisogna separare l'indirizzo nei byte che lo compongono. Quelle righe servono a questo, e sono equivalenti a due funzioni caratteristiche di Arduino (che andrebbero usate in questo caso): highByte() e lowbyte().

Ah, scritta in questo modo non l'avevo ancora vista... Quindi l'istruzione Wire.write invia prima il byte alto della posizione dove voglio scrivere, poi invia il byte basso, a seguire il byte da salvare, e se continuo con altri byte vengono salvati a seguire? O devo sempre indirizzare byte per byte?
Grazie

Credo di aver capito, ho modificato così (è un programma solo per test):

#include <Wire.h>               // libreria I2C

byte dato = 0;                  // valore da scrivere su eeprom
byte datric1 = 255;             // variabile per dato letto da eprom
byte datric2 = 255;             // variabile per dato letto da eprom
byte datric3 = 255;             // variabile per dato letto da eprom
byte datric4 = 255;             // variabile per dato letto da eprom
int eepromind = 0x50;           // indirizzo eeprom

void setup() {

  Serial.begin(38400);          // imposto velocità seriale
  Wire.begin();                 // inizializza la connessione con eeprom
  delay(50);                    // stabilizza

  dato = 59;                  // valore da scrivere nella eeprom
  //scrivi(0);                  // chiamo la funzione per scrivere e dico posizione
  dato = 111;
  //scrivi(1);                  // chiamo la funzione per scrivere e dico posizione
  dato = 169;
  //scrivi(2);                  // chiamo la funzione per scrivere e dico posizione
  dato = 222;
  //scrivi(3);                  // chiamo la funzione per scrivere e dico posizione
  
  delay(500);

  leggi(0);                      // chiamo la funzione per leggere e dico dove
  Serial.println (datric1);      // scrivo nella seriale il dato letto
  Serial.println (datric2);      // scrivo nella seriale il dato letto
  Serial.println (datric3);      // scrivo nella seriale il dato letto
  Serial.println (datric4);      // scrivo nella seriale il dato letto
}

void loop()
{
}

void scrivi(unsigned int bytepos)
{
  Wire.beginTransmission(eepromind);      // apro la connessione con la eeprom
  Wire.write(highByte(bytepos));          // invio byte H posiz dove scrivo
  Wire.write(lowByte(bytepos));           // invio byte L posiz dove scrivo
  Wire.write(dato);                       // scrivo il byte nella eeprom
  Serial.print("Rapporto scrittura= ");
  Serial.println(Wire.endTransmission()); // rapporto di trasmissione
  Wire.endTransmission();                 // chiudo la connessione con eeprom
  delay(10);
  Serial.println("Memoria scritta");
}

void leggi(unsigned int bytepos)
{
  Wire.beginTransmission(eepromind);      // apro la connessione con la eeprom
  Wire.write(highByte(bytepos));          // invio byte H posiz dove scrivo
  Wire.write(lowByte(bytepos));           // invio byte L posiz dove scrivo
  Serial.print("Rapporto lettura= ");
  Serial.println(Wire.endTransmission()); // rapporto di trasmissione
  Wire.endTransmission();                 // chiudo la connessione con eeprom

  Wire.requestFrom(eepromind, 4);         // il num dice quanti byte leggere
  if (Wire.available())
    datric1 = Wire.read();                   // salvo dato letto nella variabile
    datric2 = Wire.read();                  // salvo dato letto nella variabile
    datric3 = Wire.read();                  // salvo dato letto nella variabile
    datric4 = Wire.read();                  // salvo dato letto nella variabile
  return;
}

Un'ultima domanda, questa sringa restituisce un valore, dovrebbe essere un rapporto di trasmissione? O di comunicazione con la eeprom?

Serial.println(Wire.endTransmission());

Nella seriale se tutto funziona stampa uno zero, se non comunica un 2, c'è una tabella per sapere cosa significano questi numeri?
Grazie ancora :slight_smile:

in twi.h (sotto utility) trovi:

 * Output   0 .. success
 *          1 .. length to long for buffer
 *          2 .. address send, NACK received
 *          3 .. data send, NACK received
 *          4 .. other twi error (lost bus arbitration, bus error, ..)

Grazie a tutti, molto disponibili :slight_smile: