Почему loop() останавливается?

Я хочу перемещать свой серводвигатель (SM-S2309S) между произвольными углами. Для этого я использовал этот простой код:

#include <Servo.h>
Servo servoMain; // Определяем наш сервопривод

// SM-S2309S угловая скорость
float speed = 0.12/60;

void move(int from, int to)
{
  // инициируем переход к новому углу
  servoMain.write(to);
  // ждем, пока движение действительно произойдет под фактическим углом, чтобы пройти
  delay(1000 * speed * int(from-to));
}

void setup()
{
   servoMain.attach(10); // сервопривод на цифровом выводе 10
   Serial.begin(115200);
   // для начала переместиться в центр
   servoMain.write(90);
   delay(1000);
}

void loop()
{
  // предыдущий угол, изначально установленный как центр (согласно вызову setup())
  static int oldangle = 90;
  // очевидно безопасный диапазон от 15 до 165 градусов
  int newangle = random(15,165);
  Serial.println(newangle);
  move(oldangle,newangle);
  oldangle = newangle;
}

Он начинается с размещения руки в центре (в функции setup()), а затем должен сгенерировать случайное число (новый угол, к которому нужно перейти) в цикле.

Я получаю исходное положение, затем два хода (против часовой стрелки, затем по часовой стрелке). Вывод на последовательной консоли показывает 22 и 64, что соответствует двум перемещениям.

Затем все останавливается. На консоли нет сообщения об ошибке (я не ожидаю, что оно будет, но я не уверен, что может быть какая-либо обратная связь от Arduino, будучи полным новичком ). Что может быть причиной этой остановки после двух успешных циклов?

, 👍1

Обсуждение

ОСТАНАВЛИВАЕТСЯ или РАБОТАЕТ, но ничего не происходит?, @Dat Ha

@DatHa: извините, я не очень понимаю ваш вопрос - должна ли быть обратная связь, информирующая меня о том, работает ли программа по-прежнему или остановилась / аварийно завершилась? Я увидел два случайных значения угла, выводимых на консоль (связанные с двумя движениями серводвигателя), и больше ничего. Как я могу проверить, работает ли программа до сих пор или она потерпела крах (я полагаю, она должна по крайней мере выводить новые случайные углы, если она все еще работает)., @WoJ

мигать светодиодом в фоновом режиме, @Dat Ha

@DatHa: хорошо, большое спасибо за подсказку. Я посмотрю, как сделать так, чтобы светодиод мигал независимо от основного loop() (полагаю, что это то, что вы имели в виду, иначе вывода новых углов на консоль было бы достаточно, независимо от движений сервопривода или нет), @WoJ


1 ответ


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

5

Просто небольшая ошибка! Ничего страшного :D

В функции перемещения

void move(int from, int to) { // инициируем переход к новому углу servoMain.write(к); // ждем, пока движение действительно произойдет под фактическим углом, чтобы пройти delay(1000 * скорость * int(от-до));

предположим, что переданы значения 20, 35, тогда последняя строка будет 1000*скорость*(-15). Это отрицательное значение, поэтому функция задержки Arduino преобразует знаковый бит в очень большое беззнаковое число.

Все, что вам нужно сделать, это взять величину от - до, т.е. |от - до | вызвав функцию abs().

ваша функция перемещения будет выглядеть следующим образом:

void move(int from, int to) { // инициируем переход к новому углу servoMain.write(к); // ждем, пока движение действительно произойдет под фактическим углом, чтобы пройти delay(1000 * скорость * абс(целое(от-до)));

Просто измените свою функцию перемещения или скопируйте мою, и у вас не возникнет проблем!

,

Ах! Спасибо! Я использовал int(), когда на самом деле имел в виду abs(), чтобы точно обрабатывать случай, который вы упомянули., @WoJ

Хахаха Удовольствие мое!, @Manav

«Функция задержки ардуино зависает, так как не допускает отрицательный параметр» — это абсурдная чушь. То есть это неправильно, неправильно, неправильно. Параметр delay() представляет собой беззнаковое длинное значение, которое никогда не бывает отрицательным. Когда (как в вашем примере) «от-до» равно -15, требуемая задержка составляет около 2147483618 мс или около 3,5 недель. Таким образом, delay() не зависает, он просто делает то, что ему было сказано., @James Waldby - jwpat7

да, это на уровне байтов, но для конечного пользователя 15-секундная задержка должна закончиться через 15 секунд, но это не так! Поэтому отрицательное число - это то, что вызывает проблему: D, @Manav