C++ arduino:程序与其他程序不工作 #包括 伺服myservo;//创建伺服对象以控制伺服 int pos=90; 字符串kontrolstr=“”; 焦康特罗; 无效设置() { Serial.begin(9600); myservo.attach(9);//将针脚9上的伺服连接到伺服对象 } void循环() { if(Serial.available()) { kontrol=Serial.read();//它从python语音识别中读取 康特罗尔·康卡特(康特罗尔); } 如果(kontrolstr==“右”) {pos+=30; kontrol='0'; kontrolstr=“”; } else if(kontrolstr==“左”) {pos-=30; kontrol='0'; kontrolstr=“”; } myservo.write(pos); 延迟(100); }

C++ arduino:程序与其他程序不工作 #包括 伺服myservo;//创建伺服对象以控制伺服 int pos=90; 字符串kontrolstr=“”; 焦康特罗; 无效设置() { Serial.begin(9600); myservo.attach(9);//将针脚9上的伺服连接到伺服对象 } void循环() { if(Serial.available()) { kontrol=Serial.read();//它从python语音识别中读取 康特罗尔·康卡特(康特罗尔); } 如果(kontrolstr==“右”) {pos+=30; kontrol='0'; kontrolstr=“”; } else if(kontrolstr==“左”) {pos-=30; kontrol='0'; kontrolstr=“”; } myservo.write(pos); 延迟(100); },c++,if-statement,arduino,servo,C++,If Statement,Arduino,Servo,它在linux终端上与voice_command.py(我编写的)一起工作。当代码是这样的时候,在将代码上传到arduino之后,它工作得很好,直到语音识别理解“right”或“left”的不同单词。当语音命令向arduino发送另一个不同于“right”或“left”的字符串时,程序仍然可以正常工作,但在此之后,它不再响应“right”或“left”命令。为了解决这个问题,我做了这个改变。我放了一个“else”: #include <Servo.h> Servo myservo

它在linux终端上与voice_command.py(我编写的)一起工作。当代码是这样的时候,在将代码上传到arduino之后,它工作得很好,直到语音识别理解“right”或“left”的不同单词。当语音命令向arduino发送另一个不同于“right”或“left”的字符串时,程序仍然可以正常工作,但在此之后,它不再响应“right”或“left”命令。为了解决这个问题,我做了这个改变。我放了一个“else”:

#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);
}
#包括
伺服myservo;//创建伺服对象以控制伺服
int pos=90;
字符串kontrolstr=“”;
焦康特罗;
无效设置()
{ 
Serial.begin(9600);
myservo.attach(9);//将针脚9上的伺服连接到伺服对象
} 
void循环()
{
if(Serial.available())
{
kontrol=Serial.read();
康特罗尔·康卡特(康特罗尔);
}
如果(kontrolstr==“右”)
{pos+=30;
kontrol='0';
kontrolstr=“”;
}
else if(kontrolstr==“左”)
{pos-=30;
kontrol='0';
kontrolstr=“”;
}
否则我写这篇文章就是为了让它发挥作用。。
kontrol='0';
kontrolstr=“”;
}
myservo.write(pos);
延迟(100);
}

但是,现在它也不响应“right”和“left”命令。如何解决这个问题?

问题

您遇到的问题是,
Serial.available()
块在循环的每次迭代中仅从串行缓冲区读取一个字节。因此,当伺服系统发送单词
“right”
时,串行缓冲区为“right”。通过
loop()
的第一次迭代将
“r”
作为
kontrolstr
的值

在没有
else
块的情况下,在第二个循环中,
kontrolstr
被设置为
ri
,然后
rig
,然后
righ
等,并且只有在找到
left
right
时才会重置。这也是导致如果另一个单词被识别,
left
right
无法到达的原因-
kontrolstr
会被设置为,例如,
“horse”
,这是无法识别的,因此当它发送
“right”
,您会得到
“horserright”
,等等

对于
else
块,在第一个循环中,
kontrolstr
“r”
,因此它点击
else
块,并重置字符串。在第二个循环中,
kontrolstr
“i”
,它点击
else
块并重置字符串等,但从未到达相关控制块

可能的解决方案

解决方案的出发点是在处理前读取整个
串行
缓冲区,因此将以
if(Serial.available()
开头的块替换为:

#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);
}
while(Serial.available())
  {
    kontrol = Serial.read();
    kontrolstr.concat(kontrol);
  }
这将在第一个循环中读取整个缓冲区,因此只要在循环的迭代之间发送了所有数据,您的问题就会得到解决。但是,通过串行端口发送数据需要非零的时间,因此您的
循环()可能在发送的中间迭代触发器,在这种情况下,串行缓冲器可能是类似于“代码>”RIG“<代码> >,它不匹配<代码>“右”/代码>或<代码>“左”<代码>,将被重置,然后在下一个循环中,将得到<代码>“HT”<代码>,并且它将被重置,触发器将丢失。

如果可能的话,我认为最好的解决方案是让你的伺服发送控制字,并在它们之间加一个分隔符,例如
\n
。如果你的伺服发送
“right\n另一个字\nleft\n”
,那么你可以在处理它们之前等待整个字的输入。你可以通过将
循环()
更改为:

#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);
}
while(Serial.available())
  {
    kontrol = Serial.read();
    kontrolstr.concat(kontrol);
  }
当然,这假设您可以允许在串行缓冲区中累积额外的字(因为即使您每100ms只读取1个字符,缓冲区也没有填满,所以看起来很好)。但是,如果串行缓冲区确实溢出,则可以创建第二个字符串
bufferstring
,并始终将串行缓冲区中的任何内容附加到该字符串,然后在循环的每次迭代中,拉出最旧的命令,给出:

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);
}
#包括
伺服myservo;//创建伺服对象以控制伺服
int pos=90;
字符串kontrolstr=“”;
字符串缓冲字符串=”;
焦康特罗;
无效设置()
{ 
Serial.begin(9600);
myservo.attach(9);//将针脚9上的伺服连接到伺服对象
} 
void循环()
{
//将串行端口中的任何内容读入缓冲字符串
while(Serial.available())
{
kontrol=Serial.read();
//如果到达分隔符,停止从串行缓冲区读取
bufferstring.concat(kontrol);
}
//按分隔符拆分字符串
int delimiter_loc=bufferstring.indexOf('\n');
如果(分隔符_loc!=-1){
//获取第一个分隔符\u loc字符(不包括分隔符)
kontrolstr=bufferstring.substring(0,分隔符_loc);
//删除所有字符,包括分隔符_loc
删除(0,分隔符+1);
}
如果(kontrolstr==“右”){
pos+=30;
}else if(kontrolstr==“左”){
pos-=30;
}
//在循环的每次迭代中重置