¿Cómo convertir int a string en Arduino?

90

¿Cómo convierto un int, nen una cadena para que cuando lo envíe a través de la serie, se envíe como una cadena?

Esto es lo que tengo hasta ahora:

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++;
}
usuario947659
fuente
3
@Pubby "printf () hace que su objeto ejecutable sea ~ 1000 bytes más grande, por lo que es posible que no desee usarlo si el tamaño es un problema". playground.arduino.cc/Main/Printf
Marcello Romani
Relacionado ( no un duplicado): Convertir un int o String en una matriz de caracteres en Arduino
Peter Mortensen

Respuestas:

131

Use así:

String myString = String(n);

Puedes encontrar más ejemplos aquí .

Cassio
fuente
4
¡No necesita usar un objeto String, Serial.print o println ya los convierte!
Alexis Paques
Estoy buscando la forma de convertir 97 en un carácter 'a' o 65 en un carácter 'A'. Me refiero al número ASCII al carácter. Descubrí que esta forma no funciona.
Oki Erie Rinaldi
@OkiErieRinaldi: Puede usar - char bar = 97; funcionará.
Cassio
25

utilizar la itoa()función incluida enstdlib.h

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

Solo necesita envolverlo alrededor de un objeto String como este:

String numberString = String(n);

También puedes hacer:

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
PedroD
fuente
9

Esta es una solución de velocidad optimizada para convertir int (entero de 16 bits con signo) en una cadena.

Esta implementación evita el uso de la división, ya que el AVR de 8 bits utilizado para Arduino no tiene instrucción DIV de hardware, el compilador traduce la división en sustracciones repetitivas que consumen mucho tiempo. Por lo tanto, la solución más rápida es usar ramas condicionales para construir la cadena.

Un búfer fijo de 7 bytes preparado desde el principio en RAM para evitar la asignación dinámica. Dado que solo tiene 7 bytes, el costo del uso de RAM fija se considera mínimo. Para ayudar al compilador, agregamos un modificador de registro en la declaración de variable para acelerar la ejecución.

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() {}

Este boceto se compila en 1.082 bytes de código utilizando avr-gcc que se incluye con Arduino v1.0.5 (el tamaño de la función int2str en sí es de 594 bytes). En comparación con la solución que usa un objeto String que se compiló en 2,398 bytes, esta implementación puede reducir el tamaño de su código en 1.2 Kb (asumiendo que no necesita otro método de objeto String, y su número es estricto para el tipo int firmado).

Esta función se puede optimizar aún más escribiéndola en el código ensamblador adecuado.

vcc2gnd
fuente
1
Un enfoque alternativo para evitar DIV es multiplicar por (2 ^ N / 10) y luego desplazarse a la derecha N bits. Entonces, para N = 16, x / 10 ~ = (x * 6554) >> 16. Lo suficientemente cerca para la mayoría de los dígitos, de todos modos.
David R Tribble
1

La solución es demasiado grande. Prueba este sencillo. Proporcione un búfer de más de 7 caracteres, sin verificación.

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

Se puede modificar fácilmente para devolver el final del búfer, si descarta el índice 'l' e incrementa el búfer directamente.

Enkryptikon
fuente
0

A continuación se muestra un myitoa () compuesto por uno mismo que es mucho más pequeño en código y reserva una matriz FIJA de 7 (incluida la terminación 0) en char * mystring, que a menudo es deseable. Es obvio que se puede construir el código con carácter-shift en su lugar, si se necesita una cadena de salida de longitud variable.

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;
}
David Svarrer
fuente
0

Esto simplemente funciona para mí:

int bpm = 60;
char text[256];
sprintf(text, "Pulso: %d     ", bpm);
//now use text as string
Carlos Tornadijo
fuente