Conversioni

leo72:
A me dà, compilato, ben 1.296 byte!

E qui ci riallacciamo al discorso librerie in fase di compilazione, questo è il classico esempio di inclusione in automatico di molto codice, serve per gestire l'oggetto String, solo per aver definito una variabile :slight_smile:

Difatti l'esempio è per far capire che String è una classe ingombrante che, solo per "esistere", si porta dietro una marea di robaccia.
E' come mettersi in casa un Sanbernardo oppure un Terrier: cani sono entrambi, ma il primo mangia e sporca molto di più :stuck_out_tongue_closed_eyes:

leo72:
Difatti l'esempio è per far capire che String è una classe ingombrante che, solo per "esistere", si porta dietro una marea di robaccia.

Allora String e' da evitare in assoluto se si ha un codice un po' corposo
ma poi il char* Riga[] andra sempre usato con la sintassi riga[] = { "testo" }

Tutta 'sta storia nasce dal fatto che x = (dataFile.read()); ti fa' trovare su x il valore ascii letto dalla SD
Quindi 198 per farlo diventare un numero faccio Riga.concat(char(x)) ;
La mia Riga che attualmente e' una String deve tornare un numero perche' e' di un numero che ho bisogno
Poi per capirsi tutta la storia e' la configurazione della Ethernet che vorrei fosse modificabile dalla SD anziche' dover inserire il tutto nel codice e doverlo compilare per ogni scheda

Mettiamo di proseguire con le String ( vedo di cambiare comunque )
Per comprimere e semplificare faccio questo

void Conv_atoi(String aa ){
    char thisChar[aa.length()+1];
    aa.toCharArray(thisChar, aa.length()+1) ;
    int xx = atoi(thisChar); 
    byte bb(xx);
    } // FINE void Conv_atob()

come faccio ha "portarmi fuori" quel bb ??
Ho riesumato i testi C e C++ di un corso fatto 20 anni fa' :drooling_face: ma e' un po' una impresa

Grasssie del suggerimento

ciao

molto facile passare dal metodo Concat dell'oggetto riga ad un più leggero:

char parametro[30];
int parametro_position = 0;

nel ciclo while quando leggi un carattere alla volta fai semplicemente:

parametro[parametro_position++] = leggiDaSD();

ti basta definire la funzione con un valore di ritorno e non "void"

byte Conv_atoi(String aa ){
    char thisChar[aa.length()+1];
    aa.toCharArray(thisChar, aa.length()+1) ;
    int xx = atoi(thisChar); 
    byte bb(xx);
    return bb;
    } // FINE void Conv_atob()

quando la vai a richiamare fai

.
.
.
String pluto="Ciao";
byte pippo=Conv_atoi(pluto);
.
.
.

lucadentella:
ti basta definire la funzione con un valore di ritorno e non "void"

Praticamente cosi' ??

    byte b ;
    Riga = "222" ;
    b = Conv_atob(Riga) ;
    Serial.println(b);

 // =================
byte Conv_atob(String aa ){
    char thisChar[aa.length()+1];
    aa.toCharArray(thisChar, aa.length()+1) ;
    int xx = atoi(thisChar); 
    Serial.println(xx);
    byte bb(xx) ;
    return bb;
    } // FINE void Conv_atob()

Ho provato a risfogliare i libri ma dopo tutti 'sti anni oltretutto passati a programmare logiche molto piu' simili al basic , non e' mica semplice
Funzionare .... funziona
Ma forse e' meglio abbandonare le String
Giusto per leggere un file dalla SD e convertire una stringa si sono bruciati 14 k

o volendo potresti dichiarare bb una variabile globale e la utilizzi ogni volta che ti serve e ovunque

plrmntonio:
quando la vai a richiamare fai

String pluto="Ciao";

byte pippo=Conv_atoi(pluto);

Ho postato finche postavi Tu :slight_smile:
Ma per curiosita ... cosa vale pippo ??
Chiaro che se metto su pluto 222 avro' 222 anche su pippo , ma cosi' ?

eh già ho perso tempo mentre scrivevi comunque pippo varrà sempre il risultato della conversione fatta con la funzione Conv_atoi della variabile di tipo String che viene passata alla stessa, in questo caso pluto.

PS: pippo e pluto erano le classiche variabili di esempio che ci facevano a scuola :stuck_out_tongue:

di default se atoi() fallisce perché il char array non è un numero valido, restituisce 0:

If no valid conversion could be performed, a zero value is returned.
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

Vedo di rompere per l'ultima volta

  if (dataFile) {
    while (dataFile.available()) {
      x = (dataFile.read());
      Serial.print(char(x)); // Stampa il carattere e non il codice ASCII
    } // End while
    dataFile.close();   
   } // End if (dataFile)

Visto che il read restituisce byte, come dovrei fare per avere una stringa da cui estrarre i vari gruppi caratteri da convertire con atoi senza ricorrere all'uso di String ??

Mi rendo conto che per fare una qualsiasi cosa che vada oltre la lettura o il set di un pin ci vuole una buona conoscenza del C/C++
Tutt'altro che non serve niente come si scriveva in qualche messaggio :drooling_face:

ciao

esattamente come ti ho indicato sopra... un char è sempre un byte (http://arduino.cc/it/Reference/Char) che "identifica" un carattere secondo la tabella ASCII... puoi quindi fare un array di char e memorizzare quanto leggi dalla SD e quindi applicare direttamente a tale array la funzione atoi()

lucadentella:
puoi quindi fare un array di char

Questo e' il punto ; non capisco e non trovo come fare un array di char

Siccome i miei parametri sono tutti concatenati divisi da una , ( virgola ) facevo conto di leggere il byte che sarebbe l'x che viene fuori dal read del file
Verificare cosa ci sia dentro per trovare la virgola
Se c'e' la virgola non "accodo" il byte all'array e converto l'array in intero
Per semplicita' sara un array di interi per cui dopo avro' a[0] a[1] etc per fare quello che mi serve
Cancello l'array e vado avanti fino alla seconda virgola , poi la terza .
Il discorso di trovare la virgola salta fuori perche' puo' esserci 168 ma anche 1 ; 1 potrebbe essere 001 per avere elementi tutti da 3 caratteri ma se poi c'e' 086 si arrabbia tirando fuori storie di numeri in fomato ottale
Quindi solo 86 e niente 086

Ciao

(ti rispondo "in teoria" perché non ho sottomano un arduino+sd con cui provare)...

fai così:

  • definisci un array di char della dimensione massima che ti aspetti (es. se sono 3 cifre, char buffer[3])
  • inizi a leggere un carattere per volta dalla sd e accodi al buffer se il carattere non è ','
  • quando trovi la virgola, non la accodi al buffer e converti quanto hai memorizzato fin qui con atoi(), quindi resetti l'indice del buffer (ovvero torni a scrivere dalla posizione 0), e leggi il nuovo byte (che sarà dopo la virgola)

lucadentella:

  • definisci un array di char della dimensione massima che ti aspetti (es. se sono 3 cifre, char buffer[3])

E' quello che ho fatto

char Riga[4] ;

poi

if (dataFile) {
while (dataFile.available()) {
x = (dataFile.read());

x ha il codice asci del carattere

Come lo metto ( accodo ) sull'array Riga ?? perche poi Riga sia valida per atoi
E' questo che non so fare
Immagino che per cancellarlo basta far Riga[] = { }

Poi per il resto della struttura di controllo non avro' sicuramente problemi
If switch case for non mi fanno paura ; col linguaggio strutturato lavoro sui PLC in IEC 61131-3

Grazie per la pazienza

tieni in una variabile (tipo int posizione_riga) il punto in cui sei arrivato a scrivere nel vettore...

quindi

char carattere = leggiCarattere()
if(carattere != ',')
riga[posizione_riga++] = carattere;
else {
atoi(riga);
posizione_riga = 0;
}

brunol949:

lucadentella:
puoi quindi fare un array di char

Questo e' il punto ; non capisco e non trovo come fare un array di char

Prima di continuare col povero Luca Dentella che ti sta facendo il programma lui ;), ti consiglierei di studiarti un po' di basi di C.
Ad esempio qui spiegano gli array:
http://programmazione.html.it/guide/lezione/1099/cosa-sono-gli-array/
e qui gli array di char:
http://arduino.cc/en/Reference/String

lucadentella:
quindi

char carattere = leggiCarattere()
if(carattere != ',')
riga[posizione_riga++] = carattere;
else {
atoi(riga);
posizione_riga = 0;
}

Quindi un brutale array
Quello che dovro' capire e' la questione degli *
char e char*

Stasera riprendo in mano la cosa ; oggi e' una giornata di collaudi
Ho una torcia al plasma che mi fa' inpazzire un bus di campo sebbene sia fatto con tutti i crismi