Что такое сервопривод
Серво — мотор с редуктором и обратной связью: вместо «крутись» вы говорите «повернись на угол 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-мотор + энкодер — для непрерывного вращения с контролем позиции.
- Линейный актуатор — для линейного движения.