Skip to contentSkip to main navigation Skip to footer

Arduino и шаговый мотор

Описание


Шаговый мотор, в отличие от обычного мотора постоянного вращения, вращается пошагово и позволяет точно установить свой вал на заданный угол. В отличие от сервопривода не имеет обратной связи по углу поворота (не знает, где сейчас находится вал), но зато может вращаться без ограничений. Шаговые моторы используются в ЧПУ станках и прочих устройствах с точным позиционированием частей механизма (2D/3D принтеры, манипуляторы, плоттеры…). В наборе GyverKIT идёт шаговый мотор 28BYJ-48 с драйвером ULN2003:

Данный мотор питается от 5V, имеет 32 шага на оборот (в полношаговом режиме) и встроенный редуктор с отношением 1/63.68395. Таким образом получается 2038 шагов на один оборот выходного вала.

Фазы мотора выведены следующим образом:

Подключение


Мотор управляется через драйвер, который по сути усиливает сигнал с пинов микроконтроллера (подключать моторы напрямую к пинам нельзя!). Драйвер подключается к питанию 5V, а 4 управляющих входа – к любым цифровым пинам МК. Фаза мотора потребляет около 100 мА, поэтому возможно питание драйвера напрямую от платы Arduino.

Библиотеки


Для шаговых моторов существует несколько библиотек, самые известные из них:

  • Stepper – стандартная (идёт в комплекте с Arduino IDE) библиотека с минимальными возможностями
  • AccelStepper – позволяет вращать мотор с плавным ускорением и торможением
  • GyverStepper – моя библиотека с большим количеством возможностей и эффективными алгоритмами движения, читайте на странице библиотеки. Также есть расширенная документация

В примерах на этом сайте мы будем использовать GyverStepper как самую удобную и функциональную. Библиотека идёт в архиве к набору GyverKIT, а свежую версию всегда можно установить/обновить из встроенного менеджера библиотек Arduino по названию GyverStepper. Краткая документация находится по ссылке выше, базовые примеры есть в самой библиотеке.

Примеры


Воспользуемся версией библиотеки GyverStepper2 (входит в набор GyverStepper). Создаём объект GStepper2, в угловых скобках указываем тип драйвера STEPPER4WIRE, так как используем 4х проводной драйвер. Далее в круглых скобках – количество шагов на один оборот и пины в порядке (фаза А1, фаза А2, фаза В1, фаза В2). Из второй картинки (с описанием проводов мотора) видно, что первая фаза это провода 2 и 4, а вторая – 3 и 1. Драйвер не меняет порядок проводов, поэтому в программе нам нужно будет указать пины в порядке (1, 3, 2, 4), т.е. центральные нужно поменять местами. На схеме я подключил драйвер к пинам D2, D3, D4, D5, и в программе укажу их как (2, 4, 3, 5). Если прописать по порядку пинов – мотор будет работать некорректно!

Данный пример просто крутит мотор на один пол оборота, затем возвращает обратно. Каждый раз ждём, когда мотор приедет на позицию.

Пример 1
#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
}

Библиотека позволяет двигать мотор не блокируя выполнение кода, поэтому можно переписать следующим образом:

Пример 2
#include "GyverStepper2.h"
GStepper2< STEPPER4WIRE> stepper(2038, 2, 4, 3, 5);

void setup() {
  Serial.begin(9600);
  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()

Пример 3
#include "GyverStepper2.h"
GStepper2< STEPPER4WIRE> stepper(2038, 2, 4, 3, 5);

void setup() {
  Serial.begin(9600);
  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);
  }
}

Мотор перестанет дёргаться при смене направления движения, а график будет выглядеть вот так:

Также в библиотеке можно отправить мотор вращаться с заданной скоростью

Пример 4
#include "GyverStepper2.h"
GStepper2< STEPPER4WIRE> stepper(2038, 2, 4, 3, 5);

void setup() {
  stepper.setSpeedDeg(90);    // крутимся 90 градусов в секунду
}

void loop() {
  // движение мотора происходит здесь
  stepper.tick();
}

Домашнее задание


  • Изучить остальные возможности библиотеки

 

Связанные уроки

Полезный пример?

Похожие примеры
4 Комментария
  • Алекс, добрый день. С интересом читаю периодически материалы сайта, спасибо, много полезного нашёл в них и решений вопросов.
    Есть еще один, не совсем по теме, просто не знаю куда еще написать можно.
    В общем как измерить ток потребления шагового двигателя. Но самой же ардуиной/есп, которая и управляет двигателем этим. Суть в том, чтобы если в устройстве сломался выключатель или еще какой-то форс-мажор, чтобы можно было понять, что двигатель работает, но, например, упёрся. Чтобы не перегорел. Подскажешь какую-то идею? Готовое решение не особо интересует, хочется понять вообще в какую сторону двигаться.
    Спасибо )

    • Подойдёт как вариант. ШД буду использовать для переворота яиц. 2 концевика по обе стороны воздействуют напрямую на драйвер (ВКЛ, ВЫКЛ). Программно-же прописываю регламент времени чуть больший чем время отведённое для выполнения одного действия. В форс-мажопе программный таймер всё равно отключит ШД.

      • Смешно лепить для этого шаговик, можно простой моторчик. Концевики включают поочередно реверс. Делал такое для шлифовки ножей из старой печатной машинки . БП, мотор, две релюшки и 2 концевика. Для яиц наверно ещё реле времени понадобится.

  • Полностью согласен. Но есть большое НО. Леплю (И не только это) из того что есть. Шаговики с разбора по 10 рублей(ДЕСЯТЬ!!!!) за 1 штуку + резьбовая шпилька на М10 с кореткой. Мотор не хилый “M55SP-2NK” без редуктора прёт. К простому моторчику ещё редуктор нужен. Мозги- ардуинка и ещё некоторые модули с Алишки.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *