Добавить в избранное

Сервопривод и Arduino: подключение, библиотека Servo и плавное движение

Чтение ≈ 4 мин

Как подключить сервопривод к Arduino: питание, библиотека Servo, write и writeMicroseconds, плавное движение, калибровка цифровых серво и типичные проблемы — питание, дребезг, дрожание.

Что такое сервопривод

Серво — мотор с редуктором и обратной связью: вместо «крутись» вы говорите «повернись на угол 90°», и контроллер внутри сам удерживает положение. Классические хобби-серво крутятся в диапазоне 0–180°, есть и непрерывные на 360° (крутят как моторы, но с регулировкой скорости через импульс).

На практике: робот-рука, поворот камеры, рулевое управление модели, привод заслонки — везде нужен точный угол.

Подключение

У серво три провода:

  • Коричневый/чёрный — GND;
  • Красный — питание 5 В (для большинства 4.8–6 В);
  • Оранжевый/жёлтый/белый — сигнал, на любой цифровой пин.
#include <Servo.h>

Servo myservo;

void setup() {
    myservo.attach(9);   // сигнал на пине 9
}

void loop() {
    myservo.write(0);      // в одну крайность
    delay(1000);
    myservo.write(90);     // середина
    delay(1000);
    myservo.write(180);    // другая крайность
    delay(1000);
}

myservo.write(угол) — значение 0–180 градусов. Для точного управления — writeMicroseconds(500..2500) — импульс в микросекундах, обычно 1000 мкс = 0°, 1500 = 90°, 2000 = 180°.

Питание — главный подводный камень

Маленький SG90 потребляет до 300–500 мА под нагрузкой, MG996R — до 2.5 А. От пина 5V Arduino столько не вытягивает — серво будет дёргаться, перезагружать плату или сжечь стабилизатор.

Правила:

  • Один SG90 без нагрузки — можно от 5V платы для эксперимента.
  • Любой реальный проект — отдельный источник 5–6 В (аккумулятор, BEC, блок питания).
  • Общий GND обязателен: минус источника серво соедините с GND Arduino.
  • Конденсатор 470–1000 мкФ на питании серво — гасит броски тока.
Блок питания 5V ── + ── красный провод серво
                └── − ── коричневый ── и к GND Arduino
Arduino D9 ── оранжевый сигнал

Плавное движение

write(90) — рывок: серво рванёт к углу с максимальной скоростью. Для плавности двигаем шагами:

void moveTo(Servo& s, int target, int step = 1, int delayMs = 15) {
    int cur = s.read();                 // текущая позиция
    int dir = (target > cur) ? 1 : -1;
    for (int pos = cur; pos != target; pos += dir) {
        s.write(pos);
        delay(delayMs);
    }
}

Или с millis() для неблокирующего движения — серво не затормозит остальную логику:

uint32_t lastStep = 0;
int targetPos = 90;

void loop() {
    int cur = myservo.read();
    if (cur != targetPos && millis() - lastStep > 15) {
        lastStep = millis();
        myservo.write(cur + (targetPos > cur ? 1 : -1));
    }
    // остальная логика параллельно
}

Калибровка

Не все серво точны: 0° на одной — 90 на другой, механические крайности могут вызывать жужание. Калибруем через writeMicroseconds:

myservo.attach(9, 500, 2400);   // импульсы для 0° и 180° у вашей сервы

Методика: подавайте writeMicroseconds(1000), смотрите угол; подбирайте min/max, пока write(0) и write(180) не дадут нужные углы. Для непрерывных серво калибруется «стоп» — значение, при котором мотор не крутится (обычно ~1500 мкс).

Типичные проблемы

  • Дрожание/жужание: под нагрузкой серво пытается удержать положение — снижайте требуемый угол или улучшайте питание.
  • Перезагрузка платы при старте: бросок тока серво — отдельное питание и конденсатор.
  • Не едет в крайности: неправильная калибровка или механический упор — ограничьте диапазон write(10..170).
  • Дребезг цели: считайте угол с датчика с фильтром (среднее нескольких чтений) иначе серво дёргается.
  • ШИМ-конфликт: Servo использует Timer1 — на пинах 9, 10 перестаёт работать analogWrite пока серво присоединено.

Практический пример: сканер дистанции

Серво + ультразвуковой датчик = радар:

#include <Servo.h>
Servo radar;
const int TRIG = 7, ECHO = 6;

void setup() {
    radar.attach(9);
    Serial.begin(9600);
    pinMode(TRIG, OUTPUT);
    pinMode(ECHO, INPUT);
}

void loop() {
    for (int a = 0; a <= 180; a += 5) {
        radar.write(a);
        delay(50);
        Serial.print(a); Serial.print(":");
        Serial.println(measure());
    }
}

long measure() {
    digitalWrite(TRIG, LOW); delayMicroseconds(2);
    digitalWrite(TRIG, HIGH); delayMicroseconds(10);
    digitalWrite(TRIG, LOW);
    return pulseIn(ECHO, HIGH) / 58;   // в см
}

Итог

Сервопривод — простейший способ получить точный угол: подключили сигнал к пину, write(угол) — и готово. Секреты: отдельное питание для реальных серво, writeMicroseconds для калибровки, шаговое движение для плавности, общий GND обязателен. С этими правилами серво будет работать надёжно в любом проекте.

Полный пример: плавное покачивание

#include <Servo.h>

Servo srv;
int pos = 90;

void setup() {
    srv.attach(9);            // сигнал на D9
    srv.write(pos);
}

void loop() {
    for (pos = 0; pos <= 180; ++pos) {
        srv.write(pos);
        delay(15);             // скорость движения
    }
    for (pos = 180; pos >= 0; --pos) {
        srv.write(pos);
        delay(15);
    }
}

Управление углом через потенциометр

int angle = map(analogRead(A0), 0, 1023, 0, 180);
srv.write(angle);

Библиотека Servo: тонкости

  • attach(pin, minPulse, maxPulse) — явные пределы импульса в мкс (по умолчанию 544–2400).
  • writeMicroseconds(1500) — прямая запись длительности — точный центр серво.
  • read() — последний записанный угол (не реальную позицию — у серво нет обратной связи по углу).
  • Несколько серво на одной плате — до 12 на Uno; каждая ест таймер — на Mega до 48.

Контроль скорости и плавности

write(angle) — серво едет мгновенно в точку. Для плавного подъезда — промежуточные углы с delay или через millis() таймер. Библиотека VarSpeedServo добавляет параметр скорости в write().

Серво с обратной связью

Стандартные серво не знают своего угла — команда отдана, и всё. Для проектов, где важна фактическая позиция, берут серво с feedback-проводом (например, Feetech FS90-FB) или датчик на валу (потенциометр/энкодер).

Питание серво: критично

SG90 под нагрузкой тянет до 500 мА, MG996R — до 2.5 А. Запитывать от 5V-пина Uno — гарантированные просадки и сбросы. Всегда отдельный БП 5–6 В на серво с общим GND с Arduino. Конденсатор 470 мкФ по питанию серво сглаживает броски.

Применение в проектах

  • Поворот камеры/датчика — сканирование пространства.
  • Краны, замки, затворы — «нажми на кнопку» физически.
  • Роборуки и манипуляторы.
  • Открывалка окна/жалюзи в умном доме.
  • Указательная шкала прибора (стрелка на серво).

Полный пример: серво по кнопкам

#include <Servo.h>

Servo srv;
int pos = 90;
const int BTN_L = 2, BTN_R = 3;

void setup() {
    srv.attach(9);
    srv.write(pos);
    pinMode(BTN_L, INPUT_PULLUP);
    pinMode(BTN_R, INPUT_PULLUP);
}

void loop() {
    if (digitalRead(BTN_L) == LOW) pos = constrain(pos - 5, 0, 180);
    if (digitalRead(BTN_R) == LOW) pos = constrain(pos + 5, 0, 180);
    srv.write(pos);
    delay(20);
}

Серво с обратной связью

Стандартные серво не знают своего угла — команда отдана, и всё. Для проектов, где важна фактическая позиция, берут серво с feedback-проводом (Feetech FS90-FB) или датчик на валу (потенциометр/энкодер AS5600).

Альтернативы

  • Stepper — точнее и без ограничения угла, но сложнее управление.
  • DC-мотор + энкодер — для непрерывного вращения с контролем позиции.
  • Линейный актуатор — для линейного движения.
Поделиться
Понравился материал?

Комментарии

Добавить комментарий