Сервопривод: управляем углом через ШИМ
Применяем ШИМ к движению: поворачиваем вал серво на заданный угол.
Сервопривод — моторчик с электроникой, который поворачивает вал на угол, заданный длительностью управляющего импульса.
Как серво понимает угол
Сервопривод ждёт импульсы с частотой 50 Гц (период 20 мс). Важна ширина импульса:
| Ширина импульса | Угол вала |
| ~1.0 мс | 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.