Go Down

Topic: leggere file .csv da sd card (Read 3363 times) previous topic - next topic

pablos

#15
Jan 09, 2013, 10:09 pm Last Edit: Jan 09, 2013, 10:35 pm by pablos Reason: 1
Quote
spataffiata di codice di pablos in realtà esiste già

infatti io ho preso un pezzo di una libreria che fa solo quello che a lui serve, il suo csv non è un misto di formati, tu invece gli dai un mattone di libreria fregandotene a metà di quello che fa.

però Lesto tu sei molto bravo a scrivere libri di testo, ma non vedo mai un esempio pratico.
io prima di pubblicare uno sketch, prendo l'alimentatore, lo collego ad arduino, apro l'ide e lo scrivo, compilo piu e piu volte finchè non fa quello che deve fare, quando sono certo che funziona lo pubblico. Nessuno mi dice ... guarda che non va.

prendi una serie di char tipo "1,0,11500,6430" e facci vedere dalla A alla Z come si fa perdi il tuo tempo a scriverlo e compilarlo come facciamo tutti noi, poi spieghi cosa hai fatto, questo è il professore modello
no comment

lesto

Quote
tu invece gli dai un mattone di libreria fregandotene a metà di quello che fa.

infatti non funziona nemmeno, il puntatore a file della fscanf e quelli della SD sono differenti e non compatibili  :smiley-mr-green:

per rimediare ecco il codice compilato MA NON TESTATO (niente SD sorry), spero che si autocommenti, sono partito dall'esempio della SD :)

Quote

/*
  SD card read/write
 
 This example shows how to read and write data to and from an SD card file    
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 modified 10 Gen 2013
 by Lesto
 
 This example code is in the public domain.
     
 */
 
#include <SD.h>

File myFile;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output
  // or the SD library functions will not work.
   pinMode(10, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    
    // read from the file until there's nothing else in it:
    int numero = 0;
    while (myFile.available()) {//finchè ci sono dati
        char tmp = myFile.read(); //leggo una lettera
        switch (tmp){
          //se è una vigola o uno '\n' interpreto il valore letto come intero, se è \n avviso della fine riga
          case '\n':
          case ',':
            Serial.print("letto un intero:");
            Serial.println( numero ); //stampo il numero
            numero=0; //lo azzero per leggere il prossimo
            if (tmp == '\n'){
              Serial.print("riga è completa");
            }else{
              Serial.print("altri dati nella riga");
            }
            break;
          //in tutti gli altri casi
          default:
            if (tmp >= '0' && tmp <='9'){ //se è una cifra e non manda il tutto in overflow
              numero = (numero*10); //scifta il numero a sinistra in base 10
              numero += tmp - '0'; //salva nello spazio vuoto la nuova unità, convertendola da carattere a numero
            }else{ //altrimenti c'è un errore!
              Serial.print("Errore di interpretazione del file, carattere errato ignorato (in esadecimale):");
              Serial.println(tmp, HEX);
            }
            break;
        }
    }
    // close the file:
    myFile.close();
  } else {
     // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop()
{
   // nothing happens after setup
}






pablos, senza offesa ma se segui il link in firma o fai una ricerca sul forum e vedrai che i miei bei esperimenti me li son fatti anche io :)
Purtopppo lavoro fino alle 18.30/19.00, e anche se sono attivo sul forum capirai ce non posso tirare fuori l'arduino/arduino IDE e fare esprerimenti
poi quando arrivo a casa non ho certo voglia di scrivere e testare codice per terze parti, salvo che non sia stimolante, ovvero la questione non sia stata affrontata centinaia di volte su questo forum.

I motivi per cui ho dato della "spatafiata" al tuo codice sono 2, e come puoi vedere lamia soluzione non è molto differente dalla tua:
1. il mio prof di informatica chiamava così i nostri codici, e mi fa piacere ricordarlo;
2. devi ammettere che fai dei salti moltali.
leggi un'intera riga in char, la metti nella classe String (per l'allocazione di ram dinamica, ovvero concatenare più facilmente i dati. ma tu sai che 1 intero è di al massimo 6 cifre, ovvero -32768, * 4 perchè sono 4 interi, +3 per le virgole e +1 perlo \n, etvoilà la dimensione massima della riga), poi da String ritorni ad array di char (che non è allocato dinamicamente, quindi rendi inutile iol concetto dell'uso di String!).
Quì avstri potuto evitare di ritornare ad array di char, tanto anche la string può essere usata con [] (http://arduino.cc/en/Reference/StringBrackets)
Bella l'idea di scorrere l'array con un puntatore, ma forse scelta infelice a scopi didattici.
Avresti potuto felicemente usare atoi() (che inserita nel codice mio di prima porta da 13.994 bytes a 14.154), ma a questo punto nascondevi la parte "interessante" di conversione vera e propria, altro punto dolente di chi fa queste richieste ( e quindi usa poco il tasto search  ]:D ).
la
Serial.println((String)temp_dato[ii]+" ");//debug
è tranquillamente
Serial.println( temp_dato[ii] );//debug

ps. anche tu non hai compilato... Serial << F("File inesistente o errore SD "); non mi risulta sai  ]:)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

pablos


Come puoi vedere non c'e' nemmeno il loop e il setup proprio perchè ho chiesto se quelle parti di inizializzazioni sd e compagnia bella già le ha, ho messo solo le 2 funzioni.

L'atoi purtroppo mi ha sempre dato problemi su cifre di 5-6 numeri.
Ti ho detto quelle cose per stimolarti ahahahahah, hai molta conoscienza, conosci una montagna di teoria e al forum me compreso servono più dettagli di quello che dici. Io purtroppo tempo fa ho scelto il ramo elettronica ed elettrotecnica, l' informatica non veniva abbinata a questi corsi nei professionali, quindi non ho conoscenze approfondite, fresche, manualità come le tue, certi trucchi purtroppo mi mancano  :(

Grazie per aver postato il programma sarà fonte di ispirazione:)

ciao




no comment

pablos

#18
Jan 10, 2013, 10:55 am Last Edit: Jan 10, 2013, 11:05 am by pablos Reason: 1
alla fine Lesto hai ridotto il tutto a questo
Code: [Select]
if (tmp >= '0' && tmp <='9'){ //se è una cifra e non manda il tutto in overflow
             numero = (numero*10); //scifta il numero a sinistra in base 10
             numero += tmp - '0'; //salva nello spazio vuoto la nuova unità, convertendola da carattere a numero


Io ho fatto una cosa un po' diversa perchè a me sembrava che questi numeri lui li volesse non solo leggere ma separare e usare singolarmente con delle variabili, ecco perchè avevo creato un array temporaneo per fare questo.

-prende la riga carattere per carattere sporchi
- quando trova lo /n lo metto in chararray e lo passo alla funzione dedicata a pulire e dividere
-divide i 4 numeri rilevando il separatore ","
-prende un numero alla volta e li archivia in un array
-li usa come meglio crede prelevandoli dall'array (esempio del serial.print array)
-torna sul file a leggere una nuova linea

se deve solo visualizzarle sul serial pulendo le righe allora avevo compreso male la richiesta

ciao
no comment

lesto

Quote
alla fine Lesto hai ridotto il tutto a questo

Quote
e come puoi vedere lamia soluzione non è molto differente dalla tua

certo, difficile trovare un sistema più semplice e funzionale.

anche se volesse leggere e usare più valori, è inutile memorizzare tutta la riga in formato char, basta salvare il dato in int nelle righe
Code: [Select]

numero=0; //lo azzero per leggere il prossimo
if (tmp == '\n'){
             Serial.print("riga è completa");
           }else{
             Serial.print("altri dati nella riga");
           }


in

Code: [Select]

if (tmp == '\n'){
             arrayDati[indice] = numero;
             analizzaArrayDati(arrayDati, indice);
             indice = 0;
             Serial.print("riga è completa");
           }else{
             arrayDati[indice] = numero;
             indice++;
             Serial.print("altri dati nella riga");
           }
numero=0; //lo azzero per leggere il prossimo
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up