VIDEO  
Видео результата урока
Сервопривод позволяет поворачивать вал двигателя в диапазоне от 0 до 180 градусов. Его часто используют в различных моделях, для поворота рулей. В последнее время их используют в сочленениях роботизированных механизмов. Сервопривод управляется импульсными сигналами (PWM, или ШИМ –сигналами): 
 
Минимальная длительность импульса соответствует углу 0, а максимальная – углу 180 градусов. Но эти значения различаются у различных производителей сервоприводов, а порой меняются и у одинаковых моделей. У наиболее распространённых моделей длительность импульса 544ms соответствует углу 0, а значение 2400ms углу 180 градусов. Но для более точного управления сервоприводами приходится подбирать точные значения минимальной и максимальной длительности импульса. В данном занятии разберём несколько скетчей, которые упрощают подбор этих параметров сервопривода. 
Для тестирования сервопривода соберите следующую схему: 
 
Через монитор порта вводятся цифровые команды. Команда состоит из двух чисел: первое – номер команды, через пробел, второе – значение нужной величины. 
• Команда 1 – установить минимальную длительность в миллисекундах соответствующую углу 0 градусов. Пример: 1 544. 
• Команда 2 – установить максимальную длительность в миллисекундах соответствующую углу 180 градусов. Пример: 1 2400. 
Для выполнения серии из нескольких поворотов устанавливают значения такой серии. Для этого служат команды с 3 по 6. 
• Команда 3 – значение стартового угла серии. Пример: 3 30. 
• Команда 4 – значение последнего угла серии. Пример: 4 150. 
• Команда 5 – значение угла, на который происходит поворот в серии поворотов. Пример: 5 10. 
• Команда 6 – длительность паузы в миллисекундах между поворотами в серии поворотов. Пример: 6 30. 
• Команда 7 – Выполнение серии поворотов, с параметрами, установленными командами с 3 по 6. 
• Команда 8 - поворот вала сервопривода в заданное значение угла. Пример: 7 150. 
• Команда 9 - поворот вала сервопривода на заданный угол относительно положения, в котором находится вал сервопривода. Положительное значение соответствует повороту по часовой стрелке, отрицательное – повороту против часовой стрелки. Пример: 9 -15.
#include <Servo.h>
Servo servo;
const int SERVO_PIN = D3;
// подбираем эти min- и max-значения
int minValue = 544;
int maxValue = 2400;
void setup()
{
  servo.attach(SERVO_PIN, minValue, maxValue);
  Serial.begin(9600);
  printHelp();
}
int minLoopAngle = 45;
int maxLoopAngle = 135;
int loopStep = 1;
int loopSleep = 15;
int angle = 90;
int value;
void loop()
{
  while(Serial.available()) {
    processInput();
    printHelp();
  }
}
void processInput() {
    int variant = Serial.parseInt();
    if (Serial.available()) {
      value = Serial.parseInt();
    }
    Serial.print("Команда "); Serial.print(variant);
    Serial.print(" и значение параметра "); Serial.println(value);
   
    switch (variant) {
      case 1:
        minValue = value;
        servo.attach(SERVO_PIN, minValue, maxValue);
        servo.write(angle);
        break;
      case 2:
        maxValue = value;
        servo.attach(SERVO_PIN, minValue, maxValue);
        servo.write(angle);
        break;
      case 3:
        minLoopAngle = value; break;
      case 4:
        maxLoopAngle = value; break;
      case 5:
        loopStep = value; break;
      case 6:
        loopSleep = value; break;
      case 7:
        for (angle = minLoopAngle; angle <= maxLoopAngle; angle += loopStep) {
          servo.write(angle);
//          Serial.print("Текущий угол: "); Serial.println(angle);
          delay(loopSleep);
        }
        break;
      case 8:
        angle = value;
        servo.write(angle);
        break;
      case 9:
        angle += value;
        servo.write(angle);
        break;
      default:
        Serial.println("Непонятная команда.");
    }
}
void printHelp() {
    Serial.print("1 - Минимальный импульс мс (Текущее значение "); Serial.print(minValue); Serial.println(")");
    Serial.print("2 - Максимальный импульс мс (Текущее значение "); Serial.print(maxValue); Serial.println(")");
    Serial.print("3 - Начальный угол цикла ° (Текущее значение "); Serial.print(minLoopAngle); Serial.println(")");
    Serial.print("4 - Конечный угол цикла ° (Текущее значение "); Serial.print(maxLoopAngle); Serial.println(")");
    Serial.print("5 - Шаг цикла ° (Текущее значение "); Serial.print(loopStep); Serial.println(")");
    Serial.print("6 - Пауза цикла мс (Текущее значение "); Serial.print(loopSleep); Serial.println(")");
    Serial.println("7 - Запустить цикл");
    Serial.print("8 - Повернуть на абсолютный угол ° (Текущее значение "); Serial.print(angle); Serial.println(")");
    Serial.print("9 - Повернуть от текущего угла ° (Текущее значение "); Serial.print(angle); Serial.println(")");
    Serial.println("Введите команду и через пробел, параметр");
} 
После ввода команды через монитор порта (на картинке ниже вводится команда 9 90 – повернуть вал двигателя на 90 градусов по часовой стрелке относительно текущего положения) в мониторе порта будет выведено напоминание о командах и текущих значениях параметров. 
 
Для того, чтобы, не спеша поднять крышу домика воспользуйтесь настройками цикла поворота. Установите его параметры, вводя в мониторе порта следующие команды: 
3 0		(начальный угол сервопривода установите 0); 
4 90 		(конечный угол сервопривода установите 90); 
5 2		(сервопривод будет осуществлять повороты от 0 до 90 градусов шагами по 2 градуса); 
6 100		(между шагами будет выдерживаться пауза 0,1 секунеды); 
7		(запуска цикла) 
В результате крыша домика начнёт медленно подниматься. Чтобы вернуть её в исходное положение, воспользуйтесь командой 8 0. 
ЗАМЕЧАНИЕ. В этих тестовых командах предполагается, что сервопривод установлен таким образом, что при нулевом угле его ось соответствует закрытой крыше домика. Тогда при 90 градусах, крыша домика будет подниматься на максимальную высоту.