da stringa a LONG, ma restituisce INT

Ciao a tutti, ho scritto il codice che vedete per suddividere in sottostringhe una stringa più lunga (ricevuta da un ESP8622)
La stringa che passo è la seguente: "/10;13;32;3031698675" (request)

 int apparato, codifica, bits; 
  long int codice;
  apparato = request.substring(5, 7).toInt();
  codifica = request.substring(8, 10).toInt();
  bits = request.substring(11, 13).toInt();
  codice = request.substring(14).toInt();

  Serial.println(apparato);
  Serial.println(codifica);
  Serial.println(bits);
  Serial.println(codice);

nella variabile "codice" mi dovrebbe restituire l'ultimo numero della stringa dopo il ;
finchè la cifra è minore di 2147483647 (il numero int massimo) restituisce il valore corretto.
Con il numero nell'esempio invece mi restituisce il valore int massimo.
Ero portato a pensare che il problema fosse il metodo toInt() ma ho letto che può restituire anche un valore long.
Cosa sbaglio?

I valori long sono valori segnati, quindi da -2'147'483'648 a +2'147'483'647 .... il tuo numero, 3'031'698'675 è oltre i limiti del long e quindi ottieni un valore che è l'interpretazione in formato long (segnato) dei bit a cui il tuo numero corrispende.

Con il long NON puoi superare gli estremi su indicati. Non so se c'è un medotodo della classe String() (che io NON utilizzo) per avere un unsigned long che, al contrario dei long, NON è segnato e che quindi va da 0 a 4'294'967'295.

Guglielmo

pazzokli:
La stringa che passo è la seguente: "/10;13;32;3031698675" (request)
...
nella variabile "codice" mi dovrebbe restituire l'ultimo numero della stringa dopo il ;
...

Sei sicuro che con quel codice estrai le quattro sezioni di quella stringa? A me non pare!

Inoltre toInt ritorna già un long, ma come dice Guglielmo, il problema non è la conversione, ma il tipo di long :frowning:

Federico

Si sono sicuro che il codice estrae le sottostringhe che desidero, tant'è che con i numeri sotto il limite non ho alcun problema. L'unico mio intoppo si presenta quando devo passare un numero sopra il limite int (> 2'147'483'647).
Comunque anche il long non va bene, non avevo considerato che il range è più ampio ma perché considera anche i valori negativi che io non uso.
Cosa mi suggerite?
Per andare sul concreto, sono codici di un telecomando IR passati all'ESP8266 tramite GET e suddivisi con il codice che ho pensato, sicuramente non il più adatto ma sto studiando ::slight_smile:

ora non ho modo di provare, ma potrebbe essere una soluzione dichiarare "codice" come unsigned long.
Dovrebbe mantenere il range del long ma spostarlo tutto nel positivo, quindi arrivare a 4294967295.
Sbaglio?

pazzokli:
Si sono sicuro che il codice estrae le sottostringhe che desidero, tant'è che con i numeri sotto il limite non ho alcun problema. L'unico mio intoppo si presenta quando devo passare un numero sopra il limite int (> 2'147'483'647).

Non mi pare!
Prova a stampare le sottostringhe:

  String request = "/10;13;32;3031698675";
  Serial.println(request.substring(5, 7));
  Serial.println(request.substring(8, 10));
  Serial.println(request.substring(11, 13));
  Serial.println(request.substring(14));

Secondo me ottieni queste strighe:

3;
2;
03
698675

pazzokli:
Comunque anche il long non va bene, non avevo considerato che il range è più ampio ma perché considera anche i valori negativi che io non uso.
Cosa mi suggerite?

Il suggerimento è scritto nel post #1 di Guglielmo, sempre che ti vada bene un numero da 0 a 4.294.967.295

Federico

pazzokli:
ora non ho modo di provare, ma potrebbe essere una soluzione dichiarare "codice" come unsigned long.
Dovrebbe mantenere il range del long ma spostarlo tutto nel positivo, quindi arrivare a 4294967295.
Sbaglio?

ma le leggi le risposte >:(

non sempre ho il refresh della pagina, devo aver scritto prima che aggiornassi la pagina.
Ok grazie, proverò se possibile convertire la stringa in unsigned long.

Dovrebbe bastare il cast implicito da long int a long unsigned, cioè così:

uint32_t codice;
codice = request.substring(14).toInt();

Purtroppo non c'è un metodo toUlong() nella lib. In alternativa devi convertire il tipo String in char array con il metodo,

void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {
            getBytes((unsigned char *) buf, bufsize, index);
}

char *buf deve essere un array tipo,

char buffer[12];
String.toCharArray(buffer, 12, 0);

Ora buffer contiene i caratteri di String.
Per convertire buffer in ulong usi la funzione C strtoul, tipo così,

uint32_t number = strtoul(buffer, 0,0);

[Edit] Piccolo errore tra strtol e strtoul.
Ciao.

Maurotec:
Dovrebbe bastare il cast implicito da long int a long unsigned, cioè così:

uint32_t codice;

codice = request.substring(14).toInt();




Purtroppo non c'è un metodo toUlong() nella lib. In alternativa devi convertire il tipo String in char array con il metodo,


void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {
            getBytes((unsigned char *) buf, bufsize, index);
}




char *buf deve essere un array tipo,


char buffer[12];
String.toCharArray(buffer, 12, 0);




Ora buffer contiene i caratteri di String.
Per convertire buffer in ulong usi la funzione C strtoul, tipo così,


uint32_t number = strtol(buffer, 0,0);




Ciao.

GRAZIE MILLE!!!!
addirittura il codice mi hai messo.....

Sono riuscito col tuo codice Maurotec!!!!!!!
l'unica cosa che al posto di questo:

char buffer[12];
String.toCharArray(buffer, 12, 0);

ho scritto direttamente questo:

char buffer[12];
String.getBytes((unsigned char *)buffer, 12, 0);

ancora grazie a tutti…..