Raspberry Pi Pico: управление шаговым двигателем с MicroPython
В этом руководстве вы узнаете, как управлять шаговым двигателем с помощью Raspberry Pi Pico. Мы будем использовать униполярный шаговый двигатель 28BYJ-48 с драйвером ULN2003. Вы узнаете, как подключить его к Raspberry Pi Pico и как управлять им с помощью модуля MicroPython.
Впервые работаете с Raspberry Pi Pico? Прочитайте следующее руководство: Начало работы с Raspberry Pi Pico (и Pico W).
В этом руководстве мы рассмотрим следующие темы:
Предварительные требования
Перед тем как продолжить, убедитесь, что вы выполнили следующие предварительные требования.
Прошивка MicroPython
Для выполнения этого руководства вам необходимо установить прошивку MicroPython на вашу плату Raspberry Pi Pico. Вам также понадобится IDE для написания и загрузки кода на плату.
Рекомендуемая IDE для Raspberry Pi Pico с MicroPython — это Thonny IDE. Следуйте следующему руководству, чтобы узнать, как установить Thonny IDE, прошить MicroPython и загрузить код на плату.
Альтернативно, если вам нравится программировать в VS Code, вы можете начать со следующего руководства:
Необходимые компоненты
Вам также понадобятся следующие компоненты:
Raspberry Pi Pico
Шаговый двигатель 28BYJ-48 + драйвер ULN2003
Соединительные провода
Батарейный отсек 4xAA или любой другой источник питания (от 5 В до 12 В)
Знакомство с шаговыми двигателями
Шаговый двигатель — это бесщеточный электродвигатель постоянного тока, который делит полный оборот на определенное количество шагов. Он перемещается по одному шагу за раз, и каждый шаг имеет одинаковый размер. Это позволяет нам поворачивать двигатель на точный угол в точное положение. Шаговый двигатель может вращаться по часовой стрелке или против часовой стрелки.
На следующей фотографии показаны два шаговых двигателя 28BYJ-48.
Шаговые двигатели состоят из внутренних катушек, которые заставляют вал двигателя перемещаться по шагам в одном или другом направлении, когда ток подается на катушки определенным образом. Существует два типа шаговых двигателей: униполярные и биполярные. Мы не будем подробно рассматривать, как устроены шаговые двигатели и как они работают внутри.
Чтобы узнать более подробно, как они работают и в чем различия между каждым типом шагового двигателя, мы рекомендуем прочитать эту статью в блоге DroneBotWorkshop.
Шаговый двигатель 28BYJ-48
Существует множество шаговых двигателей с различными характеристиками. Мы будем использовать униполярный шаговый двигатель 28BYJ-48 с драйвером ULN2003 — эта комбинация широко используется любителями электроники и DIY-энтузиастами.
Характеристики шагового двигателя 28BYJ-48
Характеристики шагового двигателя (для получения дополнительной информации обратитесь к даташиту):
Номинальное напряжение: 5 В постоянного тока
Количество фаз: 4
Передаточное число: 1/64
Угол шага: 5.625°/64
Частота: 100 Гц
Шаговый двигатель 28BYJ-48 имеет в общей сложности четыре катушки. Один конец катушек подключен к 5 В, что соответствует красному проводу двигателя. Другой конец катушек соответствует проводам синего, розового, желтого и оранжевого цветов. Подача тока на катушки в определенной логической последовательности заставляет двигатель совершать один шаг в одном или другом направлении.
Шаговый двигатель 28BYJ-48 имеет угол шага 5.625°/64 в полушаговом режиме. Это означает, что двигатель имеет угол шага 5.625° — поэтому ему нужно 360°/5.625° = 64 шага в полушаговом режиме. В полношаговом режиме: 64/2 = 32 шага для выполнения одного оборота.
Однако выходной вал приводится через передаточное число 64:1. Это означает, что вал (видимый снаружи двигателя) совершит один оборот, если двигатель внутри повернется 64 раза. Это означает, что двигатель должен совершить 32 x 64 = 2048 шагов, чтобы вал совершил один полный оборот. Это означает, что вы получите точность 360°/2048 шагов = 0.18°/шаг.
Итак, подведем итог:
Общее количество шагов на один оборот = 2048 шагов
Угол шага = 0.18°/шаг
Если вы используете другой шаговый двигатель, обратитесь к его даташиту.
Не волнуйтесь, если это кажется запутанным. Существуют библиотеки, которые упрощают программирование и избавляют от необходимости беспокоиться об этих числах.
Драйвер двигателя ULN2003
Для подключения шагового двигателя к Raspberry Pi Pico мы будем использовать драйвер ULN2003, как показано на рисунке ниже. Шаговый двигатель 28BYJ-48 часто продается вместе с драйвером ULN2003 в комплекте.
Модуль поставляется с разъемом, который позволяет легко и просто подключить двигатель к модулю. Он имеет четыре входных контакта для управления катушками, которые приводят в движение шаговый двигатель. Четыре светодиода обеспечивают визуальную индикацию состояния катушек.
Распиновка драйвера ULN2003
В следующей таблице показана распиновка модуля:
Вывод |
Описание |
|---|---|
IN1 |
Управление двигателем: подключите к цифровому выводу Pico |
IN2 |
Управление двигателем: подключите к цифровому выводу Pico |
IN3 |
Управление двигателем: подключите к цифровому выводу Pico |
IN4 |
Управление двигателем: подключите к цифровому выводу Pico |
VCC |
Питание двигателя |
GND |
Общая земля |
Разъем двигателя |
Подключите разъем провода двигателя |
Подключение шагового двигателя к Raspberry Pi Pico
Давайте подключим шаговый двигатель к Raspberry Pi Pico через драйвер ULN2003. Мы подключим IN1, IN2, IN3 и IN4 к GPIO 28, 27, 26 и 22 соответственно. Вы можете использовать любые другие цифровые выводы, если укажете используемые выводы в коде.
Вы можете следовать приведенной ниже схеме подключения. Или используйте таблицу ниже в качестве справки.
Примечание
Вы должны питать драйвер двигателя от внешнего источника питания напряжением от 5 до 12 В. Мы используем 6.5 В от батарейного отсека.
Примечание
Вывод GND батарейного отсека также должен быть подключен к одному из выводов GND Raspberry Pi Pico.
Драйвер ULN2003 |
Raspberry Pi Pico |
|---|---|
IN1 |
GPIO 28 |
IN2 |
GPIO 27 |
IN3 |
GPIO 26 |
IN4 |
GPIO 22 |
Библиотека MicroPython для шагового двигателя
Существует несколько способов управления шаговым двигателем с помощью библиотеки. Мы будем использовать библиотеку, которая была создана специально для шагового двигателя 28BYJ-48, управляемого драйвером ULN2003.
Выполните следующие шаги, чтобы загрузить библиотеку на Raspberry Pi Pico.
Создайте новый файл в Thonny IDE и скопируйте код библиотеки. Код библиотеки можно найти ниже (или вы можете скачать его по этой ссылке).
Перейдите в File > Save as и выберите Raspberry Pi Pico.
Назовите файл stepper.py и нажмите OK, чтобы сохранить файл на Raspberry Pi Pico.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-stepper-motor-micropython/
# Forked from: https://github.com/larsks/micropython-stepper-motor/blob/master/motor.py
import machine
import time
class Motor:
stepms = 10
# Do be defined by subclasses
maxpos = 0
states = []
def __init__(self, p1, p2, p3, p4, stepms=None):
self.pins = [p1, p2, p3, p4]
if stepms is not None:
self.stepms = stepms
self._state = 0
self._pos = 0
def __repr__(self):
return '<{} @ {}>'.format(
self.__class__.__name__,
self.pos,
)
@property
def pos(self):
return self._pos
@classmethod
def frompins(cls, *pins, **kwargs):
return cls(*[machine.Pin(pin, machine.Pin.OUT) for pin in pins],
**kwargs)
def reset(self):
self._pos = 0
def _step(self, dir):
state = self.states[self._state]
for i, val in enumerate(state):
self.pins[i].value(val)
self._state = (self._state + dir) % len(self.states)
self._pos = (self._pos + dir) % self.maxpos
def step(self, steps):
dir = 1 if steps >= 0 else -1
steps = abs(steps)
for _ in range(steps):
t_start = time.ticks_ms()
self._step(dir)
t_end = time.ticks_ms()
t_delta = time.ticks_diff(t_end, t_start)
time.sleep_ms(self.stepms - t_delta)
def step_until(self, target, dir=None):
if target < 0 or target > self.maxpos:
raise ValueError(target)
if dir is None:
dir = 1 if target > self._pos else -1
if abs(target - self._pos) > self.maxpos/2:
dir = -dir
while True:
if self._pos == target:
break
self.step(dir)
def step_until_angle(self, angle, dir=None):
if angle < 0 or angle > 360:
raise ValueError(angle)
target = int(angle / 360 * self.maxpos)
self.step_until(target, dir=dir)
def step_degrees(self, degrees):
if degrees < 0 or degrees > 360:
raise ValueError("Degrees should be between 0 and 360")
steps_to_take = int(degrees / 360 * self.maxpos)
self.zero() # Ignore the current position, start from zero
self.step(steps_to_take)
class FullStepMotor(Motor):
stepms = 5
maxpos = 2048
states = [\
[1, 1, 0, 0],\
[0, 1, 1, 0],\
[0, 0, 1, 1],\
[1, 0, 0, 1],\
]
class HalfStepMotor(Motor):
stepms = 3
maxpos = 4096
states = [\
[1, 0, 0, 0],\
[1, 1, 0, 0],\
[0, 1, 0, 0],\
[0, 1, 1, 0],\
[0, 0, 1, 0],\
[0, 0, 1, 1],\
[0, 0, 0, 1],\
[1, 0, 0, 1],\
]
Вот и всё. Библиотека загружена на вашу плату. Теперь вы можете использовать функции библиотеки в своем коде, импортировав библиотеку.
Управление шаговым двигателем – код MicroPython
Библиотека, которую мы используем, очень интуитивно понятна в использовании. Следующий код демонстрирует различные доступные методы.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-stepper-motor-micropython/
import stepper
from time import sleep
# Define the stepper motor pins
IN1 = 28
IN2 = 27
IN3 = 26
IN4 = 22
# Initialize the stepper motor
stepper_motor = stepper.HalfStepMotor.frompins(IN1, IN2, IN3, IN4)
# Set the current position as position 0
stepper_motor.reset()
try:
while True:
#Move 500 steps in clockwise direction
stepper_motor.step(500)
sleep(0.5) # stop for a while
# Move 500 steps in counterclockwise direction
stepper_motor.step(-500)
sleep(0.5) # stop for a while
# Go to a specific position (in steps)
stepper_motor.step_until(2000)
sleep(0.5) # stop for a while
# Force a direction using the dir paramter
stepper_motor.step_until(2000, dir=-1)
sleep(0.5) # stop for a while
# Go to a specific position (angle, maximum is 359, otherwise it will spin indefinetely)
stepper_motor.step_until_angle(359)
sleep(0.5) # stop for a while
except KeyboardInterrupt:
print('Keyboard interrupt')
Как работает код
Давайте кратко рассмотрим, как работает код, чтобы увидеть различные методы, предоставляемые библиотекой для управления шаговыми двигателями.
Сначала вам нужна библиотека stepper, которую вы только что загрузили на Raspberry Pi Pico.
import stepper
Затем определите выводы, которые вы используете для управления шаговым двигателем через драйвер ULN2003. Если вы используете другие выводы, измените следующие строки:
# Define the stepper motor pins
IN1 = 28
IN2 = 27
IN3 = 26
IN4 = 22
Затем инициализируйте шаговый двигатель следующим образом (мы используем полушаговый режим, как объяснялось ранее).
# Initialize the stepper motor
stepper_motor = stepper.HalfStepMotor.frompins(IN1, IN2, IN3, IN4)
Перед тем как начать перемещение двигателя, мы используем метод reset(), чтобы сообщить коду, что текущая позиция шагового двигателя — это позиция 0.
# Set the current position as position 0
stepper_motor.reset()
Затем у нас есть цикл while, в котором мы перемещаем двигатель с помощью различных методов.
try:
while True:
Метод step() перемещает двигатель на заданное количество шагов по часовой стрелке. Передайте в качестве аргумента количество шагов, которое вы хотите совершить.
#Move 500 steps in clockwise direction
stepper_motor.step(500)
Вы также можете передать отрицательное число для движения против часовой стрелки.
# Move 500 steps in counterclockwise direction
stepper_motor.step(-500)
Если вы хотите, чтобы двигатель перешел в определенную позицию (считая от позиции, определенной как нулевая), вы можете использовать метод step_until() и передать в качестве аргумента номер шага. Этот метод найдет кратчайший путь для перемещения двигателя в указанную позицию.
# Go to a specific position (in steps)
stepper_motor.step_until(2000)
В любой момент в вашем коде вы можете вызвать метод reset(), чтобы определить новую точку отсчета (позиция 0).
Вы можете передать дополнительный параметр в метод step_until() — параметр dir. Он может быть равен 1, чтобы заставить двигатель вращаться по часовой стрелке, или -1, чтобы заставить двигатель вращаться против часовой стрелки.
# Force a direction using the dir parameter
stepper_motor.step_until(2000, dir=-1)
sleep(0.5) # stop for a while
Аналогично, существует метод, который делает то же самое, но вы можете передать позицию в градусах. Не передавайте 360 в качестве аргумента, иначе двигатель не остановится.
stepper_motor.step_until_angle(359)
Тестирование кода
Загрузите предыдущий код на ваш Raspberry Pi Pico и наблюдайте, как двигатель перемещается в различные позиции каждые полсекунды. Поэкспериментируйте с различными методами и передавайте различные аргументы, чтобы увидеть, как ведет себя двигатель.
Заключение
В этом руководстве вы узнали, как управлять шаговым двигателем с помощью Raspberry Pi Pico, запрограммированного на MicroPython. Один из самых популярных двигателей для использования в проектах DIY-любителей — это униполярный шаговый двигатель 28BYJ-48 с драйвером ULN2003.
Если вы хотите подключить другие двигатели к Raspberry Pi Pico, ознакомьтесь с руководствами ниже: