Что такое шаговый двигатель? Точное вращение с 28BYJ-48 и ULN2003 на Arduino
Как работает шаговый двигатель? Подключение 28BYJ-48 и драйвера ULN2003, шагов на оборот (2048), библиотеки Stepper и AccelStepper, поворот на угол, NEMA 17 с A4988, ESP32 и Pico.
Шаговый двигатель — мотор, который делит вращение на маленькие равные шаги. С каждой командой он поворачивается на фиксированный угол, поэтому точно известно, где мотор остановился, без всяких дополнительных датчиков. Благодаря этой точности шаговые двигатели используют 3D-принтеры, станки с ЧПУ, слайдеры для камер и автоматические шторы. Самый дешёвый способ начать учиться с Arduino — мотор 28BYJ-48 и плата-драйвер ULN2003, которая продаётся в комплекте с ним.

Как работает шаговый двигатель?
Внутри шагового двигателя вокруг зубчатого магнитного ротора расположены несколько катушек. Когда катушки включаются в определённом порядке, ротор каждый раз притягивается к ближайшей катушке и делает один шаг. Если быстро прогонять последовательность, мотор вращается быстро; если медленно — медленно; если поменять порядок на обратный — в другую сторону. Мотор отсчитывает каждый шаг, поэтому его положение известно, но при перегрузке он может незаметно пропускать шаги.
Шаговый двигатель, сервопривод или DC-мотор?
| Параметр | DC-мотор | Сервопривод | Шаговый двигатель |
|---|---|---|---|
| Движение | Вращается непрерывно | Поворачивается на заданный угол (обычно 0–180°) | Неограниченное число оборотов, шаг за шагом |
| Информация о положении | Нет | Есть (встроенная обратная связь) | Известна по счёту шагов |
| Скорость | Очень высокая | Средняя | Низкая–средняя |
| Крутящий момент на малой скорости | Низкий | Средний | Высокий |
| Типичное применение | Колёса, вентиляторы, насосы | Руки роботов, замки, рулевое управление | 3D-принтеры, ЧПУ, слайдеры, часы |
Если достаточно повернуться на угол и удерживать его, сервопривод проще; подробности в статье Что такое сервопривод? Если нужно быстрое непрерывное вращение, лучше подойдёт DC-мотор с драйвером моторов L298N. Для задач, где нужны и несколько оборотов, и известное положение, шаговому двигателю нет равных.
Характеристики 28BYJ-48
| Параметр | Значение |
|---|---|
| Тип | 4-фазный униполярный шаговый двигатель |
| Рабочее напряжение | 5 V DC |
| Передаточное число редуктора | Около 1:64 |
| Шагов на оборот | 2048 (полный шаг), 4096 (полушаг) |
| Угол шага | Около 0,18° (полный шаг) |
| Потребляемый ток | Около 200–250 mA |
| Максимальная скорость | Около 10–15 об/мин |
| Провода | 5 (красный — общий) |
Подключение драйвера ULN2003
5-проводной разъём мотора вставляется в гнездо на плате ULN2003 только одной стороной, так что ошибиться невозможно. Подключи пины IN1–IN4 платы к пинам Arduino 8–11, а клеммы + и – — к источнику 5 V. ULN2003 — это сборка транзисторов Дарлингтона, которая усиливает слабый сигнал с пина Arduino до тока, нужного катушке, а четыре светодиода на плате показывают, как катушки по очереди включаются.
| Пин ULN2003 | Arduino Uno |
|---|---|
| IN1 | D8 |
| IN2 | D9 |
| IN3 | D10 |
| IN4 | D11 |
| + (5–12 V) | Внешние 5 V (для одного мотора подойдёт пин 5V на Uno) |
| – (GND) | GND (общий с Arduino) |
Первое вращение с библиотекой Stepper
Библиотеку Stepper, которая идёт вместе с Arduino IDE, устанавливать не нужно. Следить надо только за порядком пинов: для 28BYJ-48 объект нужно объявлять в порядке 8, 10, 9, 11 (IN1, IN3, IN2, IN4). Если написать 8, 9, 10, 11, мотор вибрирует на месте вместо вращения; это самая частая ошибка.
1#include <Stepper.h>
2
3const int STEPS_PER_REV = 2048; // 28BYJ-48 tam tur / full revolution
4Stepper motor(STEPS_PER_REV, 8, 10, 9, 11); // sıra: IN1, IN3, IN2, IN4 / order: IN1, IN3, IN2, IN4
5
6void setup() {
7 motor.setSpeed(10); // devir/dakika, en fazla ~15 / RPM, max ~15
8}
9
10void loop() {
11 motor.step(STEPS_PER_REV); // bir yönde tam tur / one full turn
12 delay(1000);
13 motor.step(-STEPS_PER_REV / 2); // ters yönde yarım tur / half a turn back
14 delay(1000);
15}Управление положением потенциометром
Если хранить текущее положение мотора в переменной, его можно отправить в любую точку. Код ниже превращает положение потенциометра в 0–2048 шагов, и мотор переходит в ту же точку, словно следует за ручкой. Допуск в 10 шагов игнорирует мелкое дрожание. Подключение потенциометра — в статье Что такое потенциометр?
1#include <Stepper.h>
2
3Stepper motor(2048, 8, 10, 9, 11);
4int position = 0; // şu anki adım / current step
5
6void setup() {
7 motor.setSpeed(12);
8}
9
10void loop() {
11 int target = map(analogRead(A0), 0, 1023, 0, 2048); // potansiyometre → hedef / pot → target
12 if (abs(target - position) > 10) { // küçük titreşimleri yok say / ignore jitter
13 motor.step(target - position);
14 position = target;
15 }
16}AccelStepper: плавный разгон без блокировки
Команда step() из библиотеки Stepper останавливает программу, пока движение не закончится; всё это время нельзя читать кнопки или обновлять дисплей. Библиотека AccelStepper, которую можно установить через «Менеджер библиотек», двигает мотор шаг за шагом в фоне и добавляет разгон и торможение, чтобы не было резких стартов. Для 28BYJ-48 используется режим полушага (HALF4WIRE), в котором один оборот — это 4096 шагов:
1#include <AccelStepper.h>
2
3// 28BYJ-48 + ULN2003, yarım adım: tur başına 4096 / half-step: 4096 per turn
4AccelStepper motor(AccelStepper::HALF4WIRE, 8, 10, 9, 11);
5
6void setup() {
7 motor.setMaxSpeed(1000); // adım/saniye / steps per second
8 motor.setAcceleration(400); // adım/saniye² / steps per second²
9 motor.moveTo(4096); // bir tur ileri / one turn forward
10}
11
12void loop() {
13 if (motor.distanceToGo() == 0) {
14 motor.moveTo(-motor.currentPosition()); // geri dön / go back
15 }
16 motor.run(); // her döngüde çağır, bekletmez / call every loop, non-blocking
17}Моторы помощнее: NEMA 17 и A4988

Для задач, где нужна сила, например в 3D-принтерах и станках с ЧПУ, используют биполярные шаговые двигатели вроде NEMA 17. Такие моторы делают 200 шагов на оборот (1,8°) и намного сильнее 28BYJ-48. Ими управляют драйверы вроде A4988 или DRV8825: на каждый импульс STEP мотор делает один шаг, а пин DIR задаёт направление. Драйвер работает от 8–35 V и с микрошагом делит каждый шаг до 16 частей для более плавного движения.
1const int STEP_PIN = 3;
2const int DIR_PIN = 4;
3
4void setup() {
5 pinMode(STEP_PIN, OUTPUT);
6 pinMode(DIR_PIN, OUTPUT);
7}
8
9void loop() {
10 digitalWrite(DIR_PIN, HIGH); // yön / direction
11 for (int i = 0; i < 200; i++) { // NEMA 17'de 200 adım = 1 tur / 200 steps = 1 turn
12 digitalWrite(STEP_PIN, HIGH);
13 delayMicroseconds(800); // küçüldükçe hız artar / smaller = faster
14 digitalWrite(STEP_PIN, LOW);
15 delayMicroseconds(800);
16 }
17 delay(1000);
18}Шаговые двигатели с ESP32 и Raspberry Pi Pico
Входы ULN2003 нормально работают с сигналами 3,3 V; питание мотора всё равно подавай отдельно от 5 V. На ESP32 библиотека AccelStepper работает без изменений; можно использовать любые пины, кроме 6–11 и 34–39, например GPIO 19, 18, 5 и 17. На Pico с MicroPython мотор вращают, по очереди записывая на четыре пина последовательность полушагов:
1from machine import Pin
2import time
3
4pins = [Pin(n, Pin.OUT) for n in (2, 3, 4, 5)] # IN1–IN4 → GP2–GP5
5SEQ = [[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,1,1,0],
6 [0,0,1,0],[0,0,1,1],[0,0,0,1],[1,0,0,1]] # yarım adım dizisi / half-step sequence
7
8def rotate(steps, delay_ms=2):
9 direction = 1 if steps > 0 else -1
10 for i in range(abs(steps)):
11 for pin, value in zip(pins, SEQ[(i * direction) % 8]):
12 pin.value(value)
13 time.sleep_ms(delay_ms)
14 for pin in pins:
15 pin.value(0) # bobinleri bırak / release coils
16
17rotate(4096) # bir tur / one turn (half-step)
18rotate(-1024) # çeyrek tur geri / quarter turn backИдеи проектов с шаговым двигателем
- Стрелочные часы: настольные часы, часовую и минутную стрелки которых вращают шаговые двигатели.
- Слайдер для камеры: рельс, который очень медленно двигает камеру для таймлапс-съёмки.
- Автоматическая кормушка для рыб: механизм, который дважды в день поворачивает бункер и высыпает корм.
- Панель, следящая за солнцем: поворачивай панель в самую яркую сторону с помощью двух датчиков света; про датчики читай в статье Фоторезистор (LDR).
- Поворотный столик: столик, который равными шагами поворачивает предмет для предметной съёмки или 3D-сканирования.
- Автоматическая штора: мотор, который открывает и закрывает штору, наматывая шнур, и запоминает своё положение.
Частые ошибки и как их исправить
- Мотор вибрирует, но не вращается: неправильный порядок пинов в библиотеке Stepper; пиши 8, 10, 9, 11 вместо 8, 9, 10, 11.
- Мотор пропускает шаги: слишком высокая скорость или тяжёлая нагрузка; держи 28BYJ-48 ниже 15 об/мин и добавь разгон с AccelStepper.
- Arduino перезагружается: не хватает питания; питай мотор от внешнего источника 5 V и соедини земли.
- Мотор греется, стоя на месте: катушки остаются под током; подавай LOW на все четыре пина, когда движение закончено.
- Число оборотов не сходится: в режиме полного шага 2048 шагов, в режиме полушага 4096, а у NEMA 17 — 200. Не путай режим и мотор.
- Мотор не вращается с A4988: слишком низкое ограничение тока, нет питания мотора, или пины RESET и SLEEP не соединены между собой.
Шаговый двигатель — самый простой способ сказать «повернись ровно на столько», и на нём основаны станки вроде фрезеров с ЧПУ и 3D-принтеров. В приложении BlueGrays есть пошаговые проекты со схемами подключения и кодом: работа с шаговым двигателем 28BYJ-48 и сервопривод на 360 градусов из шагового двигателя.
Частые вопросы
Сколько шагов на оборот делает 28BYJ-48?
Около 2048 в режиме полного шага и около 4096 в режиме полушага. Передаточное число редуктора не ровно 1:64, поэтому на очень длинных перемещениях может накапливаться небольшая погрешность; для точной работы полезно время от времени обнулять положение по концевому выключателю.
Почему мой шаговый двигатель вибрирует, но не вращается?
Чаще всего катушки включаются в неправильном порядке. В библиотеке Stepper для Arduino пины 28BYJ-48 нужно писать в порядке 8, 10, 9, 11 (IN1, IN3, IN2, IN4). Мотор может вибрировать вместо вращения и при слишком высокой скорости или слишком слабом питании.
Можно ли питать ULN2003 от пина 5V Arduino?
Для одного 28BYJ-48 обычно да: мотор потребляет около 240 mA, и USB с этим справляется. С двумя моторами, сервоприводами или другими нагрузками стабилизатор Arduino и USB-порт перегружаются; в этом случае используй внешний источник 5 V и соедини земли.
Как шаговый двигатель знает своё положение?
Шаговый двигатель не измеряет положение, а знает его, считая сделанные шаги. Поэтому при запуске мотор стоит отвести в опорную точку (например, к концевому выключателю) и обнулить, а также избегать пропуска шагов из-за перегрузки или высокой скорости.
Что выбрать: шаговый двигатель или сервопривод?
Если достаточно повернуться на угол от 0 до 180 градусов и удерживать его, сервопривод проще, и драйвер у него встроенный. Для задач, где нужны несколько оборотов, большой крутящий момент на малой скорости или очень точное позиционирование, выбирай шаговый двигатель.
Чем 28BYJ-48 отличается от NEMA 17?
28BYJ-48 — маленький дешёвый мотор на 5 V, который благодаря редуктору вращается медленно, но точно. NEMA 17 — гораздо более сильный и быстрый биполярный мотор, который делает 200 шагов на оборот; ему нужен драйвер вроде A4988 и питание 12–24 V. 28BYJ-48 подходит для хобби-проектов, а NEMA 17 используют в станках вроде 3D-принтеров и фрезеров с ЧПУ.
Что собрать после прочтения
Все проекты
Работа с шаговым мотором
Мотор, который поворачивается шаг за шагом ровно настолько, насколько нужно, как стрелка часов. Через плату драйвера Arduino поворачивает маленький шаговый мотор на полный оборот в одну сторону, ждёт

Сервопривод на 360 градусов из шагового мотора
Научи обычный шаговый мотор вставать на любой нужный угол по всему кругу. Arduino вычисляет, сколько шагов нужно для каждого угла; мотор по очереди поворачивается на 0, 90, 45, 180, 135 и 360 градусов

Управление сервоприводом джойстиком
Управляй двумя моторами джойстиком, как будто поворачиваешь камеру наблюдения. Наклони рычажок влево или вправо, и нижний сервопривод медленно поворачивается, наклони вверх или вниз — верхний сервопри

Сервопривод на ESP32 (управление потенциометром)
В этом проекте сервопривод SG90 управляется потенциометром. Угол сервопривода задаётся сопоставлением аналогового значения потенциометра с диапазоном 0–180 градусов. Библиотека ESP32Servo формирует сигналы сервопривода на подходящих выходных пинах GPIO у ESP32; этот проект использует GPIO 18. Это базовый способ управления для роборук, подвесов камер и механизмов автоматических дверей.

Машинка на L298N с управлением по Bluetooth
Преврати телефон в пульт и управляй своей машинкой-роботом. Arduino получает команды из приложения-пульта на телефоне через Bluetooth-модуль и вращает колёса через драйвер моторов; машинка едет вперёд

Робот, объезжающий препятствия
Как насчёт того, чтобы собрать умную машину, которая сама находит дорогу? Робот, объезжающий препятствия, постоянно осматривает всё вокруг благодаря ультразвуковому датчику спереди. Встретив препятств

Управление светодиодами джойстиком
Наклони рычажок джойстика до упора в любую сторону, и загорится светодиод этого направления: вправо, влево, вверх и вниз — четыре разных цвета. Отпусти рычажок, он вернётся в центр, и все светодиоды п

Парктроник на ESP32 (HC-SR04 + шкала из 5 светодиодов + зуммер + OLED)
ESP32-версия автомобильного парктроника! Ультразвуковой датчик HC-SR04 измеряет расстояние до предмета перед ним. По мере уменьшения расстояния шкала из 5 светодиодов заполняется (зелёный → жёлтый → красный), а интервал сигналов зуммера сокращается. Когда предмет совсем близко (меньше 10 см), звучит непрерывная тревога и горят все светодиоды. OLED SSD1306 показывает расстояние в см крупным шрифтом и сообщение состояния (STOP / CAUTION / CLOSE / STOP! / DANGER).
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

