Conflitto(?) SD.exists() e Seriale?

Buonasera,

mi sono appena scontrato con un errore che non riesco a capire. Immagino mi stia sfuggendo qualcosa nel listato perché non riesco a dare spiegazione logica a quello che mi sta succedendo.

In pratica sono andato a sommare due codici che apparentemente singolarmente funzionano senza problemi. Una volta sommati l'output che ottengo (leggi - scrivi seriale) da un risultato che non riesco a decifrare.
I due codici fanno questo:

  1. Inizializzare SD e cercare il primo fileIndex vuoto (il nome file è del tipo TEXTxxx.txt) e creare il file
  2. Leggere da seriale, immagazzinare su un array di char e una volta ottenuto il carattere '\n' stampare a seriale il risultato.

Quando vado a unire i due listati l'output che ottengo dalla seriale è

SD initialization done.
text016.txt
cia

Di seguito il mio codice:

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

File myFile;
char fileName[12];

byte i = 0;
char sentence[82];


void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  if (!SD.begin(4)) {
    Serial.println("SD initialization failed!");
  }
  else{//SD INITIALIZED
    Serial.println("SD initialization done.");
    int n = 0;
    while(n<20){
      snprintf(fileName, sizeof(fileName), "text%03d.txt", n);
      fileName[11]=0x00;
      if(!SD.exists(fileName)){
        Serial.println(fileName);
        break;
      }
      n++;
    }
  }

}//SETUP CLOSE

void loop() {
  while (Serial.available()){
    char c = Serial.read();
    strcat(&sentence[i], &c);
    i++;
    if (c=='\n'){
      sentence[i]=0x00;
      Serial.print(sentence);
      sentence[0]=0x00;
      i=0;
    }
  }
}

Ho cercato di capire cosa provocasse il problema mettendo un pezzetto alla volta del codice della SD e mi sono fermato al punto incriminato: quando uso la funzione SD.exists() da problemi. Anche commentando ciò che sta dentro quella funzione il problema permane.
Non capisco come una cosa fatta e finita nel setup possa influenza il loop in questo modo.

Lo sketch occupa il 30% e le variabili il 40% circa della memoria. Sto usando Arduino UNO R3.

Immagino chela soluzione sia banale e mi stia sfuggendo qualcosa.

Grazie,
Andrea

EDIT:

  1. ho ottenuto il problema anche usando la funzione SD.open(filename, FILE_WRITE) senza SD.exists().
  2. sembra che vada in conflitto con l'uso dei char array, non capisco in che modo, perché se stampo di volta in volta c (il char letto) gli spazi/caratteri speciali non li vedo
  3. ho ripreso in mano una libreria che mi ero fatto una decina di anni fa e usavo tranquillamente SD.exists() e tutte le seriali, ero su un mega e ne usavo tre

:confounded:

L'errore è qui
Dove tratti come stringa di C l'indirizzo di un carattere
Vero è che stringa di C è un puntatore a carattere, ma non è solo quello

Prova a riscriverla usando caratteri invece che stringhe

Non è un conflitto, e non c'entra la SD. Il problema è come stai crecando di usare (male) i char array.

Invece di usare strcat per aggiungere il carattere ricevuto, visto che "strcat" gestisce stringhe (concatena due stringhe) e non singoli caratteri, ti basta memorizzare il nuovo carattere nel buffer ("sentence") alla posizione corrente (identificata dalla variabile "i"). E magari quando fai questo aggiungi comunque sempre per sicurezza il terminatore (e non solo quando ricevi il '\n').
Per spiegarmi una cosa del genere è un po' un "classico" per gestire stringhe ricevute sotto forma di sequenza di caratteri:

...
    char c = Serial.read();
    // Memorizza il carattere nella posizione "i" ed incrementa "i" di 1
    sentence[i++] = c;
    // Carattere terminatore
    sentence[i] = 0x0;
    if (c=='\n'){
      Serial.println(sentence);
      // Reset del buffer
      sentence[0]=0x0;
      i=0;
    }
...

Ok grazie!

Questa sera quando rientro correggo e vi faccio sapere.

Ma perché secondo voi questo problema lo riscontro solo una volta che aggiungo al codice la parte della SD e se io faccio girare il codice relativo alla lettura della seriale da solo va (o meglio sembra andare a questo punto) tutto liscio?

Andrea

evidentemente nel piazzamento delle variabili in un caso la variabile c è l'ultima (e quindi ha la memoria successiva a zero binario, viene vista come una stringa terminata)
nell'altro caso no

occhio che è sbagliato "anche" nell'altro caso, ma non succede nulla per pura fortuna

Certo, infatti dicevo 'sembra andare' proprio per quello.

Ho corretto usando il seguente codice come consigliato da @docdoc che poi penso fosse lo stesso che avresti fatto tu se ho capito bene.

void loop() {
  while (Serial.available()){
    sentence[i]=Serial.read();
    if (sentence[i]=='\n'){
      sentence[i]=0x00;
      Serial.println(sentence);
      sentence[0]=0x00;
      i=0;
    }
    else{
      i++;
      sentence[i]=0x00;
    }
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.