Convertire String in numero

Salve, come posso convertire una Stringa dal contenuto "05" in un numero 5

String NuPer = inputString.substring(1,2);
int NuPer1 = atoi(NuPer.c_str()); 
Serial.write(NuPer1);

il risultato è sempre 0 e non 5 come mi aspettavo.
Grazie

Buongiorno,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del nostro regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :slight_smile:

>fabio60:: ... aggiungo che, anche se si stratta di poche righe, ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

Sicuro che la stringa sia "05" ? mi pare strano,la atoi() scarta gli zeri iniziali.
Prova un esempio semplice, forzando una stringa c classica "005" esempio

String NuPer = inputString.substring(1,2);
char s[]="05";
int NuPer1 = atoi(s);  // atoi(NuPer.c_str());
Serial.println(NuPer1);

Bravo @docdoc, mica avevo notato che l'utente aveva usato write invece di print !!

Grazie per avermi risposto, comunque si è 05 perchè come hai potuto vedere dal codice che io ho schritto è estrapolata da una stringa proveniente dalla ricezione seriale.

Grazie ancora

La funzione atoi la puoi usare solo con le stringhe classiche del c (array di char) e non con un oggetto di classe String Edit: giustamente come aftto notare usa la funzione c_str della classe String che restituisce un array di char.
Comunque, come solitamente viene indicato evita su Arduino si usare la classe String che nella stragrande maggioranza dei casi porta ad inevitabili blocchi che memoria esaurita, problematiche non facilmente diagnosticabili e mal di testa da debug per problemi apparentemente casuali.
Quindi rimpiazza tutti i punti dove usi la classe String con le stringhe classiche del c.
ma se proprio vuoi farti del male e prendere la strada semplice che ti consenta apparentemente di arrivare all'obiettivo con il minimo sforzo ti dico che nella classe String esiste la funzione toInt() che fa quel che desideri. Se poi quando il progetto sarà quasi finito e girando per X ore si bloccherà a casaccio saprai già dove guardare :smiley:

fabpolli:
La funzione atoi la puoi usare solo con le stringhe classiche del c (array di char) e non con un oggetto di classe String.

Guarda che lui sta usando una stringa classica del 'C' ...
... il metodo c_str() ritorna una stringa classica del 'C' a partire dall'oggetto String :wink:

Guglielmo

fabio60:
il risultato è sempre 0 e non 5 come mi aspettavo.

Eh, certo, se usi Serial.write() per stampare un intero, ti manda sulla seriale un byte il cui valore è quello della variabile... Quindi il tuo codice non restituisce affatto 0 come dici, ma dato che la variabile vale 5, ottieni un byte il cui valore è 5 ossia il carattere ASCII "ENQ".

Se ti serve visualizzarlo come valore stringa usa println():

String NuPer = inputString.substring(1,2);
int NuPer1 = atoi(NuPer.c_str()); 
Serial.println(NuPer1);

gpb01:
Guarda che lui sta usando una stringa classica del 'C' ...
... il metodo c_str() ritorna una stringa classica del 'C' a partire dall'oggetto String :wink:

Guglielmo

Errore mio, non avevo notato la funzione. Comunque uno screco visto che esiste la funzione apposita. vado a correggere il post

Comunque anche se stampo con

Serial.print(NuPer1);

ottengo 30

mentre con

Serial.write(NuPer1);

ottengo 00

ma sempre 0 è, e non 5 come io volevo.
Sicuramente sbaglio io, ma non so dove.

fabio60:
Comunque anche se stampo con
Serial.print(NuPer1);
ottengo 30
mentre con
Serial.write(NuPer1);
ottengo 00

Allora definisci "ottengo": ottieni DOVE e soprattutto COSA vuoi mandare?
Hai un monitor seriale (o putty) sul PC e vuoi leggere il valore, oppure quel dato tu lo leggi via seriale con "qualcosa"? E questo "qualcosa" deve ricevere "5" o un byte di valore 5?

No, perché con Serial.print(NuPer1) se NuPer1 vale 5, non esiste che tu ottenga 30, e tantome con Serial.write (che stampa UN BYTE) non puoi ottenere 2 caratteri ossia "00"!

Quindi magari spiega meglio la cosa, e magari prova ad eseguire questo:

String NuPer = "05";
int NuPer1 = atoi(NuPer.c_str()); 
Serial.print(NuPer1);

Sul monitor seriale leggi 5 o no?

Inoltre sei sicuro che la stringa che estrai in quel modo contenga veramente "05" e non altro? Hai verificato cosa contiene inputString esattamente??

>fabio60: Scusa, puoi riportare l'output del codice così modificato:

String NuPer = inputString.substring(1,2);
Serial.println(NuPer);
int NuPer1 = atoi(NuPer.c_str()); 
Serial.println(NuPer1);

... così vediamo un po' di cose ... ::slight_smile:

Guglielmo

il codice da te suggerito l'ho scritto, ma come riportato sopra non funziona, il risultato è sempre 0

String NuPer = inputString.substring(1,2);
Serial.println(NuPer);
int NuPer1 = atoi(NuPer.c_str()); 
Serial.println(NuPer1);

in questo caso visualizzo 30

Ma ci sono due println(), come fai ad avere solo "30"?...

E soprattutto mi rispondi per favore alle mie domande che ti ho fatto? Ossia:
Allora definisci "ottengo": ottieni DOVE e soprattutto COSA vuoi mandare?
Hai un monitor seriale (o putty) sul PC e vuoi leggere il valore, oppure quel dato tu lo leggi via seriale con "qualcosa"? E questo "qualcosa" deve ricevere "5" o un byte di valore 5?

E aggiungo anche: la inputString che tipo di variabile è?

Poi prova questo:

Serial.println(inputString);
String NuPer = inputString.substring(1,2);
Serial.println(NuPer);
int NuPer1 = atoi(NuPer.c_str()); 
Serial.println(NuPer1);

Dacci tutte e tre le righe in output.

per essere più chiari la stringa ricevuta dalla seriale è un insieme di byte così composta:

A5050100FFF00D0A

per estrapolare solo il byte 05 ho scritto il seguente codice:

    String NuPer = inputString.substring(1,2);
    int NuPer1 = atoi(NuPer.c_str());

    Serial.print(NuPer);
    Serial.print(NuPer1);
    Serial.write(NuPer1);

ma sulla seriale visualizzo:
053000

Ok, magari metti println() per separare le informazioni.

Comunque se quel codice ti restituisce "053000" teoricamente dovrebbe essere "05" per NuPer e quegli strani caratteri "3000" che non mi convincono affatto: ma sei sicuro che altrove nel tuo codice (che non ci hai fatto vedere e non hai risposto a tutte le mie domande) non stampi nulla altro sulla seriale?

Oltre a questo, intanto crea questo programmino di test e dicci cosa leggi:

void setup() {
  Serial.begin(9600);
  // Qui simulo il tuo input...
  String inputString = "A5050100FFF00D0A";

  String NuPer = inputString.substring(1,2);
  int NuPer1 = atoi(NuPer.c_str());
  Serial.println(inputString);
  Serial.println(NuPer);
  Serial.println(NuPer1);
  Serial.write(NuPer1);
  Serial.println();
  Serial.println(NuPer1 == 5);
}

void loop() {

}

Io sul monitor seriale leggo:

A5050100FFF00D0A
5
5

1

(dopo le due righe con 5, il carattere è quello che dicevo, ossua il byte con valore 5, confermato dall'"1" finale).

il codice totale è:

    String NuPer = inputString.substring(1,2);
    int NuPer1 = atoi(NuPer.c_str());

    digitalWrite(EN_TX485, HIGH);
    Serial.write(165);

    Serial.print(NuPer);
    Serial.print(NuPer1);
    Serial.write(NuPer1);
    Serial.println();
    Serial.flush();
    delay(5);

    digitalWrite(EN_TX485, LOW;

in output ho:
A5 05 30 00 0D 0A

Non hai eseguito il codice che ti ho indicato, e quello che mi stai mostrando non mi pare l'oputput seriale (chi ti converte in byte hex i valori??) ma intanto vorrei fartici quindi arrivare.

Non ti pare strano che "NuPer", che dovrebbe contenere "05", contenga invece "A5"?

Perdona ma leggi bene il mio codice, dalla stringa che ho scritto A5 05 30 00 0D 0A,
il primo byte è A5 è quando stampo write per primo:

Serial.write(165);

il secondo byte è 05 quando eseguo il codice quando estrapolo il secondo carattere

Serial.print(NuPer);

il terzo byte e 30 quando eseguo il codice

Serial.print(NuPer1)

il quartobyte e 00 quando eseguo il codice

Serial.write(NuPer1)

il quinto ed il sesto byte son \n\r

ora la mia domanda è questa se io leggo il valore estrapolato del secondo byte che è 05, perchè convertendo la stringa estrapolata si trasforma in 0 stampando con print diventa 30 e con write diventa 00?

Ok, qui come vedi c'è qualcosa che ci impedisce di capirci.

Tra l'altro se la stringa in ingresso (inputString) valesse come hai detto "A5050100FFF00D0A", per estrarre "05" dovresti fare:
String NuPer = inputString.substring(2,4);
e non:
String NuPer = inputString.substring(1,2);
Vedi il reference della substring().

Ma in realtà credo che tu non ti sia mai spiegato bene. Guardando bene sia quello che affermi essere la inputString sia quello che dichiari come output, ho l'impressione che tu stia parlando di VALORI ESADECIMALI! Ed infatti termina persino con 0D0A ossia i caratteri CR e LF!

Quindi la inputString non è uguale a "A5050100FFF00D0A" ma bensì contiene i BYTE HEX:

A5 05 01 00 FF F0 0D 0A

Eppure te l'avevo anche già chiesto: questa inputString COSA è (come è definita) e da dove viene (come viene popolata)?

Se, come immagino, sono una sequenza di BYTE terminati con CR+LF (0D 0A), intanto non devi trattarli come String ma come byte[]!! Per questo quando tu fai inputString.substring(1,2) ottieni UN CARATTERE, il cui valore numerico è 5, e non la stringa "05"! Il che mi fa supporre che tu stia facendo copia/incolla di qualche codice trovato in giro e cercando di adattarlo al tuo progetto, cosa che va anche nene, ma senza capire bene come funzioni questa cosa e dando tu a noi informazioni parziali...

Quindi, ora per favore mostraci COME è definita la inputString, COME tu ora riempi questa variabile, e forse possiamo aiutarti.

Ma se chiedi aiuto, e ti si chiede di dare informazioni o di provare un certo codice, tu per favore fallo...