Как я могу остановить цикл при использовании сервопривода с клавишным вводом?

Как я могу остановить следующий код с помощью ключа?

По сути, код должен запускать сервопривод в цикле, если нажимается "t", и останавливать цикл, если нажата "s".

#include <Servo.h>

Servo myservo;  // создаем сервообъект для управления сервоприводом
// на большинстве плат можно создать двенадцать сервообъектов

int pos = 0;    // переменная для хранения положения сервопривода
int servodata;

void setup() {
  myservo.attach(8);  // присоединяем сервопривод к контакту 9 к объекту сервопривода

  Serial.begin(9600);

}

void loop() {
  if (Serial.available()>0){
    servodata = Serial.read();
    while (servodata == 't'){
           for (pos = 0; pos <= 180; pos += 1) { // переход от 0 градусов к 180 градусам
    // с шагом в 1 градус
       myservo.write(pos);              // сообщаем сервоприводу перейти в позицию в переменной 'pos'
       delay(3);                       // ждем 15 мс, пока сервопривод не достигнет позиции
  }
    for (pos = 180; pos >= 0; pos -= 1) { // переход от 180 градусов к 0 градусам
       myservo.write(pos);              // сообщаем сервоприводу перейти в позицию в переменной 'pos'
       delay(3);                       // ждем 15 мс, пока сервопривод не достигнет позиции
    }
    }
  }
  while (servodata == 's'){
    break;
  }
}

спасибо за помощь.

, 👍0

Обсуждение

В основном: не используйте блокировку для циклов и задержек. Задержки просто заняты ожиданием. Посмотрите на неблокирующий стиль кодирования, как показано в примере BlinkWithoutDelay, который поставляется с Arduino IDE. Объяснено по всему интернету., @chrisl

разделите значение servodata и серводвижение... используйте переменную flag... например, назовите флаг go... если go равно true, то запустите мотор ( if (go ) { ) ... прочитать значение из серийного номера и соответственно установить go ... таким образом, код сервопривода не находится внутри цикла if серийный, @jsotola

не могли бы вы опубликовать и пример? Спасибо, @Andy Andy

зачем вам нужен цикл for для позиционирования сервопривода?, @jsotola


1 ответ


Лучший ответ:

1

Вот быстрое и грязное решение, где каждая итерация loop() соответствует одному циклу «начать подметание»/«остановить подметание»:

  • дождитесь команды «старт»
  • затем двигайтесь вперед и назад в бесконечном цикле
  • остановиться в любой момент, если вы получили команду «стоп»
void loop() {
    // Дождаться команды «старт».
    while (Serial.read() != 't')
        continue;

    // Неоднократно прокручивать вперед и назад.
    for (;;) {
        for (int pos = 0; pos <= 180; pos += 1) {
            myservo.write(pos);
            delay(3);
            if (Serial.read() == 's') // проверка команды 'stop'
                return;
        }
        for (pos = 180; pos >= 0; pos -= 1) {
            myservo.write(pos);
            delay(3);
            if (Serial.read() == 's') // проверка команды 'stop'
                return;
        }
    }
}

Обратите внимание, что у этого подхода есть несколько недостатков:

  1. Поскольку это блокирующий код, вы не сможете легко расширить программу, чтобы она выполняла другие вещи.
  2. Прогон всегда начинается с позиции 0, а не возобновляется. с позиции, которая была текущей при последней команде «стоп».

Если вам нужно что-то более сложное, обратитесь к неблокирующему подход, основанный на конечном автомате (см. комментарий). Обратите внимание, что вы можете обойтись без delay(3);, так как это довольно короткая задержка, но вам придется разбивать развертки на один шаг в loop() итерация.

Я предлагаю вам попробовать подход FSM: прочитайте руководство, на которое я ссылаюсь. чтобы, то попытаться реализовать его. Если вы не можете заставить его работать, вы можете всегда размещайте здесь еще один вопрос.

,