Come convertire int in string su Arduino?


90

Come converto un int,, nin una stringa in modo che quando lo invio tramite seriale, venga inviato come stringa?

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++;
}

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

Risposte:


129

Usa in questo modo:

String myString = String(n);

Puoi trovare altri esempi qui .


2
Non è necessario utilizzare un oggetto String, Serial.print o println li converte già!
Alexis Paques

Sto cercando il modo per convertire 97 in un carattere "a" o 65 in un carattere "A". Intendo numero ASCII per carattere. Ho scoperto che in questo modo non funziona.
Oki Erie Rinaldi

@OkiErieRinaldi: puoi usare - char bar = 97; Funzionerà.
Cassio

25

utilizzare la itoa()funzione inclusa instdlib.h

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


13

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

String numberString = String(n);

Puoi anche 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

9

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

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

Un buffer fisso di 7 byte 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 assistere il compilatore, aggiungiamo un modificatore di registro nella dichiarazione della variabile per velocizzare 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 in 1.082 byte di codice utilizzando avr-gcc che viene fornito in bundle con Arduino v1.0.5 (la dimensione della funzione int2str stessa è di 594 byte). Rispetto alla soluzione che utilizza un oggetto String compilato in 2.398 byte, questa implementazione può ridurre la dimensione del codice di 1,2 Kb (supponendo che non sia necessario alcun altro metodo dell'oggetto String e che il numero sia rigoroso per il tipo int firmato).

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


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.
David R Tribble

1

La soluzione è troppo grande. Prova questo semplice. Fornisci 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 la fine del buffer, se si scarta l'indice 'l' e si incrementa direttamente il buffer.


0

Di seguito è riportato un myitoa () composto da sé che è di gran lunga più piccolo nel codice e riserva un array FISSO di 7 (incluso lo 0 di terminazione) in char * mystring, che è spesso desiderabile. È ovvio che si può invece costruire il codice con il carattere-shift, se è necessaria una stringa di output di lunghezza variabile.

void myitoa(int number, char *mystring) {
  boolean negative = number>0;

  mystring[0] = number<0? '-' : '+';
  number = number<0 ? -number : number;
  for (int n=5; n>0; n--) {
     mystring[n] = ' ';
     if(number > 0) mystring[n] = number%10 + 48;
     number /= 10;
  }  
  mystring[6]=0;
}


0

Questo funziona semplicemente per me:

int bpm = 60;
char text[256];
sprintf(text, "Pulso: %d     ", bpm);
//now use text as string
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.