Почему задержка более 64 миллисекунд останавливает вращение серводвигателя? Я не использую «Servo.h», вместо этого я просто управляю длиной импульса.

arduino-uno sensors motor servo pwm

Я использовал этот код

int servo = 5;
int angle;

void setup() {

  pinMode(servo, OUTPUT);

}

void loop() {
  
  
  for (angle = 0;angle<180;angle++){
    
    digitalWrite(servo, HIGH);
    delayMicroseconds((angle*(11))+365);
    digitalWrite(servo,LOW);
    delay(65);
  }

  for (angle = 179;angle>0;angle--){
    
    digitalWrite(servo, HIGH);
    delayMicroseconds((angle*(11))+650);
    digitalWrite(servo,LOW);
    delay(65);
  
    
}
}

как вы видите, я установил задержку после определенного шага на 65 миллисекунд, но это не сработает, любая задержка больше 64 миллисекунд не работает, и двигатель просто перестает вращаться.

в чем причина этого??

, 👍0

1 ответ


2

Серводвигателю требуется не только один импульс, чтобы отправить его под определенным углом. Для отслеживания того, каким должен быть угол, требуется постоянный поток импульсов с нужной частотой.

Отправляя один импульс, вы просто намекаете, куда он может отправиться, а затем останавливаетесь. Он никогда не попадет туда, если вы не будете посылать эти импульсы достаточно быстро.

Кроме того, если вы не отправите импульсы, сервопривод перейдет в "спящий режим с низким энергопотреблением". где он не активно управляет выводом, и он будет "гибким"; где вы можете перемещать сервопривод вручную.

Обычно вам нужно отправлять импульсы с частотой около 50 Гц, то есть один импульс каждые 20 мс. Многие сервоприводы будут более снисходительны, но если вы отправите их слишком медленно, они просто не будут знать, что делать.

Если вы хотите самостоятельно обрабатывать импульсы, вам нужно делать это правильно. То есть:

  1. Отправить импульс нужной длины
  2. Задержка на 20 мс минус желаемая длина.
  3. Переходите к 1, пока не будет достигнуто желаемое истекшее время.

Например:

for (angle = 0; angle<180; angle++){
  uint32_t ts = millis();
  while ((millis() - ts) < 100) { // задержка 100 мс
    digitalWrite(servo, HIGH);
    delayMicroseconds((angle * 11) + 650);
    digitalWrite(servo,LOW);
    delayMicroseconds(20000 - ((angle * 11) + 650));
  }
}

Это не будет точно из-за задержки инструкций цикла, но будет достаточно близко.

,