Проблемы с задержкой сервопривода

Итак, на прошлой неделе я протестировал стартовый комплект Arduino Uno. У нас есть задача, включая сервопривод. Мне нужно было заставить сервопривод двигаться от 0 до 90 градусов, и предполагалось, что для этого потребуется 4 секунды. Затем обратно с 90 градусов до 0 снова. Мой код такой:

#include <Servo.h>

Servo myservo;
int pos = 0;
void setup() {
  myservo.attach(9);
}
void loop() {
  for (pos = 0; pos <= 90; pos += 1) {
    myservo.write(pos);
    delay(40);
  }
  for (pos = 90; pos >= 0; pos -= 1) {
    delay(13);
  }
}

Как вы видите, задержка должна быть всего 40 и 13 миллисекунд, но она использовала 4 секунды и 1,3 секунды. но т.к. код был неверный, то я не стал переходить на эту задачу. Так что же я сделал не так.

, 👍-1

Обсуждение

90*40мс = 3,6с. 90*13мс=1,17с. Таким образом, у вас есть 3,6 с для первого движения и 1,3 с для второго движения. Пожалуйста, опишите дальше, чем это не соответствует требованиям, раз вы написали, что нужно брать 4s, а вы увидели 4s. Вот что я понял, @chrisl

90 * 40 мс = 3,6 с, но также есть некоторые накладные расходы, поскольку myservo.write(pos); и цикл for также занимает некоторое время для выполнения (также есть прерывания, которые могут добавить некоторые дополнительные задержки). Но я предполагаю, что эти накладные расходы незначительны. Возможно, экзаменатор хотел, чтобы вы это приняли во внимание. Обратите внимание, что даже если бы у вас была задержка (44), вы бы получили только 3,96 с, поэтому у вас будет отставание в 40 мс. Экзаменатору это может не понравиться., @Gerben

Также ваш второй цикл ничего не делает с сервоприводом..., @Majenko


1 ответ


1

Я бы использовал функцию millis(), чтобы настроить время как можно точнее.

Перед началом операций сохраните фактическое значение таймера millis() в переменную time_passed. После завершения операции, в данном случае шага мотора на 1°, подождите, пока не будет достигнута 90-я часть желаемого времени (4 с). Затем вы увеличиваете time_passed на 90-ю часть желаемого времени.

#include <Servo.h>

unsigned long time_passed;
unsigned long timestep = 4000 / 90; // необходимый период для достижения 4 с за 90 шагов
Servo myservo;
int pos = 0;

void setup() {
  myservo.attach(9);
}
void loop() {
  time_passed = millis();
  for (pos = 0; pos <= 90; pos += 1) {
    myservo.write(pos);
    while ( millis() - time_passed < timestep) {
    }
    time_passed = time_passed + timestep; // это было time_passed = millis(); при тестировании, но это должно быть еще точнее. Надеюсь, я не ошибся, так как тестировал только предыдущую версию ;-)

  }

  for (pos = 90; pos >= 0; pos -= 1) {
    myservo.write(pos);
    while ( millis() - time_passed < timestep) {
    }
    time_passed = time_passed + timestep; // это было time_passed = millis(); при тестировании, но это должно быть еще точнее. Надеюсь, я не ошибся, так как тестировал только предыдущую версию ;-)
  }
}
,