Сервопривод: управляем углом через ШИМ

Применяем ШИМ к движению: поворачиваем вал серво на заданный угол.

Сервопривод — моторчик с электроникой, который поворачивает вал на угол, заданный длительностью управляющего импульса.

Как серво понимает угол

Сервопривод ждёт импульсы с частотой 50 Гц (период 20 мс). Важна ширина импульса:

Ширина импульсаУгол вала
~1.0 мс
~1.5 мс90° (центр)
~2.0 мс180°

То есть управление углом — это управление шириной импульса при фиксированной частоте 50 Гц.

Перевод угла в скважность

Нам нужно перевести угол в значение duty_u16. При 50 Гц период равен 20 мс. Импульс 1 мс — это 1/20 = 5% периода, импульс 2 мс — 10%. Посчитаем на обычном Python:

def angle_to_duty(angle):
    period_ms = 20.0                  # 50 Гц
    pulse_ms = 1.0 + (angle / 180) * 1.0   # 1.0..2.0 мс
    fraction = pulse_ms / period_ms
    return round(fraction * 65535)

for a in (0, 45, 90, 135, 180):
    print(f"угол {a:3d}° -> импульс {1.0 + a/180:.2f} мс -> duty {angle_to_duty(a)}")

Вывод:

угол   0° -> импульс 1.00 мс -> duty 3277
угол  45° -> импульс 1.25 мс -> duty 4096
угол  90° -> импульс 1.50 мс -> duty 4915
угол 135° -> импульс 1.75 мс -> duty 5734
угол 180° -> импульс 2.00 мс -> duty 6554

Код на плате

from machine import Pin, PWM
import time

servo = PWM(Pin(13), freq=50)

def set_angle(angle):
    pulse_ms = 1.0 + (angle / 180) * 1.0
    duty = round((pulse_ms / 20.0) * 65535)
    servo.duty_u16(duty)

for a in (0, 90, 180, 90, 0):
    set_angle(a)
    time.sleep(1)

Как работает под капотом

Внутри серво стоит потенциометр, связанный с валом. Электроника сравнивает текущее положение вала с положением, «заказанным» шириной импульса, и крутит мотор, пока они не совпадут. Поэтому серво само удерживает угол: толкнёте вал — оно вернёт его обратно. ESP32 лишь задаёт цель через ШИМ, а отработку делает контроллер внутри серво.

Частые ошибки

  • Питать серво от вывода платы. Серво потребляет много тока — питайте его отдельным источником 5 В, а земли соедините.
  • Неточные импульсы. У разных серво границы 1–2 мс слегка отличаются; иногда диапазон 0.5–2.5 мс. Подбирайте опытно.
  • Дёргать угол слишком резко. Делайте плавные шаги, чтобы не было рывков и просадки питания.

Итог

  • Серво управляется шириной импульса при частоте 50 Гц.
  • 1 мс — 0°, 1.5 мс — 90°, 2 мс — 180°.
  • Угол переводят в duty_u16 через долю периода.
  • Серво питают отдельно: ток велик для вывода ESP32.
Проверьте себя
1. Какая частота ШИМ нужна стандартному сервоприводу?
A1 Гц
B50 Гц
C1000 Гц
D1 МГц
2. Чем серво кодирует нужный угол?
AЧастотой сигнала
BШириной (длительностью) управляющего импульса
CНапряжением питания
DЦветом провода
3. Почему серво лучше питать отдельным источником, а не выводом ESP32?
AТак красивее
BСерво потребляет большой ток, который вывод не выдаст
CESP32 не умеет ШИМ
DСерво работает на 220 В