Làm thế nào để chuyển đổi int thành chuỗi trên Arduino?


90

Làm cách nào để chuyển đổi một int, nthành một chuỗi để khi tôi gửi nó qua chuỗi, nó sẽ được gửi dưới dạng một chuỗi?

Đây là những gì tôi có cho đến nay:

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 () làm cho đối tượng thực thi của bạn lớn hơn ~ 1000 byte, vì vậy bạn có thể không muốn sử dụng nó nếu kích thước là vấn đề." sân
chơi.arduino.cc/Main/Printf

Câu trả lời:


129

Sử dụng như thế này:

String myString = String(n);

Bạn có thể tìm thêm ví dụ ở đây .


2
Bạn không cần phải sử dụng đối tượng String, Serial.print hoặc println đã chuyển đổi chúng!
Alexis Paques

Tôi đang tìm cách chuyển 97 thành ký tự 'a' hoặc 65 thành ký tự 'A'. Ý tôi là số ASCII thành ký tự. Tôi thấy cách này không hiệu quả.
Oki Erie Rinaldi

@OkiErieRinaldi: Bạn có thể sử dụng - char bar = 97; nó sẽ hoạt động.
Cassio

25

sử dụng itoa()chức năng có trongstdlib.h

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


13

Bạn chỉ cần quấn nó xung quanh một đối tượng String như sau:

String numberString = String(n);

Bạn cũng có thể làm:

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

Đây là giải pháp tối ưu hóa tốc độ để chuyển đổi int (số nguyên 16 bit có dấu) thành chuỗi.

Việc triển khai này tránh sử dụng phép chia vì AVR 8-bit được sử dụng cho Arduino không có lệnh DIV phần cứng, trình biên dịch dịch phép chia thành các phép trừ lặp đi lặp lại tốn thời gian. Vì vậy, giải pháp nhanh nhất là sử dụng các nhánh có điều kiện để xây dựng chuỗi.

Một bộ đệm 7 byte cố định được chuẩn bị từ đầu trong RAM để tránh phân bổ động. Vì nó chỉ có 7 byte, chi phí sử dụng RAM cố định được coi là tối thiểu. Để hỗ trợ trình biên dịch, chúng tôi thêm công cụ sửa đổi thanh ghi vào khai báo biến để tăng tốc độ thực thi.

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

Bản phác thảo này được biên dịch thành 1.082 byte mã sử dụng avr-gcc đi kèm với Arduino v1.0.5 (kích thước của chính hàm int2str là 594 byte). So với giải pháp sử dụng đối tượng String được biên dịch thành 2.398 byte, việc triển khai này có thể giảm kích thước mã của bạn xuống 1,2 Kb (giả sử rằng bạn không cần phương thức đối tượng String nào khác và số của bạn là nghiêm ngặt đối với kiểu int có dấu).

Chức năng này có thể được tối ưu hóa hơn nữa bằng cách viết nó bằng mã trình hợp dịch thích hợp.


1
Một cách tiếp cận khác để tránh DIV là nhân với (2 ^ N / 10) và sau đó dịch sang phải với N bit. Vì vậy, với N = 16, x / 10 ~ = (x * 6554) >> 16. Dù sao cũng đủ gần cho hầu hết các chữ số.
David R Tribble

1

Giải pháp là quá lớn. Hãy thử cái đơn giản này. Vui lòng cung cấp bộ đệm 7 ký tự trở lên, không kiểm tra.

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

Có thể dễ dàng sửa đổi để trả lại phần cuối của bộ đệm, nếu bạn loại bỏ chỉ mục 'l' và tăng bộ đệm trực tiếp.


0

Dưới đây là một myitoa () tự sáng tác, nhỏ hơn nhiều trong mã và dự trữ một mảng CỐ ĐỊNH 7 (bao gồm cả phần cuối là 0) trong chuỗi ký tự * char *, điều này thường được mong muốn. Rõ ràng là người ta có thể xây dựng mã với ký tự shift thay thế, nếu người ta cần một chuỗi đầu ra có độ dài thay đổi.

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

Điều này đơn giản làm việc cho tôi:

int bpm = 60;
char text[256];
sprintf(text, "Pulso: %d     ", bpm);
//now use text as string
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.