Bagaimana cara mengubah int menjadi string di Arduino?

90

Bagaimana cara mengubah int,, nmenjadi string sehingga ketika saya mengirimkannya melalui serial, itu dikirim sebagai string?

Inilah yang saya miliki sejauh ini:

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++;
}
pengguna947659
sumber
3
@Pubby "printf () membuat objek yang dapat dieksekusi ~ 1000 byte lebih besar, jadi Anda mungkin tidak ingin menggunakannya jika ukuran menjadi masalah." playground.arduino.cc/Main/Printf
Marcello Romani
Terkait ( bukan duplikat): Mengonversi int atau String ke array karakter di Arduino
Peter Mortensen

Jawaban:

131

Gunakan seperti ini:

String myString = String(n);

Anda dapat menemukan lebih banyak contoh di sini .

Cassio
sumber
4
Anda tidak perlu menggunakan objek String, Serial.print atau println sudah mengonversinya!
Alexis Paques
Saya mencari cara bagaimana mengubah 97 menjadi karakter 'a' atau 65 menjadi karakter 'A'. Maksud saya nomor ASCII ke karakter. Saya menemukan cara ini tidak berhasil.
Oki Erie Rinaldi
@OkiErieRinaldi: Anda dapat menggunakan - char bar = 97; itu akan berhasil.
Cassio
25

gunakan itoa()fungsi yang disertakanstdlib.h

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

Anda hanya perlu membungkusnya di sekitar objek String seperti ini:

String numberString = String(n);

Anda juga bisa melakukan:

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
sumber
9

Ini adalah solusi kecepatan yang dioptimalkan untuk mengonversi int (bertanda integer 16-bit) menjadi string.

Implementasi ini menghindari penggunaan pembagian karena AVR 8-bit yang digunakan untuk Arduino tidak memiliki instruksi DIV perangkat keras, kompilator menerjemahkan pembagian menjadi pengurangan berulang yang memakan waktu. Jadi solusi tercepat adalah menggunakan cabang bersyarat untuk membangun string.

Buffer tetap 7 byte yang disiapkan dari awal dalam RAM untuk menghindari alokasi dinamis. Karena hanya 7 byte, biaya penggunaan RAM tetap dianggap minimum. Untuk membantu compiler, kami menambahkan pengubah register ke dalam deklarasi variabel untuk mempercepat eksekusi.

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

Sketsa ini dikompilasi menjadi 1.082 byte kode menggunakan avr-gcc yang dibundel dengan Arduino v1.0.5 (ukuran fungsi int2str sendiri adalah 594 byte). Dibandingkan dengan solusi menggunakan objek String yang dikompilasi menjadi 2.398 byte, implementasi ini dapat mengurangi ukuran kode Anda sebesar 1.2 Kb (diasumsikan bahwa Anda tidak memerlukan metode objek String lain, dan nomor Anda ketat untuk tipe int bertanda tangan).

Fungsi ini dapat dioptimalkan lebih jauh dengan menuliskannya dalam kode assembler yang tepat.

vcc2gnd
sumber
1
Pendekatan alternatif untuk menghindari DIV adalah mengalikan dengan (2 ^ N / 10) dan kemudian menggeser ke kanan dengan N bit. Jadi untuk N = 16, x / 10 ~ = (x * 6554) >> 16. Cukup dekat untuk sebagian besar digit.
David R Tribble
1

Solusinya terlalu besar. Coba yang sederhana ini. Harap berikan buffer 7+ karakter, tidak ada pemeriksaan yang dilakukan.

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

Dapat dengan mudah dimodifikasi untuk memberikan ujung belakang buffer, jika Anda membuang indeks 'l' dan menaikkan buffer secara langsung.

Enkryptikon
sumber
0

Berikut di bawah ini adalah myitoa yang disusun sendiri () yang jauh lebih kecil dalam kode, dan menyimpan array TETAP 7 (termasuk mengakhiri 0) dalam char * mystring, yang sering diinginkan. Jelas bahwa seseorang dapat membangun kode dengan pergeseran karakter sebagai gantinya, jika seseorang membutuhkan string keluaran dengan panjang variabel.

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
sumber
0

Ini bekerja untuk saya:

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