Arduino'da int'i string'e dönüştürmek nasıl?


94

Bir int'i nbir dizeye nasıl dönüştürebilirim, böylece onu seri üzerinden gönderdiğimde, bir dizge olarak gönderilsin?

Şimdiye kadar sahip olduğum şey bu:

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 () çalıştırılabilir nesnenizi ~ 1000 bayt büyütür, bu nedenle boyut bir sorunsa onu kullanmak istemeyebilirsiniz." garden.arduino.cc/Main/Printf
Marcello Romani

Yanıtlar:


135

Bunun gibi kullanın:

String myString = String(n);

Burada daha fazla örnek bulabilirsiniz .


5
String nesnesi kullanmanız gerekmez, Serial.print veya println bunları zaten dönüştürür!
Alexis Paques

97'yi 'a' karakterine veya 65'i 'A' karakterine nasıl dönüştüreceğimi arıyorum. ASCII sayı karakter demek istiyorum. Bu yolun işe yaramadığını buldum.
Oki Erie Rinaldi

@OkiErieRinaldi: Kullanabilirsiniz - char bar = 97; Çalışacak.
Cassio

26

içinde bulunan itoa()işlevi kullanınstdlib.h

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


13

Sadece aşağıdaki gibi bir String nesnesinin etrafına sarmanız gerekir:

String numberString = String(n);

Şunları da yapabilirsiniz:

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

Bu, int (işaretli 16 bitlik tamsayıyı) dizeye dönüştürmek için hızı optimize edilmiş bir çözümdür.

Bu uygulama, Arduino için kullanılan 8-bit AVR'nin donanımsal DIV talimatı içermediğinden, bölmeyi kullanmaktan kaçınır; derleyici, bölmeyi zaman alıcı tekrarlayan çıkarmalara çevirir. Bu nedenle en hızlı çözüm, dizeyi oluşturmak için koşullu dalları kullanmaktır.

Dinamik ayırmadan kaçınmak için RAM'de baştan hazırlanan 7 baytlık sabit bir arabellek. Yalnızca 7 bayt olduğu için sabit RAM kullanım maliyeti minimum kabul edilir. Derleyiciye yardımcı olmak için, yürütmeyi hızlandırmak için değişken bildirimine kayıt değiştiricisi ekliyoruz.

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

Bu taslak, Arduino v1.0.5 ile birlikte gelen avr-gcc kullanılarak 1.082 bayt koda derlenmiştir (int2str işlevinin boyutu 594 bayttır). 2.398 bayta derlenen String nesnesini kullanan çözümle karşılaştırıldığında, bu uygulama kod boyutunuzu 1.2 Kb azaltabilir (başka String'in nesne yöntemine ihtiyacınız olmadığı ve sayınızın imzalı int türüne göre kesin olduğu varsayılmıştır).

Bu fonksiyon, uygun montajcı koduyla yazılarak daha da optimize edilebilir.


1
DIV'den kaçınmanın alternatif bir yolu, (2 ^ N / 10) ile çarpmak ve sonra sağa N bit ile kaydırmaktır. Yani N = 16 için, x / 10 ~ = (x * 6554) >> 16. Zaten çoğu rakam için yeterince yakın.
David R Tribble

1

Çözüm çok fazla büyük. Bu basit olanı deneyin. Lütfen 7+ karakterlik bir ara bellek sağlayın, kontrol yapılmadı.

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' dizinini atarsanız ve doğrudan arabelleği artırırsanız, arabelleğin arka ucunu vermek için kolayca değiştirilebilir.



0

Aşağıda, kod olarak çok daha küçük olan ve char * mystring'de sabit bir 7 dizisini (0 sonlandırması dahil) ayıran, kendi oluşturduğu bir myitoa () gösterilmektedir, ki bu genellikle arzu edilir. Değişken uzunlukta bir çıktı dizesine ihtiyaç duyulursa, kodun karakter kaydırmalı olarak oluşturulabileceği açıktır.

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

Bu sadece benim için çalışıyor:

int bpm = 60;
char text[256];
sprintf(text, "Pulso: %d     ", bpm);
//now use text as string
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.