String über Bluetooth langsamer als int?

Hallo,
Ich bin dabei ein kleines Roboterauto zu bauen dass ich erstmal per Smartphone über Bluetooth steuern möchte. Dazu habe ich eine kleine App fürs Smartphone gebastelt die sich über BT mit nem Arduino verbindet und einfach nur Befehle für vier Richtungen sendet.
Das funktioniert soweit auch schon.
Als erstes habe ich das ganze aber so programmiert dass die App einen String für jede Richtung sendet. Also für Vorwärts sendet die App "Forward" als Text über BT. Für Links den Text "Left" usw.
Diesen String greife ich mit dem Arduino auf und verarbeite ihn in einfachen if Befehlen. Funktioniert soweit.
Nur habe ich das Problem dass ich einen kurzen delay zwischen dem drücken in der App und dem Ausführen des Arduinos habe. Der delay ist gute 1-2 Sekunden was für die Steuerung des Autos nicht grade förderlich ist.
Jetzt habe ich statt die Befehle als String zu senden das ganze auf einfache Zahlen umgestellt.
Also sendet die App für z.b. Vorwärts jetzt eine 0 als Zahl und der Arduino verarbeitet das ganze nun halt als int und nicht als string.
Damit ist der delay weg und das Auto reagiert direkt wenn ich die entsprechende Taste in der App drücke.

Jemand ne Idee wie der delay bei der Methode mit dem String zustande kommt?
Würde das ganze der übersichtlichkeit wegen schon gerne mit nem String umsetzen aber mit 1-2 Sekunden delay ist das für mich nicht akzeptabel.

Vielleicht fehlt ein Null-Character als Abschluß des Strings, so daß der Empfänger erst mit Timeout abbricht?

Bei int werden vermutlich immer nur 2 Bytes gesendet? Bei Strings jedenfalls unterschiedlich viele Bytes.

Du musst das nur richtig machen. Text immer mit einem Linefeed abschließen. Und dann bis zu diesem Zeichen einlesen statt darauf zu warten bis nichts mehr ankommt.

Natürlich hältst du die problematische Stelle geheim.
Warum auch nicht.....

Ein Null-Character wird nicht mit gesendet.
Und wie man das auf einem Händi erzeugt, ist nochmal eine Sache für sich....

Nee, es ist schon so, dass Serial.readString() ein Zeilenende erwartet, oder es wartet bis zum Timeout.

Hm, dann wird das wohl das Problem sein.
Wie ich das in die App einbaue weiß ich jetzt allerdings auch nicht. Muss ich mal schauen ob das geht.
Die App ist nur mit dem MIT App Inventor gebastelt. Also nix aufwendiges.

Kann ja mal ein Screenshot vom "Code" anhängen.

Und der Code vom Arduino:

#include <SoftwareSerial.h> 
SoftwareSerial BT(10, 11);
String Direction = " ";
//int Direction = 4;
int ENA = 3;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 12;
int ENB = 5;

void setup() 
{   
  Serial.begin(9600); 
  BT.begin(9600); 
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENB, OUTPUT);
  analogWrite(ENA, 125);
  analogWrite(ENB, 125); 
} 
void loop() 
{ 
  if (BT.available()) 
    Direction = BT.readString(); 
  
  if (Direction == "Forward"){ 
    Serial.println("Vorwärts");
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH); 
  } 
  
  else if (Direction == "Back"){ 
    Serial.println("Rückwärts");
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW); 
  }
   
  else if (Direction == "Left"){ 
    Serial.println("Links");
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH); 
  }
   
  else if (Direction == "Right"){ 
    Serial.println("Rechts");
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW); 
  }
   
  else if (Direction == "Stop"){ 
    Serial.println("Stop");
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW); 
  } 
} 

Kenne ich nicht.

Dann wirst du am anderen Ende anfangen müssen und auf readString() verzichten und diesen String händisch zusammen dengeln dürfen.

Wie meinst du das?

Du willst readStringUntil() und nicht readString()

https://www.arduino.cc/reference/de/language/functions/communication/serial/readstringuntil/

Damit kann bis zu einem Endzeichen einlesen und es wird damit sofort abgebrochen

Du solltest verstehen was da zeitlich abläuft. Aus der Doku der Methoden geht das auch hervor. Nicht nur Code schreiben den du nicht verstehst.

Generell sind die vorgefertigten Arduino Methoden einfach zu verwenden, aber haben oft Nachteile was die Flexibilität und Performance angeht. Dinge wie readString() und parseInt() blockieren und sind daher nur eingeschränkt verwendbar. readStringUntil()/readBytesUntil() sind daher viel besser wenn man es nicht alles per Hand macht (womit man die meiste Kontrolle hat). Man kann auch die Timeout Zeit nach unten setzen. Dann wird eher abgebrochen wenn keine Daten mehr ankommen.

1 Like

Danke für den Tipp. Kannte die Funktion noch nicht. Habe es jetzt mal damit probiert und es funktioniert.
Der Befehl vom Smartphone wird sofort vom Arduino ausgeführt.