web-dev-qa-db-ger.com

Wie liest man einen String-Wert mit einem Trennzeichen auf Arduino?

Ich muss Servos von einem Computer aus verwalten. 

Ich muss also Verwaltungsnachrichten vom Computer an Arduino senden. Ich brauche die Anzahl der Servos und die Ecke. Ich denke daran, etwas zu senden: "1; 130" (erstes Servo und Ecke 130, Begrenzer ";"). 

Gibt es bessere Methoden, um dies zu erreichen? 

Hier ist mein Code:

String foo = "";
void setup(){
   Serial.begin(9600);
}

void loop(){
   readSignalFromComp();
}

void readSignalFromComp() {
  if (Serial.available() > 0)
      foo = '';
  while (Serial.available() > 0){
     foo += Serial.read(); 
  }
  if (!foo.equals(""))
    Serial.print(foo);
}

Das geht nicht. Was ist das Problem?

11
yital9
  • Sie können Serial.readString () und Serial.readStringUntil () verwenden, um -Strings aus Serial on arduino zu analysieren
  • Sie können Serial.parseInt () auch verwenden, um Ganzzahlwerte aus seriell zu lesen

Code-Beispiel

int x;
String str;

void loop() 
{
    if(Serial.available() > 0)
    {
        str = Serial.readStringUntil('\n');
        x = Serial.parseInt();
    }
}

Der seriell zu sendende Wert wäre "my string\n5" und das Ergebnis wäre str = "my string" und x = 5

18
Ihab Hajj

Die meisten anderen Antworten sind entweder sehr ausführlich oder sehr allgemein gehalten. Daher dachte ich, ich würde ein Beispiel geben, wie dies mit Ihrem spezifischen Beispiel unter Verwendung der Arduino-Bibliotheken möglich ist:

Sie können die Methode Serial.readStringUntil verwenden, um bis zu Ihrem Trennzeichen vom Port Serial zu lesen.

Verwenden Sie dann toInt , um den String in eine Ganzzahl zu konvertieren.

Also für ein vollständiges Beispiel:

void loop() 
{
    if (Serial.available() > 0)
    {
        // First read the string until the ';' in your example
        // "1;130" this would read the "1" as a String
        String servo_str = Serial.readStringUntil(';');

        // But since we want it as an integer we parse it.
        int servo = servo_str.toInt();

        // We now have "130\n" left in the Serial buffer, so we read that.
        // The end of line character '\n' or '\r\n' is sent over the serial
        // terminal to signify the end of line, so we can read the
        // remaining buffer until we find that.
        String corner_str = Serial.readStringUntil('\n');

        // And again parse that as an int.
        int corner = corner_str.toInt();

        // Do something awesome!
    }
}

Natürlich können wir das ein bisschen vereinfachen:

void loop() 
{
    if (Serial.available() > 0)
    {
        int servo = Serial.readStringUntil(';').toInt();
        int corner = Serial.readStringUntil('\n').toInt();

        // Do something awesome!
    }
}
4
Joakim

Dies ist ein tolles U-Boot, das ich gefunden habe. Das war super hilfreich und ich hoffe es wird auch für Sie sein.

Dies ist die Methode, die das Sub aufruft. 

String xval = getValue(myString, ':', 0);

Das ist das U-Boot!

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]) : "";
}
4
oharkins

Sie müssen einen Lesepuffer erstellen und berechnen, wo Ihre 2 Felder (Servo # und Ecke) beginnen und enden. Dann können Sie sie einlesen und die Zeichen in Ganzzahlen konvertieren, um sie im restlichen Code zu verwenden. So etwas sollte funktionieren (nicht auf Arduino getestet, aber Standard C):

void loop()
        {
            int pos = 0; // position in read buffer
            int servoNumber = 0; // your first field of message
            int corner = 0; // second field of message
            int cornerStartPos = 0; // starting offset of corner in string
            char buffer[32];

            // send data only when you receive data:
            while (Serial.available() > 0)
            {
                // read the incoming byte:
                char inByte = Serial.read();

                // add to our read buffer
                buffer[pos++] = inByte;

                // check for delimiter
                if (itoa(inByte) == ';')
                {
                    cornerStartPos = pos;
                    buffer[pos-1] = 0;
                    servoNumber = atoi(buffer);

                    printf("Servo num: %d", servoNumber);
                }
            }
            else 
            {
                buffer[pos++] = 0; // delimit
                corner = atoi((char*)(buffer+cornerStartPos));

                printf("Corner: %d", corner);
            }
        }
2
Mangist

Es sieht so aus, als müssten Sie nur korrigieren

  foo = '';  >>to>>  foo = "";

  foo += Serial.read();  >>to>>  foo += char(Serial.read());

Ich habe auch etwas ähnliches gemacht ..:

void loop(){
  while (myExp == "") {
    myExp = myReadSerialStr();
    delay(100);
  }
}    

String myReadSerialStr() {
  String str = "";
  while (Serial.available () > 0) {
    str += char(Serial.read ());
  }
  return str;
}
1
Aziz