2016-03-27 9 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); 
} 

これはLinuxの端末でvoice_command.py(私が書いたもの)と一緒に動作します。コードがこのような場合、このコードをarduinoにアップロードした直後に、音声認識が「右」または「左」とは異なる単語を理解するまでうまく動作します。音声コマンドが "右"または "左"とは異なる別の文字列をarduinoに送信すると、プログラムは何のエラーもなく動作しますが、この時点以降は "右"または "左"コマンドに応答しなくなります。これを解決するために私はこの変更を行いました。arduino:他の人と一緒に働いていないプログラム

#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); 
} 

しかし、今では「右」と「左」のコマンドも応答していません。どうすればこの問題を解決できますか?

+2

おそらく、Serial.available()ブロックはデータが入ってくると集計されますか?だからループの1回の反復で 'rig'を取得した場合、' else 'ブロックを打ち、 'ht'が入る前に文字列をリセットしますか? – Paul

+0

お返事ありがとうございますが、私はあなたが明確に意味するものをキャッチできませんでした。特に「リグ」と「ht」部品。私はこの問題を解決するために何をすべきか理解していませんでした。私はそれをよく理解するためにそれを少し開くことができますか?私は途中でarduinoで新しいです: –

答えて

1

問題

あなたが持っている問題は、あなたのSerial.available()ブロックのみループの各反復でシリアルバッファから1つのバイトを読んでいるということです。結果として、あなたのサーボが単語"right"を送るとき、シリアルバッファは "正しい"です。 loop()による最初の反復は、kontrolstrの値として"r"を与えます。 elseブロックなし

は、第二のループに、kontrolstrは等、righ次いで、rig次いで、riに設定され、left又はrightが発見された場合にのみリセットされます。これはまた、leftおよびrightの問題が、他の単語が認識された場合には到達しない原因となる。kontrolstrは、例えば、に設定される。 "horse"が、これはkontrolstr"r"で、最初のループで、そうそれは"right"送信するときに、あなたが"horseright"取得、else Withブロックなど

が認識されないので、elseブロックに当たる、と文字列をリセットします。 2番目のループでは、kontrolstr"i"であり、elseブロックに当たって文字列などをリセットし、関連する制御ブロックに到達することはありません。

可能な解決策

ソリューションの開始は、それを処理する前に、全体Serialバッファを読んで、これにif(Serial.available()で始まるブロックを交換することである:これは、バッファ全体を読み込みます

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

最初のループでは、すべてのデータがループの繰り返しの間に送信されている限り、問題は解決されます。ただし、シリアルポートを介してデータを送信するには、ゼロ以外の時間が必要です。したがって、loop()の送信が送信の途中でトリガーされる可能性があります。その場合、シリアルバッファは"rig"のようになります一致する"right"または"left"がリセットされ、次のループで"ht"が返され、再びリセットされます。トリガーは失われます。

もし可能であれば、あなたのサーボがコントロールワードに区切り文字を付けて送るようにするのが最善の解決策だと思います。 \n。サーボが"right\nanother word\nleft\n"を送信した場合、処理する前にすべての単語が入力されるまで待つことができます。あなたのloop()に変更することでこれを行うことができます。

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); 
} 

もちろんを、これはあなたが余分な言葉は、シリアルバッファ(中に蓄積することができるようにしてOKだということを前提とし、バッファが場合でもを充填されなかったため、罰金ですあなたは100msごとに1文字しか読んでいませんでした)。ただし、シリアルバッファがオーバーフローしている場合は、2番目の文字列bufferstringを作成して、シリアルバッファ内の文字列をその文字列に追加してから、ループの各繰り返しで最も古いコマンドを取り出し、

#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

これは私が期待していたよりはるかに良い答えです。このような明確で長い答えに感謝します! –

関連する問題