2011-10-26 19 views
59

Come si converte un int, n, in una stringa in modo tale che quando lo si invia sul seriale, viene inviato come stringa?Come convertire int in string su Arduino?

Questo è quello che ho finora:

int ledPin=13; 
int testerPin=8; 
int n=1; 

char buf[10]; 

void setup() 
{ 
    pinMode(ledPin, OUTPUT); 
    pinMode(testerPin, OUTPUT); 
    Serial.begin(115200); 
} 

void loop() 
{ 
    digitalWrite(ledPin, HIGH); 
    sprintf(buf, "Hello!%d", n); 
    Serial.println(buf); 
    delay(500); 
    digitalWrite(ledPin, LOW); 
    delay(500); 

    n++; 
} 
+0

No sprintf su Arduino? – Pubby

+0

? Tutti i commenti che c'erano qui sono andati .... cosa è successo? – user947659

+3

@Pubby "printf() rende il tuo oggetto eseguibile ~ 1000 byte più grande, quindi potresti non volerlo usare se la dimensione è un problema." http://playground.arduino.cc/Main/Printf –

risposta

89

Usa come questo:

String myString = String(n); 

Puoi trovare altri esempi here.

+2

Non è necessario utilizzare un oggetto String, Serial.print o println già convertiti! –

+0

Sto cercando il modo in cui convertire 97 in carattere "a" o 65 in carattere "A". Intendo numero ASCII per carattere. Ho trovato in questo modo non funziona. –

+0

@OkiErieRinaldi: è possibile utilizzare - char bar = 97; Funzionerà. – Cassio

-2

nel primo esempio, viene utilizzata una stringa C classica: è solo una matrice di caratteri terminata da uno zero (carattere NUL). altri esempi usano la classe String, una classe C++ che vorrei guidare lontano da altri esempi di giocattoli e piccole dimostrazioni. Fa filtrare la memoria in modi che non sono così facili da prevedere e conduce a misteriosi blocchi del tabellone.

+1

Quindi qual è la tua soluzione? – localhost

9

Questa soluzione è ottimizzata per la velocità per convertire int (numero intero a 16 bit con segno) in stringa.

Questa implementazione evita l'utilizzo della divisione poiché l'AVR a 8 bit utilizzato per Arduino non ha un'istruzione DIV hardware, il compilatore traduce la divisione in sottrazioni ripetitive che richiedono molto tempo. Quindi la soluzione più veloce sta usando i rami condizionali per costruire la stringa.

Un buffer 7 byte fisso preparato dall'inizio nella RAM per evitare l'allocazione dinamica. Poiché sono solo 7 byte, il costo dell'utilizzo fisso della RAM è considerato minimo. Per aiutare il compilatore, aggiungiamo il modificatore del registro nella dichiarazione delle variabili per accelerare l'esecuzione.

char _int2str[7]; 
char* int2str(register int i) { 
    register unsigned char L = 1; 
    register char c; 
    register boolean m = false; 
    register char b; // lower-byte of i 
    // negative 
    if (i < 0) { 
    _int2str[ 0 ] = '-'; 
    i = -i; 
    } 
    else L = 0; 
    // ten-thousands 
    if(i > 9999) { 
    c = i < 20000 ? 1 
     : i < 30000 ? 2 
     : 3; 
    _int2str[ L++ ] = c + 48; 
    i -= c * 10000; 
    m = true; 
    } 
    // thousands 
    if(i > 999) { 
    c = i < 5000 
     ? (i < 3000 
      ? (i < 2000 ? 1 : 2) 
      : i < 4000 ? 3 : 4 
     ) 
     : i < 8000 
     ? (i < 6000 
      ? 5 
      : i < 7000 ? 6 : 7 
     ) 
     : i < 9000 ? 8 : 9; 
    _int2str[ L++ ] = c + 48; 
    i -= c * 1000; 
    m = true; 
    } 
    else if(m) _int2str[ L++ ] = '0'; 
    // hundreds 
    if(i > 99) { 
    c = i < 500 
     ? (i < 300 
      ? (i < 200 ? 1 : 2) 
      : i < 400 ? 3 : 4 
     ) 
     : i < 800 
     ? (i < 600 
      ? 5 
      : i < 700 ? 6 : 7 
     ) 
     : i < 900 ? 8 : 9; 
    _int2str[ L++ ] = c + 48; 
    i -= c * 100; 
    m = true; 
    } 
    else if(m) _int2str[ L++ ] = '0'; 
    // decades (check on lower byte to optimize code) 
    b = char(i); 
    if(b > 9) { 
    c = b < 50 
     ? (b < 30 
      ? (b < 20 ? 1 : 2) 
      : b < 40 ? 3 : 4 
     ) 
     : b < 80 
     ? (i < 60 
      ? 5 
      : i < 70 ? 6 : 7 
     ) 
     : i < 90 ? 8 : 9; 
    _int2str[ L++ ] = c + 48; 
    b -= c * 10; 
    m = true; 
    } 
    else if(m) _int2str[ L++ ] = '0'; 
    // last digit 
    _int2str[ L++ ] = b + 48; 
    // null terminator 
    _int2str[ L ] = 0; 
    return _int2str; 
} 

// Usage example: 
int i = -12345; 
char* s; 
void setup() { 
    s = int2str(i); 
} 
void loop() {} 

Questo schizzo è compilato per 1.082 byte di codice utilizzando avr-gcc che impacchettato con Arduino v1.0.5 (dimensione della funzione int2str stessa è 594 byte). Rispetto alla soluzione utilizzando l'oggetto String che è stato compilato in 2.398 byte, questa implementazione può ridurre le dimensioni del codice di 1,2 Kb (presupponendo che non sia necessario alcun altro metodo di oggetto String e il proprio numero sia rigoroso rispetto al tipo int firmato).

Questa funzione può essere ulteriormente ottimizzata scrivendola nel codice assembler corretto.

+1

Un approccio alternativo per evitare DIV è moltiplicare per (2^N/10) e quindi spostarsi a destra di N bit. Quindi per N = 16, x/10 ~ = (x * 6554) >> 16. Abbastanza vicino per la maggior parte delle cifre, comunque. –

1

La soluzione è troppo grande. Prova questo semplice. Si prega di fornire un buffer di 7+ caratteri, nessun controllo effettuato.

char *i2str(int i, char *buf){ 
    byte l=0; 
    if(i<0) buf[l++]='-'; 
    boolean leadingZ=true; 
    for(int div=10000, mod=0; div>0; div/=10){ 
    mod=i%div; 
    i/=div; 
    if(!leadingZ || i!=0){ 
     leadingZ=false; 
     buf[l++]=i+'0'; 
    } 
    i=mod; 
    } 
    buf[l]=0; 
    return buf; 
} 

può essere facilmente modificato per restituire fine del tampone, se scarti index 'l' e incrementa direttamente il buffer.

16

utilizzare la funzione itoa() incluso nel stdlib.h

char buffer[7];   //the ASCII of the integer will be stored in this char array 
itoa(-31596,buffer,10); //(integer, yourBuffer, base) 
9

Hai solo bisogno di avvolgerlo attorno a un oggetto String come questo:

String numberString = String(n); 

È anche possibile fare:

String stringOne = "Hello String";      // using a constant String 
String stringOne = String('a');      // converting a constant char into a String 
String stringTwo = String("This is a string");  // converting a constant string into a String object 
String stringOne = String(stringTwo + " with more"); // concatenating two strings 
String stringOne = String(13);      // using a constant integer 
String stringOne = String(analogRead(0), DEC);  // using an int and a base 
String stringOne = String(45, HEX);     // using an int and a base (hexadecimal) 
String stringOne = String(255, BIN);     // using an int and a base (binary) 
String stringOne = String(millis(), DEC);    // using a long and a base