Servo
Сервопривод — это мотор, который может поворачиваться на заданный угол. В отличие от обычного мотора, он не может свободно вращаться (поэтому из него нельзя сделать вентилятор или колёса для машинки), но с помощью микроконтроллера можно точно задать угол поворота сервопривода с точностью до полуградуса, и он будет удерживать заданное положение.
Базовое использование
Servo(pin) -> Servo
Чтобы создать объект Servo, вызовите Servo(pin).
Аргументы:
pin (int)— порт пина (8, 9 или 12)
Возвращает:
Возвращает объект Servo для pin.
Внутри серво управляется через ШИМ на частоте 50 Гц (период = 20 мс). Частота выставляется автоматически — настраивать её вручную не нужно.
from pibody import Servo
servo = Servo(9)
.angle(angle | None) -> None | int
Получить или установить угол серво (0–180 градусов).
Аргументы:
angle (float)— необязательный параметр, задающий угол серво в диапазоне [0, 180] градусов
Возвращает текущий угол [0, 180] при вызове без аргумента, иначе устанавливает угол и возвращает None.
Геттер возвращает последний установленный через объект угол (а не считанный с железа). Если угол ещё не устанавливался, вернётся None.
from pibody import Servo
from time import sleep
servo = Servo(8)
servo.angle(180)
sleep(1)
print(servo.angle()) # 180
servo.angle(90)
sleep(1)
servo.angle(0)
sleep(1)
print(servo.angle()) # 0
servo(angle | None) -> None | int
Объект Servo можно вызывать как функцию — вызов работает точно так же, как .angle().
Аргументы:
angle (float)— необязательный параметр, задающий угол серво в диапазоне [0, 180] градусов
servo(90) устанавливает угол, servo() возвращает текущий угол.
from pibody import Servo
servo = Servo(9)
servo(90) # то же, что servo.angle(90)
print(servo()) # 90
.on()
Переинициализирует выход ШИМ (включает серво).
servo.on()
.off()
Деинициализирует выход ШИМ (отключает серво).
servo.off()
Прямое управление через PWM
Класс Servo больше не даёт доступ к duty, duty_u16 и freq. Если нужно низкоуровневое управление, создайте PWM-объект напрямую вместо Servo:
from pibody import PWM
servo = PWM(8)
servo.freq(50) # нужно задать вручную
Положение серво управляется шириной импульса сигнала ШИМ, а не непосредственно коэффициентом заполнения. Например, стандартный сервопривод на 180° ожидает импульс между 0.5 мс (0°) и 2.5 мс (180°), повторяющийся каждые 20 мс (50 Гц).
freq задаёт частоту повторения импульсов — для серво это должно быть 50 Гц (период = 20 мс). duty задаёт, какая часть этого периода сигнал находится в высоком состоянии. Для преобразования угла в значение duty:
pulse_width = (angle / 180) * 2 + 0.5 # 0.5–2.5 мс
duty = pulse_width / SERVO_PERIOD_MS # часть от 20 мс
В наборе PiBody SERVO_PERIOD_MS = 20 (равно 1000 // freq).
Превышение рекомендуемого диапазона (например, импульс > 2.5 мс для серво на 180°) не повредит сервопривод — большинство моделей просто игнорируют превышение и удерживаются на максимальном угле. Некоторые могут издавать слабое гудение на механическом упоре; это нормально. Значения ниже минимальных 0.5 мс также обрезаются аппаратурой серво до положения 0°.
Методы ниже — это методы pibody.PWM, показанные здесь применительно к серво.
.duty(value | None) -> None | float
Вы можете установить угол через duty. Для управления сначала преобразуйте угол в ширину импульса:
pulse_width = (angle / 180) * 2 + 0.5
После этого преобразуйте ширину импульса в коэффициент заполнения:
duty = pulse_width / SERVO_PERIOD_MS
Используйте значение int в диапазоне [0.025, 0.125]. Значение 0 отключит серво.
Аргументы:
value (float)— необязательный параметр, задающий коэффициент заполнения ШИМ. Может принимать значение в диапазоне [0, 0.125]. По умолчанию: 0
Если value пусто, метод возвращает коэффициент заполнения, использованный ранее.
from pibody import PWM
SERVO_PERIOD_MS = 20
servo = PWM(8)
servo.freq(50)
angle = 90
pulse_width = (angle / 180) * 2 + 0.5 # 1.5
duty = pulse_width / SERVO_PERIOD_MS # 0.075
servo.duty(duty)
print(servo.duty()) # 0.075
.duty_u16(value | None) -> None | int
То же, что и .duty(), вы можете установить угол через duty_u16. u16 означает 16-битное значение.
Используйте значение int в диапазоне [1638, 8191] Значение 0 отключит серво.
Аргументы:
value (int)— необязательный параметр, задающий коэффициент заполненияpibody.PWM. Может принимать значение в диапазоне [1638, 8191]. По умолчанию: 0
Если value пусто, метод возвращает коэффициент заполнения, использованный ранее.
from pibody import PWM
SERVO_PERIOD_MS = 20
servo = PWM(8)
servo.freq(50)
angle = 90
pulse_width = (angle / 180) * 2 + 0.5 # 1.5
duty = pulse_width / SERVO_PERIOD_MS # 0.075 (нормализованный)
duty_u16 = int(duty * 65535) # ~4915
servo.duty_u16(duty_u16)
print(servo.duty_u16()) # 4915
.freq(value | None) -> None | int
freq задаёт частоту повторения импульсов — для серво это должно быть 50 Гц (период = 20 мс).
Аргументы:
value (int)— необязательный параметр, задающий частоту ШИМ. По умолчанию: 50
Если value пусто, метод возвращает частоту, использованную ранее.
pwm.freq(50)
print(pwm.freq()) # 50