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