Почему 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, будучи полным новичком ). Что может быть причиной этой остановки после двух успешных циклов?
@WoJ, 👍1
Обсуждение1 ответ
Лучший ответ:
Просто небольшая ошибка! Ничего страшного :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
- Бесполезная проводка коробки и код
- Почему сервопривод вращается на 360 градусов?
- Как использовать фотодиод для arduino?
- Как повторить код
- Почему я не могу контролировать скорость двигателя? (М1 и Е1)
- boxservo работает вопреки коду
- Создание активного заднего крыла на радиоуправляемой машине
- Печать string and integer LCD
ОСТАНАВЛИВАЕТСЯ или РАБОТАЕТ, но ничего не происходит?, @Dat Ha
@DatHa: извините, я не очень понимаю ваш вопрос - должна ли быть обратная связь, информирующая меня о том, работает ли программа по-прежнему или остановилась / аварийно завершилась? Я увидел два случайных значения угла, выводимых на консоль (связанные с двумя движениями серводвигателя), и больше ничего. Как я могу проверить, работает ли программа до сих пор или она потерпела крах (я полагаю, она должна по крайней мере выводить новые случайные углы, если она все еще работает)., @WoJ
мигать светодиодом в фоновом режиме, @Dat Ha
@DatHa: хорошо, большое спасибо за подсказку. Я посмотрю, как сделать так, чтобы светодиод мигал независимо от основного
loop()
(полагаю, что это то, что вы имели в виду, иначе вывода новых углов на консоль было бы достаточно, независимо от движений сервопривода или нет), @WoJ