[i2c] Comunicare con EEPROM 24LCXX con libreria EEPROM24

Salve ragazzi,

premetto che uso da appena 1 settimana Arduino e di programmazione sono una capra. Sono pratico di elettronica ma mai usato questo tipo di board. Giusto per iniziare a capire come funziona mi sono scontrato con la lettura e scrittura di eeprom di cui avevo un progetto in pending con il 16f84. Visto che con il PIC non ci ero mai riuscito mi sono messo alla ricerca di qualche libreria di arduino che mi permettesse di leggere e scrivere eeprom della famiglia 24LCXX. Ho letto tantissimo, ho visto tanti metodi, con librerire i2c esterne, con la libreria wire e così via, ma quando sono andato a fare dei test ho sempre avuto problemi.

L’unica con cui ho avuto successo (grazie anche alla supervisione di un amico che mi ha indirizzato sulla giusta strada) è stata la librerira EEPROM24 di cui però non c’è assolutamente documentazione ne esempi. Vi linko la pagina di riferimento: http://rweather.github.io/arduinolibs/classEEPROM24.html#details

Per me che non ho mai messo mano ad arduino e che non ci capisco tantissimo di programmazione è stato un pò complicato iniziare a capire come usare tale libreria, ma sono riuscito nel mio intento. Questa mio post non vuole essere presuntuoso ne vuole insegnare nulla a voi che siete sicuramente molto più esperti di me. Semplicemente esporre come ho implementato tale libreria e alcune righe di codice sull’uso della stessa. Ripeto, uso da 1 settimana arduino, di programmazione non ci capisco quasi nulla, scrivo esattamente ciò che mi avrebbe fatto comodo trovare in rete quando ho iniziato a cercare informazioni, quindi se c’è qualcosa di sbagliato sarei molto felice di essere corretto.

Partiamo (ho usato una board compatibile simile all’Arduino Nano):

il collegamento della memoria è avvenuto così come da schema sulla pagina della libreria:

Dopodichè ho implementato le librerire, inizializzato il collegamento con arduino, letto e successivamente scritto dei dati in eeprom (io avevo disponibile una 24c02).

Le librerire le ho implementate in questo modo:

#include <EEPROM24.h>
#include <I2CMaster.h>
#include <SoftI2C.h>

Immediatamente dopo ho “configurato” i PIN di Arduino e configurato il tipo di eeprom secondo la tabella che si trova nella pagina della libreria:

SoftI2C i2c(SDA, SCL);
EEPROM24 eeprom(i2c, EEPROM_24LC02,0x50);

Fatto ciò ho dichiarato qualche variabile che ho usato nel programma ed inserito nel loop le mie operazioni:

Controllo se è collegata la memoria al mio arduino:

presente = eeprom.available();

questo restituisce “1” se la memoria è presente, “0” se la memoria non è presente. Dopo aver “sentito” la momoria collegata, ho semplicemente letto la memoria in un indirizzo noto:

ret = eeprom.read(indirizzo1, valore, 4);

dove “indirizzo1” è l’indirizzo da cui voglio iniziare a leggere, “valore” è il valore da scrivere, “4” la lunghezza

ret = eeprom.write(indirizzo2, valore2, 4);

come per la lettura, “indirizzo2” è l’indirizzo iniziale in cui voglio iniziare a scrivere, “valore2” il valore da scrivere e “4” la lunghezza del dato da scrivere.

Nel caso in cui si vuole leggere o scrivere solo 1 bit si può usare direttamente eeprom.read ed eeprom. write senza indicare la lunghezza dei dati da scrivere (il mio “4”),

Altre 2 funzioni che ho solo testato ma non usato sono la:

eeprom.size(); ed eeprom.pageSize();

Con eeprom.size(); mi ricavo la dimensione della mia eeprom che nel mio caso specifico è di 256 bytes, mentre con eeprom.pageSize(); non ho ben capito che parametro si ricava. Facendo una prova sulla mia 24c02 ho avuto un valore di pageSize() = 8

Tutto funziona perfettamente e sono riuscito a fare ciò che mi serviva. Se qualcuno vuole approfondire o aggiungere altro mi farebbe molto piacere. Di seguito un esempio completo (perdonatemi se ho fatto qualche grossolano errore per inesperienza, correggetemi pure). A tal proposito, dopo aver fatto tutte le operazioni nell’IF, per fermare il loop uso un accrocchio trovato in rete inserendo un while, come può essere migliorato o corretto questo codice?

Grazie mille
Luc@

//includo le librerire
#include <EEPROM24.h>
#include <I2CMaster.h>
#include <SoftI2C.h>

SoftI2C i2c(SDA, SCL); //inizializzo i pin A4 ed A5 come SDA e SCL
EEPROM24 eeprom(i2c, EEPROM_24LC02,0x50); //configuro il tipo di eeprom usata

byte valore[4]; //definisco la variabile "valore"
byte valore1[4]={
  1,2,3,4}; //definisco la variabile "valore1"
int indirizzo1 = 1; //definisco la variabile "indirizzo1"
int led = 13; //definisco la variabile led
int ret;
int presente;

void setup() {
  Serial.begin(9600); //inizializzo la velocità della seriale
  pinMode(led, OUTPUT); //setto il pin "led" come output
}

void loop() { 
  presente = eeprom.available(); //controllo se la eeprom è presente
  if (presente == 1){ 
    Serial.println("eeprom presente!");
    delay(350);
    Serial.println("Eseguo operazione!");
    Serial.println("inizio lettura");
    ret = eeprom.read(indirizzo1, valore, 4);
    Serial.print(valore[0], HEX); //stampo il valore
    Serial.print(valore[1], HEX); //stampo il valore
    Serial.print(valore[2], HEX); //stampo il valore
    Serial.print(valore[3], HEX); //stampo il valore
    delay(350);
    ret = eeprom.write(indirizzo1, valore1, 4); //scrivo il valore dichiarato prima
    Serial.println("Valori scritti, ripeto la lettura");
    ret = eeprom.read(indirizzo1, valore, 4);
    Serial.print(valore[0], HEX); //stampo il valore
    Serial.print(valore[1], HEX); //stampo il valore
    Serial.print(valore[2], HEX); //stampo il valore
    Serial.print(valore[3], HEX); //stampo il valore
    digitalWrite(led, HIGH); //accendo il led*/
    while(1){
    } //mi fermo...funziona ma implementato in modo scorretto
  } 
  else{
    Serial.println("eeprom non presente!");
    delay(350);
  }
}

Nel caso in cui si vuole leggere o scrivere solo 1 bit si può usare direttamente eeprom.read ed eeprom. write senza indicare la lunghezza dei dati da scrivere (il mio "4"),

forse intendi byte, non bit.

//mi fermo...funziona ma implementato in modo scorretto

invece è il sistema da usare, sull'arduino. Su un PC usi una EXIT perchè rilasci le risorse al SO, ma sull'arduino invece non essendoci SO bisogna "buttare via" i clock. Se non lo fai, esistono varie leggende su esplosioni e fine dell'universo.

pageSize()

indica la grandezza della pagina. La pagina è una dimensione più o meno virtuale in blocchi della memoria, credo in questo caso in bit; in pratica tu scrivi a multipli di PAGE.

Con le Eeprom 24LCxx, così come tutti i dispositivi I2C, puoi dialogarci direttamente con la libreria Wire.h integrata nell'Arduino, non occorrono librerie esterne né usare I2C software (almeno sull'Arduino).

http://www.hobbytronics.co.uk/arduino-external-eeprom

@lesto: ok, grazie mille. Si, intendevo Byte :slight_smile:

@leo72: come avevo premesso avevo già provato con altri metodi (tra cui il wire), ma di certo con il wire è più "laborioso" e quando l'ho provato, per mia inesperienza, non sono riuscito nel mio intento. Usanto questa libreria è stato tutto estremamente semplice da implementare e gestire.

E' più facile a livello utente ma diventa più complesso a livello di MCU perché ti appoggi ad una implementazione software dell'I2C (immagino dal nome della lib), appesantendo tutto.
Poi, ovviamente se ti trovi più a tuo agio così ed è meglio per te... :wink:

leo72:
E' più facile a livello utente ma diventa più complesso a livello di MCU perché ti appoggi ad una implementazione software dell'I2C (immagino dal nome della lib), appesantendo tutto.
Poi, ovviamente se ti trovi più a tuo agio così ed è meglio per te... :wink:

completamente d'accordo con te! di certo è più pesante ma l'uso di questa libreria è di più facile implementazione. Magari tra qualche mese, quando avrò un pò più di dimestichezza, usare il wire non sarà così difficile come lo è per me adesso. A tal proposito, se ne hai voglia, riusciresti a "tradurre" le poche righe che riguardano la scrittura e la lettura di questa eeprom con il wire?

grazie mille

Senza offese, ma mi dovrei studiare il datasheet di quel chip, e sinceramente non ho né il tempo né la voglia di farlo :wink:

leo72:
Senza offese, ma mi dovrei studiare il datasheet di quel chip, e sinceramente non ho né il tempo né la voglia di farlo :wink:

e allora siamo arrivati alla stessa conclusione! hihihi 8)

male.
in generale tutti i dispositivi i2c lavorano allo stesso modo, quindi imparare come funziona questo chip vuol dire in realtà semplificarsi la vita un sacco quando userai un chip senza libreria pronta, oltre che imparare veramente come funziona il chip.

e poi questa mediocrità che avanza...

puoi dialogarci direttamente con la libreria Wire.h integrata nell'Arduino, non occorrono librerie esterne né usare I2C software

però non 'puoi fare una cosa stile

eeprom.available(); //controllo se la eeprom è presente

infatti la libreria Wire è bloccante, quindi se il chip non è presente (o la comunicazione va in errore), il tuo sketch si impalla allegramente.

Lesto, ora ti banno. I mod hanno sempre ragione ]:smiley:

hai ragione se dici che si può usare la twi.h (che poi è usata anche da Wire) che non è bloccante..

Scusate se riesumo questo post del 2013 ma sto sperimentando la scrittura della eeprom esterna e ho provato ad usare le librerie di questo post..
vorrei chiedere alcune delucidazioni...facendo partire lo sketch mi dice "eeprom presente etc etc", "inizio lettura 1234 etcetc".
Ok, legge e scrive sulla eeprom. Sembra funzionare.

Ma non ho però capito una cosa: se io volessi scrivere ad un determinato indirizzo (esempio 0020 hex) il valore C3 (hex) come dovrei fare?

grazie mille!!

smartgatto:
Ma non ho però capito una cosa: se io volessi scrivere ad un determinato indirizzo (esempio 0020 hex) il valore C3 (hex) come dovrei fare?

Studiarti la libreria no ? ? ? :smiling_imp:

Se vai nel reference della libreria trovi tutti i vari metodi e uno di questi è … “bool EEPROM24::write (unsigned long address, uint8_t value)

Guglielmo

Fatto... :slight_smile:
grazie!

Esiste anche un'altra libreria per le EEPROM esterne.
--> GitHub - JChristensen/extEEPROM: Arduino library to support external I2C EEPROMs.
la versione forkata e aggiornata da me per funziona anche con la Genuino ZERO ed è inclusa nel library manager.
Basta che cerchi extEEPROM.

Salve ragazzi,

vorrei avvicinarmi al mondo Arduino pero' mi sono accorto che la sua programmazione non è cosi semplice come sembra, almeno per me che un po duretto di comprendonio... per il resto un po' di elettronica la mastico.
Vorrei capire come funziona I2c con una Eeprom tipo 24cxx, per fare alcuni esperimenti,
so che c'è una libreria di arduino che permette di leggere e scrivere memorie anche esterne.

Ho trovato un bel sito con un tutorial, dove collegato ad arduino c'è un dispaly Lcd 2x16, una memoria EEprom, pulsanti per leggere,per scrivere e cancellare la memoria, Vi linko la pagina di riferimento: http://www.microcontrollertutorial.com/arduino-tutorial-5-i2c-eeprom/

Ho montato il circuito come da schema e funziona perfettamente, quello che vorrei fare pero' e' una cosa diversa, vorrei aggiungerci un'altro zoccolo per poterci montare un'altra eeprom (naturalmente con un indirizzo diverso), cosi da poter copiare il contenuto di una eeprom (di riferimento) sull'altra.
Per me che ho pochissima esperienza nella programmazione e anche sinceramente ci prendo poco :frowning: ho capito che da solo non posso farcela.
Chiedevo se c'è qualcuno in grado di darmi qualche consiglio su come modificare il programma per il mio scopo.

emme24: essendo il tuo primo post, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

Ok, scusate

emme24:
Chiedevo se c'è qualcuno in grado di darmi qualche consiglio su come modificare il programma per il mio scopo.

Beh, direi che in quel programma hai già tutto quello che ti serve ...
... hai la routine che effettua le letture, hai quella che effettua le scritture, ti basta usare assieme leggendo da una parte (indirizzo I2C della memoria da cui leggi) e scrivendo dall'altra (indirizzo I2C della memoria su cui scrivi).

Piccolo consiglio ...
... se non hai mai sviluppato su Arduino, puoi cominciare studiando QUESTO proseguire con QUESTO e/o acquistare qualche buon libro (es. QUESTO) ... vedrai che molte cose ti si chiariranno.

Guglielmo