Lettura su SDCard

Buonasera,
con questo codice alla pressione di un tasto leggo una riga alla volta presente nel file .txt della sdcard. (leggo 2 parole separate dal punto e virgola)
il mio problema è che quando arriva alla fine dell'elenco, vorrei che con un'altro pulsante potrei tornare indietro, o meglio quando arriva a fine elenco riparta dall'inizio, oppure se fosse possibile
usare un encoder rotativo per scorrere su e giù l'elenco.

Grazie a tutti per l'aiuto.

void loop()
{

  int enterState = digitalRead(enterPin);

 
  if(enterState == HIGH)
  {
    Keyboard.begin();
   Keyboard.println(value.c_str());
    delay(1000);
  }

 
  int nextState = digitalRead(nextPin);


  
  if (nextState == HIGH)
  {
    key = "";
    value = "";
    bool inkey = true;
    while (myFile.available())
    {
      char c = (char)myFile.read();
      if(c == '\n')
      {
        if(key == "")
        {
          key = "";
          value = "";
          if(!myFile.available())
          {
           myFile.close();
            myFile = SD.open("file.txt");
          }
          continue;  
        }
        
        inkey = true;



 oled.setFont(Arial14);
  oled.setCursor(0, 0);
  oled.clear();
  oled.print(key.c_str());
 
     

        delay(500);
        return;
      }
      else
      {
        if(inkey)
        {
          if(c == ';')
          {
            inkey = false; 
          }
          else
          {
            key += c;
          }
        }
        else
        {
          value += c;
        }
      }

      if(!myFile.available())
      {
        myFile.close();
        myFile = SD.open("file.txt");
      }
    }
  }
}

Guarda il metodo seek() della libreria SD :wink:

Guglielmo

A dire il vero mi ero già cimentato con un esempio del genere, ma purtroppo non sono riuscito a concludere nulla... :confused:

Il metodo seek() ti permette di spostare il puntatore, relativo a cosa verrà letto dal file, avanti e indietro, dove vuoi tu.

Dato ch tu dici:

format:
... o meglio quando arriva a fine elenco riparta dall'inizio ...

quando la lettura da SD ti indica che sei arrivato a fine file (ti ritorna -1), devi fare una SD.seek(0) e riposizionarti, in questo modo, all'inizo. La successiva lettura leggerà esattamente dall'inizio, come tu avessi appena aperto il file.

Guglielmo

vorrei provare questa modifica, se è giusta dove va inserita rispetto al codice?

int finefile = file.size();

if{
file.seek(finefile - 1);
//fai qualcosa....
}

Grazie

... scusa a cosa dovrebbe servire?

Se apri in scrittura, si posiziona automaticamente alla fine del file per proseguire, se apri in lettura si posiziona automaticamnete all'inizio del file ... quella a che serve?

In ogni caso la inserisci dove ti serve spostarti nel file ...

Guglielmo

in realtà la sera quando torno da lavoro mi cimento con prove di ogni genere, ma senza nessun risultato,
quello di sopra è un pezzo di codice che ritenevo buono per fare quello che mi serve, però non so dove posizionarlo nel codice completo.

Vorrei fare una lettura del file .txt presente nella SD riga per riga, dalla prima all'ulima, quando arriva all'ultima vorrei che tornasse alla prima, ma se dici che il lettura si posiziona all'inizio, allora non va bene la funzione?
Cortesemente non potresti dirmi cosa e dove aggiungere?

Grazie.

format:
Vorrei fare una lettura del file .txt presente nella SD riga per riga, dalla prima all'ulima, quando arriva all'ultima vorrei che tornasse alla prima

... e ok, ma ti ho già detto come fare :

gpb01:
... quando la lettura da SD ti indica che sei arrivato a fine file (ti ritorna -1), devi fare una SD.seek(0) e riposizionarti, in questo modo, all'inizo. La successiva lettura leggerà esattamente dall'inizio, come tu avessi appena aperto il file.

... quindi, tu leggi normalmente e, quando arrivi alla fine del file (la lettura ti ritorna -1 perché non c'è più nulla da leggere) allora fai la seek(0) e torni all'inizio. Dove è il problema?

Guglielmo

il problema è che non so come fare :confused:

... beh, direi che prima di tutto dovresti rivedere un po' la tua preparazione su Arduino ... metti da parte un'attimo il programma e ... cerca di studiare QUESTO proseguire con QUESTO e acquistare qualche buon libro (come QUESTO) ... credo che poi avrai le idee un po' più chiare su come procedere :wink:

Guglielmo

grazie per i link, però credo che finchè io capisca come applicare la funzione seek, passano anni, e siccome ne ho già abbastanza (di anni), immagino come va a finire... :confused:

Te la senti di corregere il codice sopra con la funzione?

Grazie per l'aiuto.

... ok, tu indicami dove ritieni che il codice stila leggendo che il file è finito e poi vediamo assieme cosa fare.

Ricorda che comunque la sequenza è:

  1. apro la SD

  2. leggo un carattere

  3. il carattere letto vale -1?

3.1 NO, bene allora ho altri caratteri da leggere
3.1.1 utilizzo il carattere letto e torno a 2.

3.2 SI, significa che non ci sono più caratteri da leggere
3.2.1 faccio quello che devo fare quando non ho più nulla da leggere
3.2.2 faccio la seek(0) e mi riposiziono all'inizio
3.2.3 torno al punto 2.

Tutto qui.

Guglielmo

Qualche prova l'ho fatta utilizzando pezzi di codice "adattato", con la funzione seek succedeva che mi leggeva la prima linea, e la seconda linea mi troncava le parole, (seek(3) mi tagliava le prime 3 parole della linea successiva).

Forse mi sono spiegato male, il codice deve leggere in ordine una dopo l'altra (alla pressione del pulsante)
tutte le linee presenti nel file .txt, alla fine dovrebbe tornare all'inizio, oppure con un'altro pulsante leggere
dall'ultima riga fino a tornare in cima.

Il file .txt della SD è così strutturato:

primalinea;parola
secondalinea;parola
terzalinea;parola
ecc..

forse per fare questo non serve la funzione seek?

Grazie ancora per la disponibilità.

Allora, ti do ancora un aiuto, poi vale il mio post #9

Ti allego un piccolo esempio di programma che, prima scrive 10 rirge in un file sulla SD, dopo di che … legge il file carattere a carattere, controlla se è arrivato alla fine e, se è arrivato alla fine, si riposiziona all’inizio con la seek() e ripete la lettura (la lettura ed il posizionamento vengono ripetute all’infinito).

Studiatelo e cerca di capire come e quando viene semplicemente usata la seek() per tornare all’inizio del file.

Guglielmo

Test_SD.ino (1.47 KB)

Allora nel tuo esempio con myFile.seek(3); (per fare una prova) mi taglia le prime 3 lettere della prima riga.

Ho adatto la funzione seek nel codice che ho postato all'inizio e si comporta come se non sentisse proprio
la funzione myFile.seek(0);, posso mettere myFile.seek(2);, myFile.seek(3 ); che comunque a partire dalla seconda linea mi toglie sempre la prima lettera, però dopo la lettura delle 3 righe, con 5 click sul pulsante torna alla prima linea, ho notato anche che se lascio solo queste 2 righe di codice:

c = myFile.read();
if (c == -1) {
}

comunque alla terza riga (che sarebbe l'ultima) con 2 click sul pulsante torna alla prima linea con tutte le lettere, dalla seconda linea manca sempre la prima lettera.

La funzione l'ho inserita subito dopo il codice del display:
oled.setFont(Arial14);
oled.setCursor(0, 0);
oled.clear();
oled.print(key.c_str());

mentre replico al post ho provato anche con solo: c = myFile.read();
e comunque torna all'inizio linea con 5 click

Grazie.