eprom esterna su arduino

buona sera a tutti ragazzi.....volevo chiedere un'informazione....
ho montato una 24C64 su Arduino mega proprio perche' mi serve una eprom esterna e miserve inoltre scrivere almeno un numero a 4 cifre.Ho questo codice:

#include "Wire.h"

#define EEPROM_I2C_ADDRESS 0x50

void setup()
{
  Wire.begin();
  Serial.begin(9600);

  int address = 0;
  byte val = 110;

  writeAddress(address, val);
  byte readVal = readAddress(address);

  Serial.print("The returned value is ");
  Serial.println(readVal);

}

void loop()
{

}

void writeAddress(int address, byte val)
{
  Wire.beginTransmission(EEPROM_I2C_ADDRESS);
  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB


  Wire.write(val);
  Wire.endTransmission();

  delay(5);
}

byte readAddress(int address)
{
  byte rData = 0xFF;

  Wire.beginTransmission(EEPROM_I2C_ADDRESS);

  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB
  Wire.endTransmission();


  Wire.requestFrom(EEPROM_I2C_ADDRESS, 1);

  rData =  Wire.read();

  return rData;
}

Ovviamente possiamo scrivere come valore sino a 255....ma ho visto in rete qualche esempio per eprom interna che è possibile scrivere float, long int e altro, come questo:

#include <EEPROM.h>
void writeIntIntoEEPROM(int address, int number)
{ 
  EEPROM.write(address, number >> 8);
  EEPROM.write(address + 1, number & 0xFF);
}
int readIntFromEEPROM(int address)
{
  return (EEPROM.read(address) << 8) + EEPROM.read(address + 1);
}
void setup() {
  Serial.begin(9600);
  writeIntIntoEEPROM(45, 18404);
  int number = readIntFromEEPROM(45);
  Serial.print("Number: ");
  Serial.println(number);
}
void loop() {}

Coiè praticamente all'adress si sposta di 1 e.....ho provato ...ma non ci riesco....se per favore potete darmi una mano....Grazie

Prova a studiare QUESTO vecchio articolo ... ::slight_smile:

E c'è anche QUESTO tutorial di Sparkfun ... che fornisce anche una libreria.

Guglielmo

Grazie Guglielmo....già li avevo visti????
Avevo già provato....non funziona....c'è qualche problema o sono io....
Tra l'altro il primo sketch mi funziona perfettamente per valori <=255.
Il problema è che mi servono almento 4 cifre....quindi da quello che ho capito ci dovrebbe essere una seconda scrittura a fianco i primi 3 caratteri oppure scrivere 4 volte singolarmente byte per byte.
Ma non so come fare.

Gli esempi dovrebbero funzionare ... STUDIALI e capisci quello che fanno ... scrivono sempre dei byte, ma sono le parti componenti di un qualche cosa di più grande.

Altra strada, studia come funziona la "union" del 'C' ... con essa potrai avere la tua variabile lunga N bytes come una serie di N singoli bytes da scrivere e leggere.

Guglielmo

louis83:
Il problema è che mi servono almento 4 cifre....quindi da quello che ho capito ci dovrebbe essere una seconda scrittura a fianco i primi 3 caratteri oppure scrivere 4 volte singolarmente byte per byte.

Se si parla di caratteri temo che prima ci sia un po' di confusione tra valori e rappresentazioni dei valori, o tra valori e stringhe. Il valore 255 sono tre cifre/caratteri, ma sta in un byte. Quindi devi gestire valori o caratteri?????

Claudio_FF:
Se si parla di caratteri ...

... ah, beh, se addirittura parliamo di "caratteri" la cosa si semplifica ancora di più dato che ciascuno di essi sta in un byte e quindi ... gli basterebbe salvare il singolo carattere.

No, lui sembra debba scrivere interi e poi dovrà scrivere float (parla di 4 bytes) ... ma non lo fa nel modo corretto ... ::slight_smile:

Guglielmo

Scusate ragazzi ma credo che stiate facendo confusione.....senza che occorre byte...float...caratteri
A.me serve scrivere tipo 250 854 356....numeri a tre cifre e poi anche 4 cifre.......se guardate nel mio primo post ho pubblicato il codice perfettamemte funzionante....ma aimé funziona solo sino a 255........
Vorrei un aiuto su come fare per scrivere INT.

Ti ho già risposto al post #3 ...

Guglielmo

... comunque, su Arduino, un 'int' è composto di DUE bytes, quindi, allo stesso modo come separi la parte bassa ed alta dell'indirizzo della EEPROM (l'indirizzo è un 'int') così separi le due parti della tua variabile intera e le memorizzi in due celle consecutive.

Ma ripeto, se avessi STUDIATO (verbo che mi sembra, anche da thread precedenti, ti sia ostico) gli esempi che ti ho indicato, avevi la soluzione già fatta. Non solo, Sparkfun offre anche una libreria che legge e scrive variabili di qualsiasi lunghezza, basta passargli la variabile e quanto è lunga e ci pensa la libreria a fare il tutto ... ::slight_smile:

Guglielmo

Gentile gbp01 per essere qui e disturbarvi......vuol dire che magari é da ieri che ciprovo con scarsi risultati....quindi mi sono permesso a scrivere il mio problema per avere un aiuto e non rimproveri.....
Quindi vi chiedo gentilmente una mano o un esempio come fare per risolvere il problema......Grazie

louis83:
Gentile gbp01 per essere qui e disturbarvi......vuol dire che magari é da ieri che ciprovo con scarsi risultati....

... chi ha parlato di disturbo? :o :o :o Assolutamnete nessun disturbo, ci mancherebbe !

Io ho solo detto che, purtroppo, tu chiedi sempre la "pappa fatta", ma, come già ti è stato detto in un altro thread e come spiegato nel REGOLAMENTO, al punto 16.1 e 16.13, noi qui NON la forniamo perché vogliamo che l'utente si impegni, capisca, impari e quindi risolva da solo sia il problema attuale che ha, sia i problemi futuri :slight_smile:

Ora, ti sono stati dati vari link di programmi, tutorial, esempi e librerie già fatte con esempi funzionanti ... hai provato a studiarli e vedere cosa fanno e non solo a lanciarli e dire che non funzionano?

Tra gli esempi della libreria di Sparkfun ce ne è proprio uno che scrive e legge un 'int' (2 bytes) ed un 'float' (4 bytes), si chiama "Example1_BasicReadWrite.ino" ... lo hai visto? lo hai provato? non credo ... ::slight_smile:

Ti sono statio forniti TUTTI gli strumenti per risolvere e ci sono anche gli esempi fatti ... ripeto, basta fermarsi un attimo a guardarli, leggere il codice, provarlo e vedere che funziona, dopo di che ...
... applicare la stessa cosa alle proprie esigenze. :wink:

Guglielmo

Scusate ragazzi ma credo che stiate facendo confusione.....senza che occorre byte...float...caratteri
A.me serve scrivere tipo 250 854 356....numeri a tre cifre e poi anche 4 cifre.......se guardate nel mio primo post ho pubblicato il codice perfettamemte funzionante....ma aimé funziona solo sino a 255........
Vorrei un aiuto su come fare per scrivere INT.

A me sembra che il problema sia alla radice, ma a questo punto ho bisogno di una conferma dall'utente. Hai difficoltà con la codifica ASCII?

Hai difficoltà con i tipi di dato predefiniti (cioè byte, int, unsigned long, long, float ecc.)?

Se si è necessario colmare queste lacune, diversamente ciò che scrivo ti sembrerà aramaico antico. :slight_smile:

La teoria ci insegna che il tipo di dato byte è grande 8-bit, accendendoli tutti (i bit) si può al massimo codificare in binario un numero decimale il cui valore è appunto 255. Quindi con 8-bit ci sono 256 valori differenti se ci aggiungiamo lo zero. Ora immagina la memoria (non importa se ram, eeprom interna o esterna) come una pagina di un quaderno a quadretti, bene ogni quadretto è una locazione di memoria è grande appunto 8-bit (1 byte). Allora se la variabile vive in memoria ram e la possiamo immaginare come la pagina a sinistra e la eeprom quella a destra aprendo il quaderno, possiamo immaginare di copiare il contenuto quadretto per quadretto.

Il tipo di dato a 16-bit ci permette di codificare in binario (accendendo tutti i bit) un numero decimale del valore di 65535. Attenzione che si tratta sempre di byte, due in questo caso e quanto detto vale per valori interi senza segno, quando c'è il segno si deve sacrificare un bit, ad esempio il byte con segno (tipo int8_t) mi permette di codificare un valore negativo -128 o un valore positivo 127, vedi qui

Questo per quel riguarda i numeri, mentre per i caratteri si usano sempre i numeri ma si fa riferimento ad una tabella di equivalenza da numero e simbolo, ad esempio a 65 (decimale) corrisponde il carattere 'A'.

PS: la union è la soluzione pulita per accedere ai singoli byte di una porzione di memoria composta da più byte. La versione sporca consiste nel cast di puntatori.

union MyUnion {
   bytePerbyte[4] ;
   float f;
};

// dichiarazione
MyUnion myUnion;

// accesso sia in scrittura che lettura
// myUnion.f con questo accedo alla variabile f

// accesso byte per byte alla variabile f tramite l'array bytePerByte
myUnion.bytePerByte[0] // primo byte della variabile f
myUnion.bytePerByte[1] // secondo byte della variabile f
myUnion.bytePerByte[2] // terzo byte della variabile f
myUnion.bytePerByte[3] // quarto byte della variabile f

Ovviamente in scrittura vale il codice

myUnion.f = 165.25;

Se vuoi accendere (quasi) tutti i bit dei 4 byte, puoi scrivere:

myUnion.bytePerByte[0] = 255;
myUnion.bytePerByte[1] = 255;
myUnion.bytePerByte[2] = 255;
myUnion.bytePerByte[3] = 250;

Se stampi il valore di myUnion.f sarà -6.64614 e rotti, se anche l'ultimo è 255 dovrebbe stampare 'nan', vedi

PS: Circa la pappa fatta aggiungo che se avevo sottomano del codice che faceva quello che chiedevi lo postavo poiché il copia ed incolla non mi costa nulla e sicuramente mi costava meno di quello che ho scritto prima.

Ciao.

>Maurotec: ... guarda che con la libreria già pronta di Sparkfun NON occorre fare null'altro che chiamare una funzione passandogli l'indirizzo di dove salvarla e la variabile da salvare (indipendentemente dalla lunghezza), senza tante altre inutili complicazioni, quindi ... ::slight_smile:

Dalla descrizione della libreria:

A simple to use I2C library for talking to any EEPROM. It uses the same template system found in the Arduino EEPROM library so you can use the same get() and put() functions.

Various external EEPROMs have various interface specs (overall size, page size, write times, etc). This library works with all types and allows the various settings to be set at runtime. All read and write restrictions associated with pages are taken care of. You can access the external memory as if it was contiguous.

... e si installa direttamente dal "library manager" del IDE ... :smiling_imp:

Guglielmo

Ancora più semplice ...
... ho trovato una libreria fatta apposta per le AT24Cxx, la allego a questo post.

L'unica cosa da fare è modificare (come ho fatto io per la mia EEPROM) la riga 40 del file AT24CX.h per mettere il giusto indirizzo I2C della EEPROM. L'esempio di base fa vedere come leggere e scrivere byte, interi, array, ecc.

Provala, guarda bene l'esempio di demo, vedi come effettua le varie cose e prova ad utilizzarla.

Più di così ... ::slight_smile:

Guglielmo

PS:... se non sei sicuro dell'indirizzo I2C, usa il i2cscanner per verificarlo

AT24Cx.zip (8.18 KB)

Provala, guarda bene l'esempio di demo, vedi come effettua le varie cose e prova ad utilizzarla.

Occhio che sono io che l'ho scaricata per dargli una occhiata brevemente.

Per il poco tempo (secondi) che ho dedicato alle due librerie, preferisco quella di sparkfun.
Quella di sparkfun usa i template (put e get), stessa cosa per la libreria standard di arduino.

Ciao.

Maurotec:
Per il poco tempo (secondi) che ho dedicato alle due librerie, preferisco quella di sparkfun.

... si, anche io, ma, essendo "generica" richiede un po' più di configurazione per la specifica EEPROM con cui la si usa, il che ... implica la lettura del datasheet :wink:

Guglielmo

Problema risolto....ringrazio tutti i ragazzi del forum che mi hanno aiutato....in modo particolare a Guglielmo che mi ha consigliato la libreria sparkfun..... Example1_BasicReadWrite.ino.
Riesco a scrivere perfettamente qualsiasi valore sula mia 24c64 e a leggerla con una altro Arduino.

Grazie veramente.

Bene, sono contento che alla fine sei riuscito a risolvere :slight_smile:

Guglielmo