2016-03-27 6 views
2
#include <Servo.h> 

Servo myservo; // create servo object to control a servo 


int pos = 90; 
String kontrolstr = ""; 
char kontrol; 

void setup() 
{ 
    Serial.begin(9600); 
    myservo.attach(9);// attaches the servo on pin 9 to the servo object 
} 

void loop() 
{ 
    if(Serial.available()) 
    { 
     kontrol=Serial.read(); // it reads from python voice recognition 
     kontrolstr.concat(kontrol); 
    } 
    if(kontrolstr== "right") 
     {pos += 30; 
     kontrol = '0'; 
     kontrolstr = ""; 
     } 
    else if(kontrolstr== "left") 
     {pos -= 30; 
     kontrol= '0'; 
     kontrolstr = ""; 
    } 

    myservo.write(pos); 
    delay(100); 
} 

Es funktioniert mit voice_command.py (was ich schrieb) auf Linux-Terminal. Wenn der Code so ist, direkt nach dem Hochladen dieses Codes auf Arduino, funktioniert es gut, bis die Spracherkennung ein anderes Wort von "rechts" oder "links" versteht. Wenn der Sprachbefehl an Arduino eine andere Zeichenfolge als "rechts" oder "links" sendet, funktioniert das Programm immer noch ohne Fehler, aber nach diesem Punkt beginnt es nicht mehr mit "rechts" oder "links" zu antworten. Um das zu lösen, habe ich das geändert. Ich habe ein ‚anderes‘:arduino: Programm mit sonst funktioniert nicht

#include <Servo.h> 

Servo myservo; // create servo object to control a servo 


int pos = 90; 
String kontrolstr = ""; 
char kontrol; 

void setup() 
{ 
    Serial.begin(9600); 
    myservo.attach(9);// attaches the servo on pin 9 to the servo object 
} 

void loop() 
{ 
    if(Serial.available()) 
    { 
     kontrol=Serial.read(); 
     kontrolstr.concat(kontrol); 
    } 
    if(kontrolstr== "right") 
     {pos += 30; 
     kontrol = '0'; 
     kontrolstr = ""; 
     } 
    else if(kontrolstr== "left") 
     {pos -= 30; 
     kontrol= '0'; 
     kontrolstr = ""; 
    } 
    else {    // I write this to make it work.. 
     kontrol = '0'; 
     kontrolstr = ""; 
    } 

    myservo.write(pos); 
    delay(100); 
} 

aber jetzt ist es nicht zu „rechts“ und „links“ Befehl reagiert. Wie kann ich dieses Problem lösen?

+2

Vermutlich aggregiert der Serial.available() - Block die Daten, wenn sie eingehen? Wenn Sie also in einer Iteration der Schleife 'Rig' erhalten, werden Sie den Block" else "treffen und die Zeichenkette zurückstellen, bevor die' ht' eingeht, richtig? – Paul

+0

Danke für die Antwort, aber ich konnte nicht klar, was Sie meinen. Besonders "Rig" und "HT" Teile. Ich habe nicht verstanden, was ich tun soll, um dieses Problem zu lösen. Kannst du es ein wenig öffnen, damit ich es gut verstehe? Ich bin übrigens neu in arduino :) –

Antwort

1

Das Problem

Das Problem, das Sie haben, ist, dass Ihr Serial.available() Block nur in jeder Iteration der Schleife ein Byte aus dem seriellen Puffer zu lesen. Wenn Ihr Servo das Wort "right" sendet, ist der serielle Puffer daher "richtig". Die erste Iteration durch loop() ergibt "r" als Wert für kontrolstr.

Ohne den else Block auf der zweiten Schleife wird kontrolstr zu ri gesetzt ist, dann rig, dann righ, usw., und wird erst zurückgesetzt, wenn left oder right zu finden sind. Dies führt auch dazu, dass das Problem left und right nicht erreicht wird, wenn ein anderes Wort erkannt wurde - kontrolstr wäre z. "horse", dies nicht erkannt wird, so ist, dann, wenn es sendet "right", erhalten Sie "horseright" usw.

Mit dem else Block auf der ersten Schleife, kontrolstr ist "r", so trifft es den else Block und setzt den String. Auf der zweiten Schleife, kontrolstr ist "i", es trifft den else Block und setzt die Zeichenkette, usw. zurück und erreicht nie den relevanten Steuerblock.

Mögliche Lösungen

Der Beginn der Lösung vor der Verarbeitung der gesamten Serial Puffer zu lesen ist, so ersetzen Sie den Block mit if(Serial.available() zu beginnen:

while(Serial.available()) 
    { 
    kontrol = Serial.read(); 
    kontrolstr.concat(kontrol); 
    } 

den gesamten Puffer Dies wird gelesen in der ersten Schleife, so lange alle Daten zwischen Iterationen der Schleife gesendet wurden, wird Ihr Problem gelöst. Es dauert jedoch nicht null Zeit, um Daten über einen seriellen Port zu senden, daher ist es möglich, dass Ihre loop() Iteration in der Mitte eines Sendevorgangs ausgelöst wird. In diesem Fall könnte der Serial Buffer beispielsweise "rig" sein Match "right" oder "left", wird zurückgesetzt, dann in der nächsten Schleife erhalten Sie "ht", und wieder wird es zurückgesetzt werden - der Trigger wird verpasst.

Wenn möglich, ich denke, die beste Lösung wäre, dass Ihr Servo die Steuerwörter mit einem Trennzeichen zwischen ihnen senden, z. \n. Wenn Ihr Servo "right\nanother word\nleft\n" sendet, können Sie warten, bis ganze Wörter eingehen, bevor Sie sie verarbeiten.Sie können dies tun, indem Sie Ihre loop() zu:

void loop() 
{ 
    kontrolstr = ""; // Reset on each iteration of the loop 
    while(Serial.available()) 
    { 
    kontrol = Serial.read(); 
    // If we reach the delimiter, stop reading from the Serial buffer 
    if (control == '\n') { 
     break; 
    } 
    kontrolstr.concat(kontrol); 
    } 
    if(kontrolstr== "right") { 
    pos += 30; 
    } else if(kontrolstr== "left") { 
    pos -= 30; 
    } 

    myservo.write(pos); 
    delay(100); 
} 

Natürlich setzt dies voraus, dass Sie mit so dass zusätzliche Wörter OK sind in den seriellen Puffer zu akkumulieren (scheint in Ordnung, da der Puffer nicht füllte sich auch dann, wenn Du hast alle 100ms nur 1 Zeichen gelesen. Wenn es jedoch zu einem Überlauf des seriellen Puffers kommt, können Sie eine zweite Zeichenfolge bufferstring erstellen und immer das, was sich im seriellen Puffer befindet, an diese Zeichenfolge anhängen und dann bei jeder Iteration der Schleife den ältesten Befehl herausziehen.

#include <Servo.h> 

Servo myservo; // create servo object to control a servo 

int pos = 90; 
String kontrolstr = ""; 
String bufferstring = ""; 
char kontrol; 

void setup() 
{ 
    Serial.begin(9600); 
    myservo.attach(9);// attaches the servo on pin 9 to the servo object 
} 

void loop() 
{ 
    // Read whatever's in the Serial port into the buffer string 
    while(Serial.available()) 
    { 
    kontrol = Serial.read(); 
    // If we reach the delimiter, stop reading from the Serial buffer 
    bufferstring.concat(kontrol); 
    } 

    // Split the string by the delimiter 
    int delimiter_loc = bufferstring.indexOf('\n'); 
    if (delimiter_loc != -1) { 
    // Get the first delimiter_loc characters (doesn't include the delimiter) 
    kontrolstr = bufferstring.substring(0, delimiter_loc); 

    // Remove all the characters up to and including the delimiter_loc 
    bufferstring.remove(0, delimiter_loc + 1); 
    } 

    if(kontrolstr== "right") { 
    pos += 30; 
    } else if(kontrolstr== "left") { 
    pos -= 30; 
    } 

    // Reset on each iteration of the loop 
    kontrolstr = ""; 

    myservo.write(pos); 
    delay(100); 
} 
+0

Dies ist viel viel bessere Antwort als ich erwartet hatte. Vielen Dank für eine so klare und lange Antwort! –