Zeichenkette aus mehreren Variablen kombinieren

Hallo,

ich möchte gerne eine Variable (integer) mit einem Text gemeinsam in den seriellen Monitor schreiben.

    int wert_dht11 = DHT11.temperature;
    
    Serial.println("Temperatur-Station 1: ", wert_dht11);

Bekomme ne Fehlermeldung. Liegt das an den unterschiedlichen Datentypen? Muss ich aus dem integer zuerst nen string machen? Wenn ja, wie funktioniert das?

Die Serial.println Funktion hat nur 2 übergabe Werte, die Ausgabe und die Formatierung

Einfache Variante:

int value1 = 1;
int value2 = 10;
Serial.print("Value 1:");
Serial.print(value1);
Serial.print(" Value 2");
Serial.println(value2);

Professionelle Variante:

char buf[100];
int value1 = 1;
int value2 = 10;

sprintf(buf, "Dies ist mein String mit Wert1: %d und Wert2: %d", value1, value2);

Serial.println(buf);

Mehr dazu unter: http://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm

Wenn ich die einfache Variante von dir mache, sprich:

Serial.print("Value 1:");
Serial.print(value1);

Das Problem ist, ich brauch beide Variablen bzw. Text und Variable in einer Zeichenkette. Mit deiner Variante sind das doch 2 verschiedene Zeichenketten oder?

Hallo,

sein buf vom 2. Bsp. ist quasi eine Zeichenkette. Genau genommen ein char array. Schau dir die sprintf Funktion nochmal an.

Wenn es nur um die zusammengesetzte Darstellung geht, dafür gibts auch die Streaming Lib. http://arduiniana.org/libraries/streaming/

Was heißt Zeichenkette für dich ?

Wenn du es im Seriellen Monitor betrachtest ist es nur eine Zeichenkette die nicht mit einer Newline abgeschlossen ist. Erst wenn du das ganze mit println abschließt. Es sind aber Zwei übertragungen.

Verwende die zweite Variante, die macht genau das was du suchst. Alle Zeichen mit % sind Platzhalter und das d steht für eine ganze Zahl. Danach kannst du hinter den String so wie in deinem Beispiel die Variablen einfach anhängen.

Mit %3d kann man z.B. auch erzingen das eine Zahl immer mit 3 Stellen angezeigt wird.
z.B:

value = 5

Ausgabe = 005

    char buf[100];
    int chk = DHT11.read(dht11_pin);

    int wert_dht11 = DHT11.temperature;

    sprintf(buf,"Temperatur-Station-1: ",wert_dht11);

    Serial.println(buf);

bekomme als Ausgabe trotzdem nur Temperatur-Station-1 und nicht die integer-variable.

Was mache ich falsch?

as Problem ist, ich brauch beide Variablen bzw. Text und Variable in einer Zeichenkette

Du hast gesagt dass du es auf dem seriellen Monitor anzeigen willst. Das ist das nicht nötig und macht nur mehr Arbeit und kostet mehr Speicher. Für andere Anwendungen braucht man es dagegen wirklich in einem String.

Es gibt auch noch PString: http://arduiniana.org/libraries/pstring/ Damit kann man mit print()/println() mit char Arrays verwenden. Und die Streaming Lib aus #3 geht auch damit

bekomme als Ausgabe trotzdem nur Temperatur-Station-1 und nicht die integer-variable.

Was mache ich falsch?

printf() nicht verstanden. Hast du gedacht %d steht da zum Spaß da? Das ist der Platzhalter für die Variable

Funktioniert jetzt. Ja hab das %d übersehen :slight_smile:

Jetzt möchte ich gerne an einem anderen Arduino aus der Zeichenkette den String vorm 1. Komma auslesen. Habe dazu die Funktion getValue gefunden:

void setup() {
  Serial.begin(9600);
}


void loop() {
  if (Serial.available() > 0) {
    delay(100);
    while (Serial.available() > 0)
    {
      String msg = Serial.read();
      String arduino = getValue(msg, ',', 0);
      String station = getValue(msg, ',', 1);


      Serial.println(arduino);


    }

  }

}


String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = { 0, -1  };
  int maxIndex = data.length() - 1;
  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Fehlermeldung: Conversion from ‘int’ to ‘String’ is ambiguous"

Was mache ich genau falsch?

Gerade hier reicht eben print()/println() völlig aus, wenn du nicht externe Bibliotheken wie VirtualWire verwenden musst

Zum Einlesen: http://forum.arduino.cc/index.php?topic=359203.msg2486412#msg2486412

Kannst du auch erst mal mit dem Serial Monitor testen

Alternativ, wenn man weiß dass immer zwei Integer gesendet werden kann man das Parsen (in parseSerial()) auch ganz einfach so machen:

int value1 = atoi(strtok(serialBuffer, ","));
int value2 = atoi(strtok(NULL, ","));

Der Code da ist eher wenn die Anzahl der Zahlen unbekannt ist. Deshalb die while Schleife und das Array. Kommt auf die Anwendung an.

Und wenn ich schon sehe dass String Objekte per Value übergeben werden....

du hast über 9000 Beiträge hier, d.h. es muss dir doch Spaß machen zu helfen? Wieso muss man dann so abgehoben antworten: "Und wenn ich schon sehe dass String Objekte per Value übergeben werden...."

Wenn ich es wüsste, würd ichs doch anders machen oder?

Mein Verständis mit NULL hintergrundwissen/basics:

Ich habe ne Variable (integer), da steht ein Messwert drin. Den Integer wandel ich in einen String um, damit ich diesen gemeinsam mit einem weiteren String ("Temperatur-Station-1") in die serielle Schnittstelle schreiben kann. Jetzt habe ich quasi einen langen String, den ich in den seriellen Monitor schreibe, um von dort aus vom 2.Arduino zuzugreifen. Im 2. Arduino lese ich über "String msg = Serial.read(); " die serielle Schnittstelle aus -> und genau in dieser Zeile kommt die Fehlermeldung mit dem Converten von 'int' nach 'String'.. Aber in der seriellen Schnittstelle steht doch ein String oder?

Der Fehler kommt weil die Datentypen nicht kompatibel sind! Für Arduino String nach int gibt es toInt(). Siehe Doku: https://www.arduino.cc/en/Reference/StringObject

Serial.read() liefert übrigens nur ein Zeichen. Keinen ganzen String. Das ist also nicht korrekt. Für blockierendes Einlesen bis zu einem Endzeichen gibt es readStringUntil(): https://www.arduino.cc/en/Reference/StreamReadStringUntil (und als Endzeichen ein Linefeed nehmen)

Generell musst du die Arduino String Objekte von C Strings unterscheiden. Letztere sind Null-terminierte char Arrays. String Objekte sind auf den ersten Blick etwas einfacher zu handhaben, aber kommen mit gewaltigen Limitierungen. Gerade Parsen und Konvertieren ist problematisch, weil die Methoden dafür größtenteils fehlen oder kompliziert zu verwenden sind. Mit C Strings kann man dagegen Jahrzehnte alte Standard C Funktionen verwenden. Diese haben etwas kryptische Namen, aber man kann alles damit machen. Du siehst auch dass die Verwendung von subString() hier sehr kompliziert ist

Der Sketch in dem Link oben liest erst mal die Zeichen in ein char Array ein. Wenn das das Endzeichen (Linefeed) da ist wird gemeldet dass man fertig ist. Das Parsen geschieht dann in zwei Schritten: 1.) strtok() (string tokenizer) liefert immer einen Zeiger auf das nächste Token (ein Teil-String) 2.) atoi() (ascii to integer) konvertiert diesen Teil-String in einen Integer

Wie gesagt, wenn man weiß dass man N Zahlen bekommt, sind es N Zeilen Code! Bei einer unbekannten Anzahl lässt man strtok() einfach solange in einer while-Schleife laufen bis am Ende NULL kommt. Man muss sich nie mit genauen Indizes herumärgern! Außerdem wird der String in situ bearbeitet, d.h. er wird selbst verändert und es wird kein zusätzlicher Speicher belegt. Bei String Objekten und substring() bekommst du dagegen jedesmal neue Objekte zurück

Außerdem ist der Code nicht-blockierend. Das heißt man kann währen des Einlesens noch andere Dinge tun, statt auf die Daten zu warten.