Jak przekonwertować int na string na Arduino?


90

Jak przekonwertować int nna ciąg, aby wysyłany przez numer seryjny był wysyłany jako ciąg?

Oto, co mam do tej pory:

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 () powiększa twój wykonywalny obiekt o ~ 1000 bajtów, więc możesz nie chcieć go używać, jeśli rozmiar jest problemem." plac
— zabaw.arduino.cc/Main/Printf

Odpowiedzi:


131

Użyj w ten sposób:

String myString = String(n);

Więcej przykładów znajdziesz tutaj .


4
Nie musisz już używać obiektu String, Serial.print lub println już je przekonwertuj!
— Alexis Paques

Szukam sposobu, jak zamienić 97 na znak „a” lub 65 na znak „A”. Mam na myśli liczbę ASCII do znaku. Okazało się, że ten sposób nie działa.
— Oki Erie Rinaldi

@OkiErieRinaldi: Możesz użyć - char bar = 97; to będzie działać.
— Cassio,

25

użyj itoa()funkcji zawartej wstdlib.h

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


13

Wystarczy owinąć go wokół obiektu String w następujący sposób:

String numberString = String(n);

Możesz też:

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

Jest to zoptymalizowane pod kątem szybkości rozwiązanie do konwersji int (16-bitowej liczby całkowitej ze znakiem) na łańcuch.

Ta implementacja unika używania dzielenia, ponieważ 8-bitowy AVR używany dla Arduino nie ma sprzętowej instrukcji DIV, kompilator tłumaczy podział na czasochłonne powtarzalne odejmowania. Dlatego najszybszym rozwiązaniem jest użycie gałęzi warunkowych do zbudowania łańcucha.

Stały bufor 7 bajtów przygotowany od początku w pamięci RAM, aby uniknąć dynamicznej alokacji. Ponieważ ma tylko 7 bajtów, koszt stałego użycia pamięci RAM jest uważany za minimalny. Aby pomóc kompilatorowi, dodajemy modyfikator rejestru do deklaracji zmiennej, aby przyspieszyć wykonywanie.

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

Ten szkic jest kompilowany do 1082 bajtów kodu przy użyciu avr-gcc, który jest dołączony do Arduino w wersji 1.0.5 (rozmiar samej funkcji int2str wynosi 594 bajty). W porównaniu z rozwiązaniem wykorzystującym obiekt String, który został skompilowany do 2398 bajtów, ta implementacja może zmniejszyć rozmiar kodu o 1,2 Kb (zakładając, że nie potrzebujesz innej metody obiektowej String, a liczba jest ściśle związana z typem int ze znakiem).

Tę funkcję można dodatkowo zoptymalizować, pisząc ją w odpowiednim kodzie asemblera.


1
Alternatywnym podejściem do uniknięcia DIV jest pomnożenie przez (2 ^ N / 10), a następnie przesunięcie w prawo o N bitów. Więc dla N = 16, x / 10 ~ = (x * 6554) >> 16. W każdym razie wystarczająco blisko dla większości cyfr.
— David R Tribble

1

Rozwiązanie jest o wiele za duże. Spróbuj tego prostego. Proszę podać bufor znaków 7+, bez sprawdzania.

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

Można go łatwo zmodyfikować, aby oddać koniec bufora, jeśli odrzucisz indeks „l” i bezpośrednio zwiększysz bufor.



0

Poniżej znajduje się własna skomponowana myitoa (), która ma znacznie mniejszy kod i rezerwuje STAŁĄ tablicę 7 (łącznie z zakończeniem 0) w char * mystring, co jest często pożądane. Jest oczywiste, że zamiast tego można zbudować kod za pomocą przesunięcia znaków, jeśli potrzebny jest łańcuch wyjściowy o zmiennej długości.

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

To po prostu działa dla mnie:

int bpm = 60;
char text[256];
sprintf(text, "Pulso: %d     ", bpm);
//now use text as string
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.