2011-10-26 1665 views
59

如何將int,n轉換爲字符串,以便在通過串行發送它時將其作爲字符串發送?如何將int轉換爲Arduino上的字符串?

這是我到目前爲止有:

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

無sprintf在Arduino上? – Pubby

+0

?這裏所有的評論都沒有了......發生了什麼? – user947659

+3

@Pubby「printf()使您的可執行對象大1000字節,所以如果大小有問題,您可能不想使用它。」 http://playground.arduino.cc/Main/Printf –

回答

89

使用這樣的:

String myString = String(n); 

你可以找到更多的例子here

+2

你不需要使用一個字符串對象,Serial.print或println已經轉換它們! –

+0

我正在尋找如何將97轉換爲'a'字符或將65轉換爲'A'字符的方式。我的意思是ASCII碼的字符。我發現這種方式不起作用。 –

+0

@OkiErieRinaldi:你可以使用 - char bar = 97;它會工作。 – Cassio

-2

在第一個例子中,使用了一個經典的C字符串:它只是一個以零(NUL字符)結尾的字符數組。其他示例使用String類,這是一個C++類,除了玩具示例和小型演示外,我將遠離它。它以不易預測的方式泄漏內存,並導致板卡的神祕鎖定。

+1

那麼你的解決方案是什麼? – localhost

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

這草圖使用AVR-GCC其與Arduino的V1.0.5捆綁(int2str函數的大小本身是594個字節)編譯爲1082個字節的代碼。與使用編譯爲2,398字節的String對象的解決方案相比,此實現可以將代碼大小減少1.2 Kb(假定您不需要其他String的對象方法,並且您的編號對signed int類型是嚴格的)。

該函數可以通過寫入適當的彙編代碼進一步優化。

+1

另一種避免DIV的方法是乘以(2^N/10),然後右移N位。所以對於N = 16,x/10〜=(x * 6554)>> 16。無論如何,足夠接近大多數數字。 –

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'並直接增加緩衝區,可以很容易地修改緩衝區的末端。

16

使用包括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) 
9

你只需將其套在這樣一個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