2016-03-27 31 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 terminalinde voice_command.py (yazdığım) ile çalışır. Kod böyle olduğunda, bu kodu arduino'ya yükledikten hemen sonra, ses tanıma, "sağ" veya "sol" dan farklı bir kelimeyi anlayana kadar iyi çalışır. Ses komutu arduino'ya "sağ" veya "sol" dan farklı bir dizge gönderdiğinde, program hala hatasız çalışır ancak bu noktadan sonra artık "doğru" veya "sol" komutunu yanıtlamaya başlamaz. Bunu çözmek için bu değişikliği yaptım. Ben koymak bir 'başka':arduino: çalışmıyor başka program

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

Ancak artık çok "doğru" ve "sol" komutunu yanıt vermiyor. Bu sorunu nasıl çözebilirim?

+2

Muhtemelen Serial.available() bloğu, veri geldiği gibi toplanıyor mu? Eğer döngünün bir yinelemesinde "teçhizat" alırsanız, "başka" bloğuna vuracaksınız ve "ht" gelmeden önce dizgiyi sıfırlayacaksınız, değil mi? – Paul

+0

Cevabınız için teşekkürler, ama ne demek istediğini net olarak yakalayamadım. Özellikle 'teçhizat' ve 'ht' parçaları. Bu sorunu çözmek için ne yapmam gerektiğini anlamadım. Onu iyi anlamak için biraz açabilir misin? Bu arada arduino'da yeniyim :) –

cevap

1

Sorun

sizin Serial.available() blok sadece döngünün her tekrarında Seri tampon itibaren bir bayt okuma olduğunu Karşılaştığınız sorundur. Sonuç olarak, servo dosyanız "right" kelimesini gönderdiğinde, Seri tampon "doğru" olur. loop() ile yapılan ilk yineleme, kontrolstr için "r" değerini verir. else blok olmadan

, ikinci döngü, kontrolstr vb sonra ri, rig, daha sonra righ e ayarlanır ve left veya right bulunan yalnızca sıfırlanır. Başka bir kelime tanımlanmışsa left ve right sorununa neden olan da budur - kontrolstr, örn. "horse", bu kontrolstr"r" olduğunu ilk döngü, böylece o zaman "right" gönderdiği zaman, sen "horseright" olsun, else bloğu ile vb

tanınmaz, bu yüzden else blok vurur ve dizeyi sıfırlar. İkinci döngüde, kontrolstr"i", else bloğuna vurur ve dizeyi sıfırlar, vb, asla ilgili kontrol bloğuna ulaşmaz.

olası çözümler

çözeltinin başlangıç ​​olarak işleme önce tüm Serial tampon okumak, böylece için if(Serial.available() başlayarak blok değiştirmektir

: Bu, tüm tampon okuyacak

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

ilk döngüde, tüm veriler döngü yinelemeleri arasında gönderildiği sürece sorununuz çözülecektir. Ancak, bir Seri bağlantı noktası üzerinden veri göndermek için sıfır olmayan bir süre alır, bu nedenle loop() yinelemenin bir gönderimin ortasında tetiklenmesi olasıdır, bu durumda Seri arabellek "rig" gibi bir şey olabilir, "right" veya "left" eşleşmesi sıfırlanacak, ardından bir sonraki döngüde "ht" elde edilecek ve tekrar sıfırlanacak - tetikleyici atlanacaktır. Mümkünse, servo sürücünüzün kontrol sözcüklerini aralarında bir sınırlayıcıyla göndermesini sağlamak en iyi çözümün, örneğin; \n. Servonuz "right\nanother word\nleft\n" gönderirse, tüm sözcüklerin işlenmeden önce gelmesini bekleyebilirsiniz.Sen değiştirerek bunu edebilirsiniz loop() için: tampon bile dolduruyor değildi çünkü

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

, bu ekstra kelimeler Seri tampon (birikmesine izin Tamam konum olduğunu varsayar iyi görünüyor Her 100 ms'de sadece 1 karakter okuyordunuz). Ancak, Seri arabellek taşması gerçekleşirse, ikinci bir dize bufferstring oluşturabilir ve her zaman Seri arabelleğinde bulunan her şeyi bu dizeye ekleyebilir, daha sonra döngüdeki her yinelemede en eski komutu çıkartarak aşağıdakileri yapabilirsiniz:

#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

Bu, almayı umduğumdan çok daha iyi bir yanıt. Böyle açık ve uzun bir cevap için çok teşekkürler! –

İlgili konular