Шаговый мотор, в отличие от обычного мотора постоянного вращения, вращается пошагово и позволяет точно установить свой вал на заданный угол. В отличие от сервопривода не имеет обратной связи по углу поворота (не знает, где сейчас находится вал), но зато может вращаться без ограничений и с очень высокой точностью. Шаговые моторы используются в ЧПУ станках и прочих устройствах с точным позиционированием частей механизма (2D/3D принтеры, манипуляторы, плоттеры...). В наборе GyverKIT идёт шаговый мотор 28BYJ-48 с драйвером ULN2003:
Драйвер #
![]() |
В наборе GyverKIT | START | IOT | EXTRA |
---|---|---|---|---|
Шаговый драйвер | ✔ |
- Питание: до 50 V
- Ток: до 500 mA на канал
Мотор #
![]() |
В наборе GyverKIT | START | IOT | EXTRA |
---|---|---|---|---|
Шаговый мотор | ✔ |
- Тип: униполярный
- Питание: 5V
- Шагов на оборот (сам мотор): 32
- Шагов на оборот (на выходном валу): 2038
- Передаточное отношение редуктора: 1:63.68395
- Максимальная скорость (шагов в секунду): 400
- Максимальная скорость (оборотов в минуту): 12
Фазы мотора выведены следующим образом:
Подключение к Arduino #
Мотор управляется через драйвер, который по сути усиливает сигнал с пинов МК. Драйвер подключается к питанию 5V, а 4 управляющих входа – к любым цифровым пинам МК. Фаза мотора потребляет около 100 мА, поэтому возможно питание драйвера напрямую от платы Arduino.
Программирование #
Для вращения мотора нужно подавать сигналы на пины драйвера в определённой последовательности:
Вот пример full-step режима. Пины я указываю в порядке A+, A-, B+, B-
, т.е. средние пины при подключении (или в программе) нужно поменять местами.
// средние два пина меняем местами!
#define DRV_PIN_1 2
#define DRV_PIN_2 4
#define DRV_PIN_3 3
#define DRV_PIN_4 5
void _write4(bool p0, bool p1, bool p2, bool p3) {
digitalWrite(DRV_PIN_1, p0);
digitalWrite(DRV_PIN_2, p1);
digitalWrite(DRV_PIN_3, p2);
digitalWrite(DRV_PIN_4, p3);
}
// сделать шаг в направлении (0 или 1)
void step(bool dir) {
static uint8_t curstep;
dir ? ++curstep : --curstep;
switch (curstep & 0b11) {
case 0: _write4(1, 0, 1, 0); break;
case 1: _write4(0, 1, 1, 0); break;
case 2: _write4(0, 1, 0, 1); break;
case 3: _write4(1, 0, 0, 1); break;
}
}
void setup() {
pinMode(DRV_PIN_1, OUTPUT);
pinMode(DRV_PIN_2, OUTPUT);
pinMode(DRV_PIN_3, OUTPUT);
pinMode(DRV_PIN_4, OUTPUT);
}
void loop() {
// 500 шагов в одну сторону
int steps = 500;
while (steps--) {
step(0);
delay(5);
}
// 1000 шагов в обратную
steps = 1000;
while (steps--) {
step(1);
delay(5);
}
}
Библиотеки #
Для шаговых моторов существует несколько библиотек, самые известные из них:
Stepper
– стандартная (идёт в комплекте с Arduino IDE) библиотека с минимальными возможностями- AccelStepper – позволяет вращать мотор с плавным ускорением и торможением
- GyverStepper – моя библиотека с большим количеством возможностей и эффективными алгоритмами движения, читайте на странице библиотеки
GyverStepper2 #
Данный пример просто крутит мотор на один пол оборота, затем возвращает обратно. Каждый раз ждём, когда мотор приедет на позицию.
Код
#include "GyverStepper2.h"
GStepper2<STEPPER4WIRE> stepper(2038, 2, 4, 3, 5);
void setup() {
stepper.setMaxSpeed(400); // скорость движения к цели
stepper.setTargetDeg(180); // отправляем на 180 градусов
}
void loop() {
while (stepper.tick()); // ждём, когда мотор доедет
stepper.setTargetDeg(0); // отправляем обратно
while (stepper.tick()); // ждём, когда мотор доедет
stepper.setTargetDeg(180); // отправляем на 180
}
Библиотека позволяет двигать мотор не блокируя выполнение кода, поэтому можно переписать следующим образом:
Код
#include "GyverStepper2.h"
GStepper2<STEPPER4WIRE> stepper(2038, 2, 4, 3, 5);
void setup() {
Serial.begin(115200);
stepper.setMaxSpeed(400); // скорость движения к цели
stepper.setTargetDeg(0); // начинаем движение с позиции 0
}
bool dir = 1; // направление
void loop() {
// движение мотора происходит здесь
stepper.tick();
// если мотор доехал до заданной позиции
if (stepper.ready()) {
dir = !dir; // разворачиваем (меняется 1,0,1,0...)
stepper.setTargetDeg(dir * 180); // едем в другую сторону (0 или 180)
}
// асинхронно вывожу в порт графики
static uint32_t tmr;
if (millis() - tmr >= 20) {
tmr = millis();
Serial.println(stepper.pos);
}
}
В библиотеке также есть поддержка движения с ускорением, добавим настройку setAcceleration()
:
Код
#include "GyverStepper2.h"
GStepper2<STEPPER4WIRE> stepper(2038, 2, 4, 3, 5);
void setup() {
Serial.begin(115200);
stepper.setAcceleration(500); // ускорение
stepper.setMaxSpeed(400); // скорость движения к цели
stepper.setTargetDeg(0); // начинаем движение с позиции 0
}
bool dir = 1; // направление
void loop() {
// движение мотора происходит здесь
stepper.tick();
// если мотор доехал до заданной позиции
if (stepper.ready()) {
dir = !dir; // разворачиваем
stepper.setTargetDeg(dir * 180); // едем в другую сторону
}
// асинхронно вывожу в порт графики
static uint32_t tmr;
if (millis() - tmr >= 20) {
tmr = millis();
Serial.println(stepper.pos);
}
}
Также в библиотеке можно отправить мотор вращаться с заданной скоростью:
Код
#include "GyverStepper2.h"
GStepper2<STEPPER4WIRE> stepper(2038, 2, 4, 3, 5);
void setup() {
stepper.setSpeedDeg(90); // крутимся 90 градусов в секунду
}
void loop() {
// движение мотора происходит здесь
stepper.tick();
}
Полезные страницы #
- Набор GyverKIT – наш большой стартовый набор Arduino, продаётся в России
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])
- Поддержать автора за работу над уроками