Non riesco a scrivere e leggere nella EEPROM [RISOLTO]

Ho creato tre matrici e due funzioni per leggere o scrivere i valori in EEPROM, nelle funzioni ci sono dei comandi per inviare su un normalissimo display LCD, a scopo di debug, i dati scritti o letti, in scrittura semprerebbe tutto ok ma quando provo a leggere ottengo solo degli zero.
sto utilizzando un display nextion.
Per praticità avendo tre pagine ciascuna con sedici btn ho fatto si che gli ID dei btn siano da 1..16 e le matrici da 17 byte non utilizzando il primo, ogni pagina ha la sua matrice, quindi pagina uno usa MP1, pagina due MP2 e così via.

I parametri che invio alle funzioni sono esatti

** Dichiarazione matrici
uint8_t MP1[17][3]; //banco memorie Page 1 [L] [C] [Rly]
uint8_t MP2[17][3]; //banco memorie Page 1 [L] [C] [Rly]
uint8_t MP3[17][3]; //banco memorie Page 1 [L] [C] [Rly]
void R_mem(int page, int btn)
{
	
	if (page == 1)
	{
		C_pos = EEPROM.read(MP1[btn][0]);
		L_pos = EEPROM.read(MP1[btn][1]);
		mode_status = EEPROM.read(MP1[btn][2]);
	}
	
	if (page == 2)
	{
		C_pos = EEPROM.read(MP2[btn][0]);
		L_pos = EEPROM.read(MP2[btn][1]);
		mode_status = EEPROM.read(MP2[btn][2]);
	}
	
	if (page == 3)
	{
		C_pos = EEPROM.read(MP3[btn][0]);
		L_pos = EEPROM.read(MP3[btn][1]);
		mode_status = EEPROM.read(MP3[btn][2]);
	}
   
   
	lcd.clear();
	lcd.setCursor(1, 0);
	lcd.print("R >M-"+ String(page) + "-" + String (btn) +"-"+ String(EEPROM.read(MP1[btn][0])) + "-" +String(L_pos)+ "-"+ String(mode_status)); 
	
}

void W_mem(int page, int btn, int C, int L, int mode)
{
	if (page == 1)
	{
		EEPROM.write(MP1[btn][0],C);
		delay (10);
		EEPROM.write(MP1[btn][1],L);
		delay (10);
		EEPROM.write(MP1[btn][2],mode);
		delay (10);
	}
	
	if (page == 2)
	{
		EEPROM.write(MP2[btn][0],C);
		EEPROM.write(MP2[btn][1],L);
		EEPROM.write(MP2[btn][2],mode);
	}
	
	if (page == 3)
	{
		EEPROM.write(MP3[btn][0],C);
		EEPROM.write(MP3[btn][1],L);
		EEPROM.write(MP3[btn][2],mode);
	}
	
	 lcd.clear();
	lcd.setCursor(0, 1);
	lcd.print("W>M-"+ String(page) + "-" + String (btn)+ "-" + String(C) + "-" + String(L) + "-" +String(mode)); 
}

Onestamente non riesco a capire se e dove sbaglio, anzi escluderei il se.

Grazie per l'attenzione

Non credo che le istruzioni EEPROM.xxx supportino le matrici ma può darsi che mi sbagli

Prova ad usare get() e put() invece di read e write.

carlofiv:
Ho creato tre matrici e due funzioni per leggere o scrivere i valori in EEPROM, nelle funzioni ci sono dei comandi per inviare su un normalissimo display LCD, a scopo di debug, i dati scritti o letti, in scrittura semprerebbe tutto ok ma quando provo a leggere ottengo solo degli zero.

Dovresti usare tutti valori byte, in quanto se hai un "int" che vale ad esempio 4, questo è rappresentato da due byte ossia 0x0 e 0x4, e quindi quando scrivi con write() o leggi con read() dato che scrivono e leggono un byte avrai sempre zero.
Converti in "byte" tutte le variabili e parametri delle funzioni, e vedi se in questo modo ti torna tutto.

Altrimenti puoi anche pensare di usare put() e get(), come hanno detto, ma eviterei per ora di complicare le cose.

Poi, giusto come commento "accessorio", perché tre matrici e non una sola, con tre elementi?
Ossia io avrei fatto:

uint8_t MP[3][17][3]; //banchi memorie [L] [C] [Rly]

che diventa un più semplice:

...
void R_mem(byte page, byte btn)
{
  C_pos = EEPROM.read(MP[page-1][btn][0]);
  L_pos = EEPROM.read(MP[page-1][btn][1]);
  mode_status = EEPROM.read(MP[page-1][btn][2]);
...

Altra cosa "accessoria", è evitare l'uso di "String()" per motivi che in questo forum abbiamo descritto ampiamente in passato, per cui o usi una variabile char* come buffer di riga, oppure dividi i print facendone uno per ogni elemento. Ad esempio:

...
  lcd.print("R >M-"); lcd.print(page); lcd.print("-");
  lcd.print(btn); lcd.print("-"); 
...

Per finire, stando al commento ed all'uso che ne fai, occhio che tu hai invertito L e C. Nel commento scrivi che i tre elementi finali dell'array sono L, C e Rly (credo/spero nell'ordine), mentre quando leggi o scrivi sono C, L, mode (?).

Concorquoto docdoc

Inoltre aggiungo:

È concettualmente un errore scrivere due funzioni simmetriche come quelle per leggere e/o scrivere gli stessi oggetti che abbiano argomenti di tipo differente tra di loro

E serve di vedere il completo programma

Ok Docdoc seguirò le tue indicazioni sostituendo gli INT con i BYTE che asinata che ho commesso.

Idem per String.

In quanto al commento effettivamente ho scambiato L con C.

Ciao e Grazie

temo che cambiare gli int in byte non sarà risolutivo

il prototipo della EEPROM.write() cita esplicitamente byte (o uint8_t, poco cambia)

quindi già viene fatto un cast da int a byte, e quindi i primi 8 bit dello int già vengono strippati via, non vengono scritti come si temeva

io credo che il problema sia altrove, in particolare nella visibilità delle variabili

ecco perché chiedo ancora una volta di vedere il codice completo

Ecco il codice della console, come già scritto tutte le chiamate LCD sono destinate a sparire nella versione definitiva quando il NEXTION sarà ok ed in prantica a parte la EEPROM dovrei esserci.
Il codice è un po' sporco e penso che ricorrrerò maggiormente a delle funzioni.

Cosa volevi dire perchè non ho capito?

Standardoil:
È concettualmente un errore scrivere due funzioni simmetriche come quelle per leggere e/o scrivere gli stessi oggetti che abbiano argomenti di tipo differente tra di loro

accordatore_rs485_base_NEXTION.ino (11.5 KB)

Non ho ancora acceso il pc, non ho ancora visto il programma

Ma temo ci sia stato una grossa confusione con gli indirizzi in eeprom

Alle eeprom.read() va passato l'indirizzo da dove leggere, non la variabile da scrivere

Mi sa che fai prima a riscrivere l'intera parte di gestione della eeprom, non c'è UN solo errore
È proprio strana l'intera gestione

non riesco assolutamente a capire la logica che sta dietro al programma che hai scritto

come funzionerebbe il salvataggio da e per la eprom?

cosa vorresti salvare? e come?

e come vorresti ricaricarlo?

Standardoil credo di aver fatto giusto
cito solo una riga del mio codice e la descrivo

C_pos = EEPROM.read(MP1[btn][0]);

C_pos La variabile che andrà a contenere quanto letto dalla funzione EEPROM.read()
MP1 è la matrice che contiene i valori
[btn] è la linea della matrice da leggere, valore 1..16
lo zero tra parentesi quadre è la colonna della matrice da 0 a 2 (se lo scrico letteralmente impazzisce l'editor del forum

Non è lavoro mio convincerti...

carlofiv:
... cito solo una riga del mio codice e la descrivo ...

... mi sembra proprio che tu NON abbia capito i metodi della classe EEPROM ... ::slight_smile:

La EEPROM è una memoria non volatile che su Arduino UNO è composta da 1024 bytes che hanno indirizzo logico che va da 0 a 1023.

Quando tu vuoi scrivere nelle EEPROM UN singolo byte usi il metodo write(addr, val) che vuole DUE parametri: addr che è l'indirizzo dove scrivere, ovvero una delle posizioni da 0 a 1023; val che è il valore del byte che vuoi salvare in quel indirizzo.

Quando tu vuoi leggere dalla EEPROM UN singolo byte usi il metodo read(addr) che vuole UN solo parametro: addr che è l'indirizzo dove leggere, ovvero una delle posizioni da 0 a 1023 e ritorna il valore del byte che si trova a quell'indirizzo.

Quindi, addr può essere SOLO un numero intero non segnato che va da 0 a 1023 e quello che si va a scrivere in quel indirizzo può essere SOLO un byte che va da 0 a 255.

Vedi un po' ora se tu stai usando i metodi in questo modo ...

Guglielmo

Io suggerisco al'OP di studiare gli esempi della libreria eeprom presenti nel reference.

Sembrerebbe che le tre matrici da 17 per tre contengano gli 'indirizzi'

Ma che senso avrebbe?

A parte che non ho trovato (dal telefonino) dove vengono nizializzate...

Standardoil:
Sembrerebbe che le tre matrici da 17 per tre contengano gli 'indirizzi'

Ma che senso avrebbe?

A parte che non ho trovato (dal telefonino) dove vengono nizializzate...

Le matrici vengono inizializzate alle righe 47,48 e 49

Standardoil:
Sembrerebbe che le tre matrici da 17 per tre contengano gli 'indirizzi'
Ma che senso avrebbe?

Guglielmo

gpb01 ho riletto con più attenzione il tuo post

https://forum.arduino.cc/index.php?topic=715995.msg4810265#msg4810265

e credo di averlo male interpretato cercando di leggere o scrivere un singolo elemento della matrice.

Sono un poco confuso, mi sa che domani tiro fuori uno schetch più basico di quello che ho scritto finora per esercitarmi con sta EEPROM.

Standardoil:
Sembrerebbe che le tre matrici da 17 per tre contengano gli 'indirizzi'

Ma che senso avrebbe?

A parte che non ho trovato (dal telefonino) dove vengono nizializzate...

Il display alla pressione di un BTN invia alla mcu due valori :
-il numero della pagina in cui è posizionato il btn (da 1 a 3)
-lo ID del btn premuto (da 1 a 16) ecco spiegato perchè le matrici sono da 17 visto che non utilizzo lo 0.
Quella fuzione di lettura scrive nella varibile C_val quello che trova nella matrice con il numero corrispondente a quello della pagina , quindi nella riga della matrice corrispondente all' ID del btn e poi a seconda se vogliamo recuperare C,L o RLY leggo l'elemento 0,1 o 2.
In scrittura il procedimento sostanzialmente è simile pag, id, colonna C,L o RLY, val .
Apparentemente mi sembra tutto logico.
Carlo

carlofiv:
gpb01 ho riletto con più attenzione il tuo post ...

... dove io intendevo che con UNA singola put() o una singola get(), scrivevi e leggevi TUTTA la matrice.

Guglielmo