Arduino에서 int를 문자열로 변환하는 방법은 무엇입니까?


90

int, n를 문자열 로 변환 하여 직렬로 보낼 때 문자열로 보내도록 하려면 어떻게해야 합니까?

이것이 내가 지금까지 가지고있는 것입니다.

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 ()는 실행 가능한 객체를 ~ 1000 바이트 더 크게 만들므로 크기가 문제가되는 경우 사용하지 않을 수 있습니다." 놀이터
Marcello Romani

답변:


131

다음과 같이 사용하십시오.

String myString = String(n);

여기에서 더 많은 예를 찾을 수 있습니다 .


4
String 객체, Serial.print 또는 println을 사용할 필요가 없습니다.
Alexis Paques 2015 년

97을 'a'문자로 또는 65를 'A'문자로 변환하는 방법을 찾고 있습니다. 문자에 ASCII 숫자를 의미합니다. 이 방법이 작동하지 않는다는 것을 알았습니다.
오키 이리 리 날디

@OkiErieRinaldi : 사용할 수 있습니다-char bar = 97; 작동합니다.
Cassio

25

itoa()포함 된 기능 사용stdlib.h

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


13

다음과 같이 String 객체를 감싸기 만하면됩니다.

String numberString = String(n);

다음을 수행 할 수도 있습니다.

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

이것은 int (부호있는 16 비트 정수)를 문자열로 변환하기위한 속도 최적화 솔루션입니다.

이 구현은 Arduino에 사용되는 8 비트 AVR에 하드웨어 DIV 명령이 없기 때문에 나누기를 사용하지 않습니다. 컴파일러는 나누기를 시간이 많이 걸리는 반복적 인 빼기로 변환합니다. 따라서 가장 빠른 솔루션은 조건부 분기를 사용하여 문자열을 만드는 것입니다.

동적 할당을 피하기 위해 RAM에서 처음부터 준비된 고정 7 바이트 버퍼. 7 바이트에 불과하므로 고정 RAM 사용 비용은 최소로 간주됩니다. 컴파일러를 지원하기 위해 변수 선언에 레지스터 수정자를 추가하여 실행 속도를 높입니다.

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

이 스케치는 Arduino v1.0.5와 함께 번들로 제공되는 avr-gcc를 사용하여 1,082 바이트의 코드로 컴파일됩니다 (int2str 함수 자체의 크기는 594 바이트). 2,398 바이트로 컴파일 된 String 객체를 사용하는 솔루션과 비교할 때이 구현은 코드 크기를 1.2Kb까지 줄일 수 있습니다 (다른 String의 객체 메서드가 필요하지 않고 숫자가 signed int 유형에 엄격하다고 가정).

이 함수는 적절한 어셈블러 코드로 작성하여 더 최적화 할 수 있습니다.


1
DIV를 피하는 또 다른 방법은 (2 ^ N / 10)을 곱한 다음 N 비트만큼 오른쪽으로 이동하는 것입니다. 따라서 N = 16, x / 10 ~ = (x * 6554) >> 16. 어쨌든 대부분의 숫자에 대해 충분히 가깝습니다.
David R Tribble

1

솔루션이 너무 큽니다. 이 간단한 것을 시도하십시오. 확인되지 않은 7 자 이상의 버퍼를 제공하십시오.

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

인덱스 'l'을 버리고 버퍼를 직접 증가 시키면 버퍼의 백엔드를 제공하도록 쉽게 수정할 수 있습니다.



0

다음은 코드에서 훨씬 더 작은 자체 구성 myitoa ()이며 char * mystring에 7 (종료 0 포함)의 FIXED 배열을 예약합니다. 이는 종종 바람직합니다. 가변 길이 출력 문자열이 필요한 경우 대신 문자 이동으로 코드를 작성할 수 있다는 것은 분명합니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.