suggerimento per problema

Buonasera a tutti i ragazzi.....
Volevo una mano a risolvere un problema....praticamente mi servirebbe capire come fare un confronto con un numero o una parola scritta in un documento su sd......cioè aprire quel file e se é presente quella scritta o quel numero mi spegnerebbe un relé.
Precisamente ho un documento.txt su sd se è presente la parola CANE in una qualsiasi riga o posizione ......l arduino mi spegnerebbe o accenderebbe un led o relé....se non é presente continuerebbe il normale processo.

Intanto devi aprire il file, poi devi leggere una riga per volta e fin qui dovresti avere già il codice tra gli esempi. Il file .txt dovrà avere un fine riga per ogni riga. Se invece in ogni riga scrivi una sola parola e ancora più semplice.

Esempio di file .txt
PESCE\r\n
GATTO\r\n
CANE\r\n

\r è la sequenza di escape e sta per Return Carriage
\n è la sequenza di escape e sta New Line

Mentre il file .txt potrebbe anche essere scritto così:
PESCE GATTO CANE\r\n

Va posto pure il .txt visto che ci siamo.

Inizia almeno a postare il codice che usi per aprire e leggere il file.

Questo è il pezzo di codice che mi va a leggere il file con una sola riga dalla SD, lo visualizza sul display e posso assegnarlo ad una variabile , se voglio:

  if (SACCA == true)
  {
    lcd.setCursor(0, 2);
    lcd.print("SERIALE: ");
    rimasti = 0; //

    while (SACCA.available())
    {
    int c = SACCA.read();
    lcd.write(c);
    if (isdigit(c))
    {
    rimasti = rimasti * 10 + c - '0';
    }
    }
    delay(1000);
    SACCA.close();
  }

Il nuovo documento ha questa tipologia, un seriale per riga, esempio:
CANE
GATTO
PESCE
RANA

ma può contenere anche caratteri alfanumerici a 10 caratteri tipo:

S52V6D5R23
852TG6AS3F

Io voglio che il programma vada a leggere le varie righe che possono essere anche 10.000 e quando per esempio mi trova PESCE, mi svolga una funzione, tipo mi accenda un led.
(DA CONSIDERARE CHE OGNI RIGA CONTIENE UNA SOLA PAROLA O SERIALE)

Non è semplicissimo

Inoltre dalla tua descrizione non è chiaro se la parola da cercare sia una costante oppure no

Comunque ho pubblicato due 'storie' (mi rifiuto di chiamarla guide) sull'argomento

Cerca i miei: "ti metto ti trovo ma non riesco a toglierti..." e " grep non vuol dire greppia"

Anzi, fai una cosa furba:

Leggiti per bene il nostro: "aiutateci ad aiutarvi" e anche il mio "la pappa è fatta"

Ci trovi tutti (tutti) gli spunti che ti servono

Ho controllato le due "guide", non ci capisco molto...se potete darmi una avvio per favore....

A fine processo nel .txt verrà scritto un seriale o una parola tipo:

CANE
o
4D6E2658RG

(UNA PAROLA O UN SERIALE PER RIGA)

A fine processo l' arduino si riavvia e alla partenza deve andare a verificare se nel .txt è presente quel seriale.

Da considerare che quel seriale è impostato come stringa:

String codicevalido = "4D6E2658RG";

Quindi al riavvio l'arduino deve fare il confronto e se presente far accendere un led

La seguente chiamata a funzione restituisce un byte.

int c = SACCA.read();

La prima volta restituisce la C di CANE. Secondo la tabella ascii il byte decimale 62 (0x43) corrisponde il simbolo ‘C’.

Bene il valore della variabile la devi aggiungere ad una variabile contenitore e continuare ad aggiungere caratteri fino a quando c’è un carattere diverso da ‘\n’. Quindi se la variabile è uguale a ‘\n’ hai terminato di collezionare i dati e dal file hai letto una riga.

Per collezionare caratteri si può usare la classe contenitore String(), ma ci sono metodi più affidabili, per adesso prova con String().
String parola(""); // la variabile contenitore

while (SACCA.available())
    {
    int c = SACCA.read();
    if ( c == '\n') 
        break;  // qui viene  interrotto il ciclo
    parola += c;
    
    }
    // qui la variabile parola dovrebbe contenere quanto letto da sd ad esempio "CANE"

 
SACCA.close();

NOTA: codice non testato scritto al volo.

Ciao.

Niente da fare non ci riesco.....

ho provato la parte di codice , ma non so se non funziona o sono io il problema...

Spiego meglio ....io ho fissato questo

String codicevalido ="1F5W46DF"

ora volevo capire dove sostiutirlo nella parte di codice....non ci sto capendo niente...purtroppo

String codicevalido ="1F5W46DF"

ora volevo capire dove sostiutirlo nella parte di codice....non ci sto capendo niente...purtroppo

Posta nuovamente il codice che stai usando. Prima di postare il codice premi Ctrl+T che esegue una indentazione automatica.

Non pensare al momento a codicevalido e alla comparazione, pensa a stampare sul monitor seriale, ogni parola letta dal file, questo al momento è il tuo obbiettivo.

Se il codice che ho postato funziona, dovresti potere scrivere:

Serial.println(parola);

Sul monitor seriale dovresti vedere tutto ciò che hai letto dal file.

PS: non ho al momento modo di scrivere codice con arduino.

Ciao.

Ho sistemato il codice prendendo spunto da “ti metto ti trovo ma non riesco a toglierti…” come consigliato da STANDARDOIL

{
    byte riga = 1;

    if (!SD.exists(FILEUTENTI))
    {
        Serial.print(F("File inesistente: "));
        Serial.println(FILEUTENTI);
        return ;
    }
    else
    {
        File dataFile = SD.open(FILEUTENTI, FILE_READ);
        Serial.print(riga);
        Serial.print(' ');

        while (dataFile.available())
        {
            //fino alla fine del file
            char cx = dataFile.read();

            if (cx == '\r')
            {
                continue;
                // ignoro fine riga windows
            }

            if (cx == '\n')
            {
                // fine riga linux
                Serial.println();
                Serial.print(++riga);
                Serial.print(' ');
                continue;
            }

            Serial.print(cx);
        }

        dataFile.close();
    }
}

praticamente mettendo utenti.txt con dentro vari SERIALI , da seriale riesco a visualizzare perfettamente i vari SERIALI.

Devi postare il codice per intero, cioè l'intero sketch (ricorda di dare Ctrl+T).

{
    byte riga = 1;

    if (!SD.exists(FILEUTENTI))
    {
        Serial.print(F("File inesistente: "));
        Serial.println(FILEUTENTI);
        return ;
    }
    else
    {
        File dataFile = SD.open(FILEUTENTI, FILE_READ);
        Serial.print(riga);
        Serial.print(' ');

        while (dataFile.available())
        {
            // legge un byte dal file e lo salva in cx
            char cx = dataFile.read();

            if ( ( cx != '\r' ) || ( cx != '\n' ) ) {

                   parola += cx;  // aggiunge il byte cx alla variabile parola

            } else  if ( cx == '\n' )   {
                   // parola contiene la riga letta dal file.
                   // la variabile parola è di tipo String documentati su questo tipo e le sue funzioni membro.
                   // Una funzione membro si chiama "compare" e si dovrebbe usare simile a:

                   if ( parola.compare( codicevalido  ) {
                         Serial.print("codice trovato = ");
                         Serial.println( codicevalido );

                         parola = "";  // azzera la variabile parola  
                         // break; // togli il commento se vuoi smettere di leggere il file 
                   } else {
                        // la comparazione non ha avuto sucesso
                        // se qui non inserisce del codice puoi togliere else { } 

                   }   
                           
               
            }

           
        }

        dataFile.close();
    }
}

Prova e fa sapere.
Nota che il tipo di dato String è comodo da usare ma ha un effetto lato che può o meno presentarsi.
Questo effetto lato è chiamato "frammentazione della RAM" e quando si verifica lo sketch ha un comportamento imprevedibile (solitamente si blocca).

In sostituzione del tipo String ci sono gli array di caratteri che se gestiti correttamente sono affidabili.
Per adesso accontentati di String e raggiungi l'obbiettivo, dopo quando ti senti pronto vedi qui

Ciao.

Ho provato e non capisco una cosa :

parola.compare( codicevalido )

compare forse dovrebbe essere compareTo o equals????

e poi parola la devo definire come variabile...stringa o altro???? questo non capisco

forse a parola devo associare i SERIALI???

Praticamente da SERIALE mi visualizza solo 1 nella prima riga

compare forse dovrebbe essere compareTo o equals?

Errore mio ,compareTo è il mebro della classe String.

Puoi anche usare == per comparare due variabili di tipo String

if (parola == codicevalido) {
   // questa porzione di codice viene eseguito solo se il contenuto della variabile parole è uguale
  // al contenuto della variabile codicevalido
}

e poi parola la devo definire come variabile...stringa o altro???? questo non capisco

Ecco il motivo per cui ti chiedo di postare l'intero sketch, solo così posso modificarlo aggiungere e rimuovere dichiarazioni.

Si comunque la variabile parola la devi dichiarare globale di tipo String

Ciao.

Niente da fare con l'ultimo pezzo di codice fornitomi gentilemente da Maurotec nel monitor seriale mi spunta solamente 1.

con quello di STANDARDOIL invece:

{
   byte riga = 1;

   if (!SD.exists(FILEUTENTI))
   {
       Serial.print(F("File inesistente: "));
       Serial.println(FILEUTENTI);
       return ;
   }
   else
   {
       File dataFile = SD.open(FILEUTENTI, FILE_READ);
       Serial.print(riga);
       Serial.print(' ');

       while (dataFile.available())
       {
           //fino alla fine del file
           char cx = dataFile.read();

           if (cx == '\r')
           {
               continue;
               // ignoro fine riga windows
           }

           if (cx == '\n')
           {
               // fine riga linux
               Serial.println();
               Serial.print(++riga);
               Serial.print(' ');
               continue;
           }

           Serial.print(cx);
       }

       dataFile.close();
   }
}

da SERIALE visualizzo tutte le righe ordinate con i vari CODICI;

Sono bloccato...non so più che fare.

Ho gia letto il mio ti metto ti trovo.....soprattutto nella sezione codiceautorizzato....ma non ci riesco
non so piu che fare

ALLORA.........
con questo codice mi funziona solo se il il seriale è impostato sulla prima riga del.txt sulla SD:

    if (SACCA == true)
     {
       lcd.setCursor(0, 2);

       rimasti = 0; //

       while (SACCA.available())
       {
         char c = SACCA.read();
        
         lcd.write(c);
         if (isdigit(c))
         {
           rimasti= rimasti * 10  + c - '0';
         }
       }
       delay(1000);
 
     }

   if (rimasti == codiceAutorizzato)
   {
     lcd.setCursor(0, 1);
     lcd.print("DISTRUTTA");
     SACCA.close();
     Riavvia();
   }

Quindi se per esempio il mio seriale è 145 mi spunta su lcd 145 e poi "DISTRUTTA" altrimenti mi visualizza tutti i codici ognuno diviso da quadratini
esempio:
144565||15514

... la discussione sulllo stesso/simile argomento prosegue QUI.

Guglielmo