Problema PROGMEM e Array di array

sto diventando pazzo è da un paio di giorni che cerco di capire dove sbaglio ma il cervello ormai mi è andato in fumo :slight_smile:

dichiaro gli array con i dati
PROGMEM prog_char h0[]={4,14,31,0,31,31,31,0};
PROGMEM prog_char h1[]={4,14,31,0,0,0,0,0};
PROGMEM prog_char h2[]={31,31,31,31,4,4,4,0};
PROGMEM prog_char h3[]={0,4,4,4,31,31,31,31};
PROGMEM prog_char h4[]={0,0,0,0,0,31,14,4};
PROGMEM prog_char h5[]={0,31,31,31,0,31,14,4};

dichiaro l'array contenitore
PROGMEM const char *item[] = {h0, h1, h2, h3, h4, h5};

adesso provo a leggere i singoli valori precedentmente dichiarati in ogni array

byte buffer[8];

for (int i=0;i<6;i++)
{
strcpy_P((char*)buffer,(char*)pgm_read_word(&(item[ i ])));
for (int j=0;j<8;j++)
{
Serial.print(buffer[j]);
Serial.print(" ");
}
Serial.println("");
}

mi vengono ritornati questi valori:

4 14 31 0 13 18 3 158
4 14 31 0 13 18 3 158
31 31 31 31 4 4 4 0
0 31 31 31 4 4 4 0
0 31 31 31 4 4 4 0
0 31 31 31 4 4 4 0

qualcuno mi potrebbe illuminare per capire dove sbaglio

vi ringrazio in anticipo
Buona domenica a tutti

Intanto non so se char byffer[8] sia corretto. Le stringhe di solito hanno 1 carattere terminatore, \0.
Prova con char buffer[9].

Poi prova con questo:
strcpy_P(buffer, (char*)pgm_read_word(&(item*)))*
senza fare il casting di buffer
Infine ti do un link:
avr-libc: Data in Program Space

leo72:
Intanto non so se char byffer[8] sia corretto. Le stringhe di solito hanno 1 carattere terminatore, \0.
Prova con char buffer[9].

Poi prova con questo:
strcpy_P(buffer, (char*)pgm_read_word(&(item*)))*
senza fare il casting di buffer
Infine ti do un link:
avr-libc: Data in Program Space
[/quote]
ho messo: char buffer[9]
non ho fatto il casting quindi ho scritto: strcpy_P(buffer, (char*)pgm_read_word(&(item[ i ])))
ma nella seriale non stampa nulla

  • *

Qui non c'è il problema dello zero finale, perché per stampare il contenuto dell'array non usa una funzione come Serial.print, ma stampa i byte uno ad uno.

La pagina dove il tutto è speigato per bene è questa:

La strcpy_P copia fino al primo byte nullo. Osserva attentamente dove si trova il byte 0 in ciascuno dei 6 array h0..h5. Gli altri byte di buffer[] non vengono toccati dalla strcpy_P, ma tu li stampi lo stesso. Dopo il byte zero hai sostanzialmente dei valori casuali (oppure quelli precedentemente memorizzati in quelle posizioni).

Il problema di fondo è che stai usando una funzione che presuppone stringhe null-terminated, la strcpy_P, in un constesto in cui 0x00 non significa "fine", e lavori invece con array di byte in di cui conosci a priori la dimensione.

La soluzione secondo me è eliminare la strcpy_P e copiare "a mano" byte per byte i dati dalla progmem al buffer in RAM.

ho in parte capito il problema e risolto in modo spartano

analizziamo il primo array:
PROGMEM prog_char h0[]={4,14,31,0,31,31,31,0};

quando questo array veniva letto e arrivva alla posizione 3 che corrisponde allo 0, per lui l'array era finito quindi dal valore successivo in poi iniziava a dare valori sbagliati, per adesso ho solo levato questo zero e tutto funziona, ma se mi capitase di dover metere per forza uno zero, come potrei risolvere?

Ma hai la necessità di salvare dei byte oppure salvi gli ASCII di una stringa? Perché in questo caso allora ti converrebbe forse salvare direttamente la stringa e far fare lo sporco lavoro a PROGMEM.

ma se mi capitase di dover metere per forza uno zero, come potrei risolvere?

Le funzioni str* lavorano sull'assunto che il byte zero indica la fine della stringa. Se non rispetti questa convenzione, allora devi evitare l'uso di quelle funzioni, e fare il lavoro di copia "a mano".

in questi array salvo dei numeri che successivamente vengono passati alla funzione creaCustomChar per creare dei caratteri non presenti nel mio LCD

Se devi copiare dei byte null non puoi usare strcpy_P. Cerca tra le funzioni _P una funzione di copia che non inizi con "str". Mi viene in mente memcpy(), ad esempio (è solo un suggerimento di ricerca...)

In alternativa hai considerato l'uso della EEPROM ?