Ich habe eine einfache mobile Anwendung erstellt, um LED_ON oder LED_OFF zu senden, wenn auf eine Schaltfläche geklickt wird. Im folgenden Code wird die While-Schleife während der Ausführung nicht vollständig abgeschlossen, aber der Controller geht zur void-Schleife () und fährt von dort fort.
char command;
String my_final="LED_OFF";
#define led 9
void setup(){
Serial.begin(9600);
pinMode(led, OUTPUT);
Serial.println("ready");
}
void loop(){
if(Serial.available() > 0){
my_final = "";
while(Serial.available() > 0){
command = (byte)Serial.read();
my_final += command;
Serial.println("test");
}
Serial.println(my_final);
}
if(my_final == "LED_ON"){
Serial.println(my_final);
analogWrite(led, 255);
my_final == "LED_ON";
}
if(my_final == "LED_OFF"){
Serial.println(my_final);
analogWrite(led, 0);
my_final == "LED_OFF";
}
}
Das Hauptproblem tritt auf, my_final=""
da ich dies tun muss, um neue Eingaben vom Bluetooth zu akzeptieren. Ich kann einfach keinen Weg finden, dieses Problem zu umgehen.
BEARBEITEN
Das bekomme ich im seriellen Monitor. test L test E test D test _ test O test N
.
Bei der seriellen Kommunikation werden Daten byteweise übertragen. Ihr Code ist schnell genug, um ein Byte zu lesen und zu verarbeiten, bevor das nächste empfangen wird.
Es gibt viele mögliche Lösungen dafür, und die Verwendung von Verzögerungen ist keine gute.
Sie könnten am Ende jedes Befehls ein Markierungszeichen senden, z . B. LED_ON!
. Dann wissen Sie, dass Sie Ihrem Array weitere Zeichen hinzufügen müssen, bis Sie ein Ausrufezeichen sehen. Ein häufiger Kandidat für eine Markierung ist das Zeilenumbruchzeichen.
Eine andere Lösung besteht darin sicherzustellen, dass alle Befehle die gleiche Länge haben (z. B. 6 Bytes). Dann könnten Sie einfach warten, bis Sie so viele Zeichen erhalten
if(Serial.available() >= 6) ...
Beachten Sie, dass Sie bei der zweiten Lösung Befehle nicht korrekt empfangen können, wenn Sie ein einzelnes Byte verlieren, bis Sie erneut synchronisieren. Um erneut zu synchronisieren, könnten Sie beispielsweise den Inhalt von Serial
nach einem Timeout verwerfen, wenn ein unvollständiger Befehl zu lange dort sitzt.
@9600 Baudrate, Sie empfangen Daten mit 10 Bit pro Millisekunde. Ein Zeichen besteht aus 8 Bits + Start- und Stoppbits in einem Frame. Sie lesen den Puffer schneller als er. Eine einfache Lösung wäre also, eine Verzögerung von > 1 ms oder so nach dem seriellen Lesen () in die Schleife einzufügen.
delay(1)
nach dem read()
when pingenSerial.available() == 0
Das Puffern bis zum Zeilenvorschub könnte so aussehen (mein Arduino-Code ist etwas eingerostet, also bitte verzeihen Sie einfache Fehler - der Algorithmus sollte stimmen):
finished = false;
command = "";
while (!finished) {
if (Serial.available() > 0) {
c = (byte)Serial.read();
if (c == '\n') {
finished = true;
}
else {
command += c;
}
}
}
Diese Schleife liest einfach weiter Zeichen und fügt diese Zeichen dem Variablenbefehl hinzu.
Dies setzt voraus, dass die Kommunikationsverbindung perfekt ist, da sie keine Zeichen fallen lässt oder verstümmelt. Um dies robuster zu machen, könnten Sie eine Überprüfung vornehmen, um sicherzustellen, dass die Zeit zum Empfangen des Befehls nicht zu lang ist.
Vielleicht möchten Sie auch auf jeden Befehl entweder mit einer Bestätigung oder einem Huh antworten? (nack) Antwort, die dem Server mitteilt, was vor sich geht.
Viel Spaß beim Machen!
Was passiert, wenn der eingehende Datenstrom so aussieht:
LE
..Td.. D_O
..Td.. N
?
Td ist eine zufällige kleine Verzögerung.
Wenn Ihr while(Serial.available() > 0){
schneller als Td ist, haben Sie nur Reset my_final = "";
mit LE
drin. Das heißt, als nächstes erhalten Sie D_O
und setzen es dann wieder zurück.
\n
, aber Sie müssen trotzdem abfragen Serial.available()
, also müssen Sie etwas herausfinden.
Dmitri Grigorjew
while
Schleife verlässt, wobei die BedingungSerial.available()
immer noch wahr ist?Ganesha Vicky
test L test E test D test _ test O test N
Dmitri Grigorjew
while
Schleife gesprungen ist, was mit einem seriellen Monitor nicht zu sehen ist.AaronD
my_final == "LED_ON";
soll tun? (am Ende desif(my_final == "LED_ON"){}
Blocks, und ebenso fürOFF
)Benutzer253751
Ganesha Vicky