[RISOLTO]Files da SD a display poi si corre via in I2c

Salve, dopo aver risolto i problemi di connessioni SPI multiple approccio al problema vero e proprio, cioè leggere i settaggi di una macchina utensile storati su sd in files tutti uguali da 256bytes e visualizzarli su un display tipo nokia3110 per selezionare quale inviare alla macchina utensile in I2c. Mai letto più di un file da sd...mi è venuto in mente di continuare, ovvero fare un file index con un editor con la lista dei file contenuti nell' SD, poi una volta selezionato lo richiamo e leggo il file memorizzando su un array i 256 byte, oppure spedendoli direttamente ( da vedersi). Ma procedo per gradi e affronto i problemi uno alla volta. Il primo ostacolo è arrivato subito..... una volta visualizzati i primi 6 ( ne riesco a vedere solo 6 alla volta sul display ) la sd continua a spedire e io non so come stoppare per fare scorrere il cursore ( inverto la visualizzazione spostandola su e giù con 2 pulsanti ) ed eventualmente caricarne altri sei... insomma la seriale bufferizza, ma quanto e come faccio a bloccare un flusso e a riprendere la sequenza da dove l' avevo lasciata? Idee??
Un' altra cosa.......ho usato le bellissime librerie di Adafruit per usare il display, funzionano bene, ma sono onnivore di ram, ne consumano 504 byte secchi perchè fanno la copia dei pixel dei display,inoltre anche la libreria SD consumicchia RAM... totale lire sono già agli sgoccioli....provo a cambiare libreria?

Buongiorno,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

Grazie Guglielmo.
Ho fatto il post e letto il regolamento.
Qualche anno fa mi ero già iscritto a questo forum, con un altro nickname, ma siccome ho perso tutto ( pw e Id )ho ricominciato tutto da capo, non credo rappresenti una violazione al regolamento, poichè la vecchia iscrizione è da considerare persa...è corretto?

Flanker6:
... ho perso tutto ( pw e Id )ho ricominciato tutto da capo, non credo rappresenti una violazione al regolamento, poichè la vecchia iscrizione è da considerare persa...è corretto?

Corretto, grazie :slight_smile:

Guglielmo

Flanker6:
... Un' altra cosa.......ho usato le bellissime librerie di Adafruit per usare il display, funzionano bene, ma sono onnivore di ram, ne consumano 504 byte secchi perchè fanno la copia dei pixel dei display,inoltre anche la libreria SD consumicchia RAM... totale lire sono già agli sgoccioli....provo a cambiare libreria?

Non risolvi cambiando libreria, se sei agli sgoccioli devi proprio cambiare MCU ...
... o un Arduino MEGA, o, se hai problemi di spazio, ti suggerisco QUESTA.

Guglielmo

Flanker6:
Il primo ostacolo è arrivato subito..... una volta visualizzati i primi 6 ( ne riesco a vedere solo 6 alla volta sul display ) la sd continua a spedire e io non so come stoppare per fare scorrere il cursore ( inverto la visualizzazione spostandola su e giù con 2 pulsanti ) ed eventualmente caricarne altri sei... insomma la seriale bufferizza, ma quanto e come faccio a bloccare un flusso e a riprendere la sequenza da dove l' avevo lasciata?

Non mi è chiaro (anche perché se non posti almeno parte del codice se non tutto, è difficile), tu visualizzi la lista dei file che trovi sulla SD fino a 6 file per schermata, quindi da cursore ne selezioni uno e quello viene spedito: in che senso "non so come stoppare per fare scorrere il cursore"? Quando tu selezioni un settaggio e confermi l'invio, lui inizia ad inviare ed essendo solo 256 byte suppongo che ci metta si e no qualche decimo di secondo, cos'è che devi stoppare?

>Flanker6: Per il resto, se guardi gli esempi della libreria SD, ce ne è uno che serve per elencare i files presenti. Adattandolo alle tue esigenze, potresti avere un array che conterrà i nomi dei files ed all'inizio, fai come in quel esempio per popolare l'array con tutti i nomi.

Una volta che hai tutti i nomi dei files nell'array diventerà piuttosto semplice visualizzarli a gruppi di sei sul display, andare vanti, indietro e selezionare.

Guglielmo

Intanto, grazie per le risposte, al dunque, l' array era stata la prima idea, poi vedendo il compilatore che mi mandava già un warning di poca ram ancora prima di iniziare ho pensato al file index, che viene letto regolarmente, sul serial monitor, il problema è la lettura di pacchetti da 6 ...e poistop, per riprendere a mio piacimento.Ho buttato giù qualcosa, ma non va bene... comunque adesso sono in giro x lavoro, fino a tutto domani, quando torno posto il codice cosi spero mi diate una mano a ragionarci sopra.. grazie a tutti
..

Salve a tutti, il codice che sto testando ora è questo:

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// include the SD library:--------
#include <SPI.h>
#include <SD.h>
const int chipSelect = 10;
//-------------------

int contrast=57;

volatile boolean up = false;
volatile boolean down = false;
volatile boolean middle = false;
int i=0;
int downButtonState = 0;
int upButtonState = 0;  
int selectButtonState = 0;          
int lastDownButtonState = 0;
int lastSelectButtonState = 0;
int lastUpButtonState = 0;
//int indicebuffer = 0; // indice di scorrimento del buffer di ricezione
char ch; // zona di ricezione dei caratteri da tastiera
String nomefile = {"index3.txt"}; // nome del file su sd
String buffile  = " "; // buffer file letto
String LCDrow1 = " "; // righe visualizzate ogni pagina su LCD
String LCDrow2 = " "; //
String LCDrow3 = " "; //
String LCDrow4 = " "; //
String LCDrow5 = " "; //
String LCDrow6 = " "; //
int flagrow = 1;

Adafruit_PCD8544 display = Adafruit_PCD8544( 5, 6, 7, 9, 8 ); // (clk,Din,DC,CE,Rst)

//---------------------------------FUNZIONI-----------------------------------
void visiva() {
   display.setTextSize(1);
   display.setTextColor(BLACK, WHITE);
   
    display.setCursor(0, 0);
    display.print(LCDrow1);
     delay(5);
    display.setCursor(0, 8);
    display.print(LCDrow2); 
     delay(5);
    display.setCursor(0, 16);
    display.print(LCDrow3); 
     delay(5);
    display.setCursor(0, 24);
    display.print(LCDrow4); 
     delay(5);
    display.setCursor(0, 32);
    display.print(LCDrow5); 
     delay(5);
    display.setCursor(0, 40);
    display.print(LCDrow6); 
     delay(5);
    display.display(); 
    
      }// end visiva


//----------------------------------------------------------------------------


//----------------------------------------------------------------------------
void setup() {
  pinMode(2, INPUT_PULLUP);// pulsanti con pull up
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  
  display.begin();      
  display.setContrast(contrast); //Set contrast to 57
  display.clearDisplay(); 
  display.display();  
  //--------------------------sd stuff---
  while (!Serial) {
; // wait for serial port to connect.
}
Serial.print("Inizializzazione SD card ------>");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("SD non presente o difettosa");
    // don't do anything more:
    return;
  }
  Serial.println("  SD pronta");

}

//----------------------------------------------------------------------------
void loop() {
  
File filesd = SD.open(nomefile); //apro il file indice
if (filesd) //Se il file è stato aperto correttamente
{
  Serial.println("file aperto"); // debug
while (filesd.available()) //Continua fino a che c'è qualcosa
{
 ch = (filesd.read()); // memorizza in ch il carattere appena letto
 buffile += ch ;      // somma i ch e forma la stringa
// Alla fine di ogni linea l' editor mette un CR ( \r ) e un LF ( \n )
 if (ch == '\n' ) { // riconoscimento LF 
    switch ( flagrow ){
       case 1:
             LCDrow1 = buffile ;//
             buffile =" ";//
             flagrow = 2;
             Serial.println(LCDrow1);//debug
             visiva();
             break;
                      
       case 2:
             LCDrow2 = buffile ;//
             buffile =" ";//
             flagrow = 3;
             Serial.println(LCDrow2);
             visiva();
             break;
                        
       case 3:
             LCDrow3 = buffile ;//
             buffile =" ";//
             flagrow = 4;
             Serial.println(LCDrow3);
             visiva();
             break;
                        
       case 4:
             LCDrow4 = buffile ;//
             buffile =" ";//
             flagrow = 5;
             Serial.println(LCDrow4);
             visiva();
             break;
                        
       case 5:
             LCDrow5 = buffile ;//
             buffile =" ";//
             flagrow = 6;
             Serial.println(LCDrow5);
             visiva();
             break;
                        
       case 6:
             LCDrow6 = buffile ;//
             buffile =" ";//
             flagrow = 0;
             Serial.println(LCDrow6);             
             visiva();              
             continue;
      case 0:            
             for(; ;)
          { 
            if (digitalRead(3) == LOW) // premo il pulsante x vedere altri 6 file
                        { 
                         flagrow = 1;
                         display.clearDisplay(); 
                         delay(50);
 LCDrow1 = " "; // svuoto righe 
 LCDrow2 = " "; //
 LCDrow3 = " "; //
 LCDrow4 = " "; //
 LCDrow5 = " "; //
 LCDrow6 = " "; //
 visiva();
                          
                        //    display.display();
                          
                          Serial.println("passa di qui");
                          break;
                          }
           }
                              break;// forse non serve
            
                        }// switch               
                    }// if                                           
                }// while        


Serial.println("file CHIUSO"); 
//nomefile.close();
for(; ;); //per bloccare tutto

        }// if sd 
      }// loop

Ovviamente è una versione debug e manca la funzione cursore, che ora non serve, la simulo bloccando lo scorrimento......
Si comporta non come vorrei..
mi visualizza correttamente i primi 5 files, il sesto, chissà perchè non c'è, e sembra non lo legga, lo salta e lo stesso fa altre 2 o 3 volte abbastanza random, come se i dati in seriale arrivassero troppo veloci, ma non sempre...Bho sono un po' fermo....Sono pronto per le bachettate..

Oggi ho voluto cambiare un po' impostazione mentale per aggredire il problema, con l'ottica di risparmiare byte, il più possibile.Leggendo post del passato, mi è piaciuta l' idea della lettura delle righe all' interno di un file terminate con "\n", cosa simpatica, ma di fatto mi sono reso conto che se i file li chiamo riempendo sempre tutti gli spazio possibili dello standard 8.3 ho già gli "indirizzi" dei vari nomi dei file contenuti dentro all' SD.In questo modo salto tutta la problematica relativa al buffer della ricezione delle letture e vad direttamente a chiamare io i nome....bene e adesso ?!? Proseguo prossimamente posto il nuovo codice che adesso è impresentabile....Comunque se qualcuno ha idee sul motivo della lettura un po' a gruviera che faceva prima, del file, mi interessa lo stesso...grazie a tutti

void loop() {
  
File filesd = SD.open(nomefile); //apro il file indice
if (filesd) //Se il file è stato aperto correttamente

il microcontroller esegue all'infinito la routine "loop", se il lavoro lo devi fare una sola volta lo devi mettere altrove,

Flanker6:
Comunque se qualcuno ha idee sul motivo della lettura un po' a gruviera che faceva prima, del file, mi interessa lo stesso...grazie a tutti

Mah ho provato a capire la logica di quel codice ma sinceramente ci vedo solo una gran confusione di idee e poca conoscenza del meccanismo di Arduino... :wink:

Per cui provo a darti qualche dritta, ti consgilio di approfondire quello che ti dico e sperimentare una cosa alla volta:

Primo, le cose da fare una sola volta (come in questo caso la lettura del contenuto del file indice su SD) le devi mettere nel setup(), non nella loop().
Secondo, non usare mai la classe "String" perché è fonte di grossissimi problemi di stabilità di Arduino. Devi imparare ad usare le stringhe classiche del linguaggio "C" (ossia degli array di char).
Terzo, dovresti iniziare a studiare gli array, non solo per le stringhe ma anch eper memorizzare il contenuto dell'indice.
Quarto, dentro fai un inutile ciclo di attesa con "for( ; ; )" quando hai già la loop() che fa la stessa cosa. E metterlo alla fine del primo tuo ciclo è deleterio perché finito di elaborare la prima volta, poi non fa assolutamente più nulla!
Quinto, usa delle costanti per i numeri dei pin, perché così oltre ad essere più leggibile il codice è più parametrico
Sesto, usa Ctrl-T nell'IDE per formattare il codice con indentazioni coerenti
Settimo, se la SD non la trovi devi bloccare il programma, quindi non "return;" che fa andare al loop() comunque ma un ciclo infinito "while(1) { }" (qui sì!) per tenerlo bloccato.

Ora, dopo che avrai studiato un poco gli array, inizia a scrivere un primo programma di test nel quale nella setup() apri il file indice e lo leggi tutto memorizzando ogni riga in un elemento dell'array.
Quindi lascia stare il display per ora e manda su seriale quello che hai letto, per verificare che ci siano TUTTE le righe del file indice.

Fatto questo, nel loop() scriverai il resto per manda alla seriale ciò che manderesti nelle 6 righe del display e verifica che funzioni come atteso con solo 2 pulsanti per fare su/giù.

Se non funziona, posta qui il nuovo codice e ti aiutiamo, ma se funziona allora ti basta iniziare ad implementare semplicemente l'output verso il dispaly al posto della seriale.

Ti posto un esempio come bozza da sviluppare (quindi non l'ho affatto provata ma scritta "al volo" per te), dove troverai già una prima impostazione anche per gli array:

#include <SPI.h>
#include <SD.h>

// Pulsanti su/giù
const byte btnUp = 2;
const byte btnDown = 3;

// Elenco dei file presenti su SD, massimo 20 file da 12 caratteri
char nomeFile[20][12];
// numero di file trovati
byte totFile = 0;
// Puntatore al primo file mostrato sul display
byte curFile = 0;
// Buffer di lettura dal file indice
char buf[32] = "";
// Puntatore all'interno del buffer di lettura
byte bufPtr = 0;
// Puntatore al numero di riga del cursore display (da 1 a 6)
byte curPtr = 1;

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

  pinMode(btnUp, INPUT_PULLUP);// pulsanti con pull up
  pinMode(btnDown, INPUT_PULLUP);

  Serial.print("Inizializzazione SD card ------>");
  if (!SD.begin(chipSelect)) {
    Serial.println("SD non presente o difettosa");
    // don't do anything more:
    while(1) { }
  }

  Serial.println("  Leggo l'indice");
  // Leggo il contenuto del file indice, in caso di errore mi fermo
  if ( !readIndex() )
    while(1){}
  
  // Letto l'indice, mostro i primi 6 file
  mostraLista(curFile, curPtr);
}

bool readIndex()
{
  File filesd = SD.open(nomefile); //apro il file indice
  if (filesd) //Se il file è stato aperto correttamente
  {
    Serial.println("  File aperto:"); // debug
    while (filesd.available()) //Continua fino a che c'è qualcosa
    {
      ch = filesd.read(); // memorizza in ch il carattere appena letto
      if (ch != '\r' )  // Ignoro il "CR"
        continue;
      if (ch != '\n' )  // Se diverso da LF memorizzo il carattere
        buf[bufPtr++] = ch;
      else
      { // Fine riga! Termino la stringa
        buf[bufPtr++] = 0;
        // Memorizzo il nome nell'array
        strcpy(nomeFile[totFile], buf);
        Serial.println(buf); // debug
        // Aggiorno i puntatori
        ++totFile;
        bufPtr = 0;
      }
    }
    return true;
  }
  else
  {
    Serial.println("Errore di apertura del file indice!");
    return false;
  }
}

void mostraLista(byte primo, byte cur)
{
  // Mostra a display 6 righe a partire da quella specificata a parametro
  
  // DA FARE
  
  // Puntatore al primo file
  curFile = 0;
  
  // Posiziona il cursore (riga "cur")
  
  // Puntatore alla riga cursore
  curPtr = cur;
}
  
//----------------------------------------------------------------------------
void loop() {
  
  // Per ora non faccio ancora nulla
  
  // Se premo il tasto "Su"
    // Se la riga corrente del display è la prima
      // Se il file corrente (puntatore) non è il primo (>0)
        // devo scrollare in su (puntatore -1)
      // fine
    // altrimenti
      // sposto il cursore in alto
    // fine
    // Aggiorno il display
    mostraLista(curFile, curPtr);
  // fine
  
  // Se premo il tasto "Giù"
    // Se la riga corrente è la sesta
      // Devo scendere con la pagina
    // altrimenti
      // sposto il cursore in basso (curPtr + 1)
    // fine
    // Aggiorno il display
    mostraLista(curFile, curPtr);
  // fine
  
}// loop

PS: ovviamente se hai domande o dubbi, chiedi pure.

Caspita!!! Prima di tutto un grosso grazie per la risposta colma di indicazioni, adesso tocca a me, ci metterò un po', ma siccome sono tenace credo che, grazie al vostro supporto, ne uscirò. Ho dato un' occhiata e sicuramente dovrò chiedere qualke cosa. Un' unica puntualizzazione per giustificare il for(;:wink: ficcato la'...era solo per bloccare il tutto in fase di debug. Che dire, a presto con molte novità, spero.

Salve a tutti.
Ho fatto uno sketch usando gli array di ch, soprattutto per imparare, ma mi ero reso già conto che c'era un problema....la ram, infatti con il solo uso delle librerie x sd e e per il display rimango poco più di 400 bytes liberi, considerando che 256 li uso sicuramente per memorizzare il file letto, da inviare in I2C, rimango poco spazio per memorizzare i nomi dei files, che invece potrebbero essere anche molti ( 60/100) quindi un array che per ogni nome consuma 12 byte non me lo posso permettere con questa macchina ( arduino uno ) Come si legge nei post Guglielmo aveva consigliato di cambiare hw,ma quello proposto lo trovo un po' caro, guardavo con maggior interesse l' esp8266, ma devo verificare la compatibilità delle librerie e poi fare prove, ma rimanendo in casa arduino uno, pensando ai post letti su questo forum, mi serebbe venuta in mente una soluzione di questo tipo: siccome conosco la lunghezza di ogni nome file e mi impongo di farli tutti lunghi uguali ( 8.3 = 12byte) posso ricavarmi con una formula, tipo n=n+12 l' indirizzo all' interno del file di ogni nome, chiamandolo ogni volta, aggiornando il display nella posizione seguente oppure 6 alla volta ( consumo byte 12 x6 = 72 ) forse così me lo posso permettere.Mi impensierisce il warning che il compilatore già mi da' ora con 400 byte disponibili dicendo che potrei avere instabilità....e arrivandoad esaurire quasi questa risorsa, cosa rischio??
Cosa ne pensate...non ho ancora provato nulla in questa direzione, non ho mai usato seek(). position(), prima di implementare qualcosa in questa direzione volevo il vostro parere...grazie

Flanker6:
rimango poco spazio per memorizzare i nomi dei files, che invece potrebbero essere anche molti ( 60/100) quindi un array che per ogni nome consuma 12 byte non me lo posso permettere con questa macchina ( arduino uno )

Si ma infatti, che ti importa, tanto tu li fai vedere solo 6 per volta quindi se lo scopo è permettere all'operatore di selezionarne uno, usa come hai accennato un buffer per la "pagina" di 6 nomi, poi quando devi andare avanti leggi i successivi 6 sempre nello stesso buffer, e così via.
Per quanto riguarda il resto, ossia l'occupazione totale di RAM, devi cercare di ottimizzare tu qualcosa, ad esempio PROGMEM o spostando in flash le stringhe costanti con F().

Puoi anche cercare in rete, ad esempio vedi QUI.

Ma se vuoi qualche indicazione ancora più precisa dovresti o mostrarci quali sono gli elementi più "ingombranti" o meglio postarci qui l'intero sketch.

Quindi mi sconsigli di provare a battere la strada della costruzione di un "puntatore" all'elenco nel file ? Era un tentativo di "ottimizzare"
Per quanto riguarda il cambio di hw verso esp8266 ....hai qualche esperienza su quella piattaforma, soprattutto la compatibilità delle librerie SD e del display...
Adesso provo a buttare giù qualcosa con l' array a pagina e vedo come va la ram.
Articolo interessante, anche se non completamente compreso.

ti seguo da un po', ma non ho ancora ben chiaro cosa vuoi fare
io questo ho capito:

  1. tu hai alcuni file (tanti) su una SD, tutti con nome in formato 8.3
  2. tu vuoi elencarli (solo i nomi) su un display 6 per volta (avendo il display 6 righe)
  3. in qualche maniera vuoi poter scorrere l'elenco 6 file per sei file, su e giù, e scegliere un file specifico
  4. poi trasmttere (in IIC, ma al momento è un dettaglio, tale file a una macchina esterna)

ci ho pigliato?

comunque lamenti un eccessivo consumo di memoria

mi sembra strano
6 stringhe da 12 caratteri non occupano più di 78 caratteri terminatori compresi

aggiungi un poco di cosine, indici, puntatori e variabili varie (insomma il solito fritto misto) non credo sia molto

posso vedere il codice (completo e attuale)?

Esatto Standardoil, inoltre i files sono tutti lunghi uguali, 256byte.
col primo codice postato, col quale visualizzavo i files sul display, ma avevo dei buchi ogni tanto ( alcuni files venivano saltati ) quando lo compilavo, leggevo un warning che mi avvertiva che avevo rimasto solo 420 bytes di ram e il sistema potrebbe diventare instabile.
Nella versione sperimentale successiva, imboccatami da DocDoc, con soli 20 files in array( in realtà ne dovrei poter gestire molti di più) avevo ridotto la ram libera a circa 180 bytes, così non ne avevo rimasti abbastanza neppure per poi caricarmi il file selezionato di 256bytes in un' altro array per poi spedirlo in I2C. Qundi ho pensato a soluzioni diverse, come ho già scritto...al momento sono fermo e ho frammenti di codice scritti, ma non so se seguire l' idea della lettura del file index calcolandomi le posizioni dei nomi sul file e caricarne 6 alla volta per visualizzarli ( consumo ram 72 bytes ) oppure passare all' esp8266, ripartendo da capo nella sperimentazione lettore SC e display ( ho visto che si dovrebbe riuscire a fare ) la gestione I2C( chissà se funzia )...e il programma già fatto con le dritte di DocDoc, che già funzionicchia...bho sono un po' spiazzato

Secondo me se non hai ancora fatto la parte di iic, non hai finito la gestione files, e gia lamenti problemi di RAM tu conviene cambiare macchina, anche perché non mi pare che nei tuoi codici vi siano troppe variabili inutili, o eccessivamente grandi. Anche perché non stiamo parlando di pochi byte, ricavabili cambiando qualche int in byte e mettendo qualche F() nelle Serial.print. Non so se ci sono librerie meno dispendiose in termini di RAM, che magari "buttino" qualcosa in più nella memoria programmi, ma mi sembra l'unica soluzione

all'ora

ho provato, si possono guadagnare una trentina di byte, in effetti pochini
credo che ti tocchi per forza passare ad un hardware più performante

la mia esperienza con le SD su ESP8266 è pessima, ma forse è solo un caso
per il display non ne ho la più pallida idea

ma tu hai già un indice di nomi di file?

comunque evita sempre, come la peste l'uso degli oggetti String

quello che ti lascio qui è la versione che usa char * di quello del tuo post #8

1596 byte mentro quello tuo occupava 1627
non c'è un oggetto stringa che sia uno ed è pure più piccolo 17238 byte di programma contro 18274

non è nemmeno più difficle da scrivere, basta abituarsi a usare char * al posto di String

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// include the SD library:--------
#include <SPI.h>
#include <SD.h>
#define chipSelect  10
//-------------------

#define contrast 57

volatile boolean up = false;
volatile boolean down = false;
volatile boolean middle = false;
int i = 0;
byte downButtonState = 0;
byte upButtonState = 0;
byte selectButtonState = 0;
byte lastDownButtonState = 0;
byte lastSelectButtonState = 0;
byte lastUpButtonState = 0;



char nomefile[] = "index3.txt"; // nome del file su sd
char buffile[14]; // buffer file letto
char LCDrow1[14]; // righe visualizzate ogni pagina su LCD
char LCDrow2[14];
char LCDrow3[14];
char LCDrow4[14];
char LCDrow5[14];
char LCDrow6[14];
byte flagrow = 1;

Adafruit_PCD8544 display = Adafruit_PCD8544(5, 6, 7, 9, 8);   // (clk,Din,DC,CE,Rst)

//---------------------------------FUNZIONI-----------------------------------
void visiva()
{
    display.setTextSize(1);
    display.setTextColor(BLACK, WHITE);
    display.setCursor(0, 0);
    display.print(LCDrow1);
    delay(5);
    display.setCursor(0, 8);
    display.print(LCDrow2);
    delay(5);
    display.setCursor(0, 16);
    display.print(LCDrow3);
    delay(5);
    display.setCursor(0, 24);
    display.print(LCDrow4);
    delay(5);
    display.setCursor(0, 32);
    display.print(LCDrow5);
    delay(5);
    display.setCursor(0, 40);
    display.print(LCDrow6);
    delay(5);
    display.display();
}// end visiva


//----------------------------------------------------------------------------


//----------------------------------------------------------------------------
void setup()
{
    pinMode(2, INPUT_PULLUP);// pulsanti con pull up
    pinMode(3, INPUT_PULLUP);
    pinMode(4, INPUT_PULLUP);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    // Open serial communications and wait for port to open:
    Serial.begin(9600);
    display.begin();
    display.setContrast(contrast);
    display.clearDisplay();
    display.display();
    //--------------------------sd stuff---
    Serial.print("Inizializzazione SD card ------>");

    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect))
    {
        Serial.println(F("SD non presente o difettosa"));
        // don't do anything more:
        return;
    }

    Serial.println(F("  SD pronta"));
}

//----------------------------------------------------------------------------
void loop()
{
    File filesd = SD.open(nomefile); //apro il file indice

    if (filesd) //Se il file è stato aperto correttamente
    {
        Serial.println(F("file aperto")); // debug
        byte i = 0;

        while (filesd.available()) //Continua fino a che c'è qualcosa
        {
            char  ch = (filesd.read()); // memorizza in ch il carattere appena letto
            buffile[i++] = ch ;    // somma i ch e forma la stringa
            buffile[i] = 0; // per terminare sempre la stringa

            // Alla fine di ogni linea l' editor mette un CR ( \r ) e un LF ( \n )
            if (ch == '\n')    // riconoscimento LF
            {
                switch (flagrow)
                {
                    case 1:
                        strcpy(LCDrow1, buffile) ; //
                        buffile[0] = 0; //
                        flagrow = 2;
                        Serial.println(LCDrow1);//debug
                        visiva();
                        break;

                    case 2:
                        strcpy(LCDrow2, buffile); //
                        buffile[0] = 0; //
                        flagrow = 3;
                        Serial.println(LCDrow2);
                        visiva();
                        break;

                    case 3:
                        strcpy(LCDrow3, buffile); //
                        buffile[0] = 0; //
                        flagrow = 4;
                        Serial.println(LCDrow3);
                        visiva();
                        break;

                    case 4:
                        strcpy(LCDrow4, buffile) ; //
                        buffile[0] = 0; //
                        flagrow = 5;
                        Serial.println(LCDrow4);
                        visiva();
                        break;

                    case 5:
                        strcpy(LCDrow5, buffile) ; //
                        buffile[0] = 0; //
                        flagrow = 6;
                        Serial.println(LCDrow5);
                        visiva();
                        break;

                    case 6:
                        strcpy(LCDrow6, buffile) ; //
                        buffile[0] = 0; //
                        flagrow = 0;
                        Serial.println(LCDrow6);
                        visiva();
                        continue;

                    case 0:
                        for (; ;)
                        {
                            if (!digitalRead(3)) // premo il pulsante x vedere altri 6 file
                            {
                                flagrow = 1;
                                display.clearDisplay();
                                delay(50);
                                LCDrow1[0] = 0; // svuoto righe
                                LCDrow2[0] = 0; //
                                LCDrow3[0] = 0; //
                                LCDrow4[0] = 0; //
                                LCDrow5[0] = 0; //
                                LCDrow6[0] = 0; //
                                visiva();
                                //    display.display();
                                Serial.println(F("passa di qui"));
                                break;
                            }
                        }

                        break;// forse non serve
                }// switch
            }// if
        }// while

        Serial.println(F("file CHIUSO"));

        //nomefile.close();
        for (; ;); //per bloccare tutto
    }// if sd
}// loop

inoltre si possono fare ancore delle (piccole) limature
usare un array di char * invece di 6 differenti variabili
e unificare i 6 casi attraverso un indice invece che 6 pezzi uguali di programma

comunque rimane poca cosa,

hai per caso una MEGA?