Arduino: программа с еще не работает

#include <Servo.h>

Servo myservo;  // create servo object to control a servoint 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);
}

Он работает с voice_command.py (который я написал) на терминале Linux. Когда код подобен этому, сразу после загрузки этого кода в arduino он работает хорошо, пока распознавание голоса не поймет другое слово из «правого» или «левого». Когда голосовая команда отправляет в arduino другую строку, отличную от «правая» или «левая», программа по-прежнему работает без каких-либо ошибок, но после этой точки она больше не отвечает на «правую» или «левую» команду. Чтобы решить это, я сделал это изменение. Я положил «еще»:

#include <Servo.h>

Servo myservo;  // create servo object to control a servoint 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() Блок читает только один байт из последовательного буфера в каждой итерации цикла. Как следствие, когда ваш сервопривод отправляет слово "right"последовательный буфер «правильный». Первая итерация loop() дает "r" в качестве значения для kontrolstr,

Без else блок, на второй петле, kontrolstr установлен в ri, затем rig, затем righи т.д., и сбрасывается только тогда, когда left или же right найдены. Это также то, что вызывает проблему left а также right не достигнуто, если другое слово было распознано — kontrolstr было бы установлено, например, "horse", это не распознается, поэтому, когда он отправляет "right", ты получаешь "horseright", так далее.

С else блок, на первом цикле, kontrolstr является "r"так что бьет else блок и сбрасывает строку. На втором цикле 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);
}

Конечно, это предполагает, что вы в порядке, позволяя накапливать дополнительные слова в последовательном буфере (кажется, все в порядке, поскольку буфер не заполнялся, даже когда вы читали только 1 символ каждые 100 мс). Однако если случится так, что последовательный буфер переполнен, то вы можете создать вторую строку bufferstring и всегда добавляйте к этой строке все, что находится в буфере Serial, затем на каждой итерации цикла извлекайте самую старую команду, давая:

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]