Микроконтроллеры Arduino, Электронные компоненты, Сенсоры и Радиодетали

Управление шаговым двигателем NEMA17 с помощью Arduino

Опубликовано: 17.10.2022

 

Биполярный шаговый двигатель используется в роботизированных механизмах таких как 3D-принтеры, станки с ЧПУ, игрушки и так далее. Особенностью шагового двигателя является дискретное вращение. То есть, при подаче на обмотку двигателя импульса совершается небольшой поворот ротора. Шаговый двигатель износостойкий, потому что не имеет в своей конструкции щёток, которые соприкасаются с ротором. Биполярный двигатель имеет по одной обмотке для каждой фазы движения магнитного ротора.

Рис. 1 Биполярный двигатель

 

Вариантов управления двигателем может быть несколько в зависимости от поставленной задачи. Но самый простой способ – это использование драйвера двигателя, который и предназначен для управления биполярными шаговыми двигателями. На рисунке снизу компактный драйвер двигателя с платой расширения.

Рис. 2 Драйвер шагового двигателя A4988 на плате расширения

 

Плата расширения для драйверов шаговых двигателей позволяет упростить подключение драйверов к микроконтроллеру Arduino и управлять двигателем задавая шаг вращения, время вращения, а также направление движения.

Возможности данной платы и драйвера ограничиваются управлением только одного шагового двигателя. Используя такой вариант подключение проще всего изучить и понять взаимодействие микроконтроллера и шагового двигателя и, соответственно, научится управлять шаговиком.

В нашем проекте используются:

  1. Шаговый двигатель NEMA17
  2. Драйвер шагового двигателя A4988
  3. Плата расширения для драйверов шаговых двигателей A4988/DRV8825
  4. Микроконтроллер Arduino UNO R3
  5. Тактовая кнопка на модуле KY-004

 

Подключение шагового двигателя к микроконтроллеру

 

Чтобы подключить шаговый двигатель к плате расширения, достаточно соединить штатные разъёмы на двигателе и плате кабелем, который обычно входит в комплект при покупке NEMA17. Сложностей с подключением не должно возникнуть, так как разъемы стандартные.

Рис. 3 Подключённые устройства

 

Единственная сложность может возникнуть с управляющими пинами. Поэтому внимательно посмотрите на плату расширения драйвера шагового двигателя. На ней вы найдёте пины, которые обозначены:

  • S – step – шаг,
  • D – direction – направление,
  • E – enable – включить-выключить двигатель (подача питания на его обмотки).

Так же на плате есть пины питания:

  • – напряжение питания,
  • – напряжение питания,
  • GND – земля.

Не забудьте правильно подключить питание и платы расширения. Основное питание схемы происходит через штатный разъем Arduino блоком питания 9В с током не менее 1А. Ни в коем случае не запитывайте схему только от USB-разъема, т.к. это может привести к выходу контроллера из строя. Далее питание драйвера и двигателя производится  с контроллера. с пина на Arduino UNO, земля GND так же подключается к микроконтроллеру к соответствующему пину. подключаются к разъёму на контроллере, который обозначается как VIN. Управляющие пины платы расширения S, D, E в нашем проекте мы подключаем к цифровым пинам микроконтроллера D2, D3, D4. Проверьте подключение, сверившись с таблицей ниже.

Рис. 4 Таблица подключения платы расширения драйвера двигателя к Arduino UNO

 

Справка:

Двигатель NEMA17 сконструтрован таким образом, что совершает 200 шагов за оборот в стандартном полношаговом режиме. Каждый шаг поворачивает ротор на 1,8 градуса.

Для обеспечения работы двигателя в разных режимах на плате расширения есть переключатели. Разное положение переключателей задаёт разный режим работы. Это удобно при решении некоторых задач. Режимы работы смотрите в таблице ниже:

Рис. 5 Режимы работы шагового двигателя в соответствии с расположением переключателей на плате расширения.

 

Для нашего проекта мы будем использовать микрошаговый режим, соответствующий 1/16 шага. Для этого передвиньте все переключатели на плате расширения двигателя в положение ON.

Примечание: Изменяя режим работы шагового двигателя можно менять скорость вращение и количество оборотов.

 

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

Кнопку подключаем двумя проводами. К шестому пину D6 на плате микроконтроллера подключаем управляющий разъем кнопки, обозначенный буквой S. Контакт, обозначенный «-» мы подключаем к GND на плате микроконтроллера.

Питание микроконтроллера производится от блока питания 9В.

Далее подключаем микроконтроллер к компьютеру и переходим к его программированию.

 

Разбор скетча управления шаговым двигателем

 

Вы можете скачать полный скейч, который мы здесь используем по этой ссылке.

 

Первые строки нашего кода определяют какие пины мы используем для управления шаговиком и для управления кнопкой:

//Пины управления шаговиком

#define STEP_PIN         2

#define DIR_PIN          3

#define ENABLE_PIN       4

//Пин кнопки

#define start_button 6

 

Далее необходимо определить переменные для управления временем поворота и паузы, то есть задержки между импульсами. Задержка считается в микросекундах (1000 мксек = 1 мсек = 0.001 сек.). Обратите внимание, что, чем больше задержка между импульсами, тем медленнее вращается двигатель. И ещё один важный момент, не рекомендуется устанавливать время меньше 100 мксек.

 

В этой части кода можно настроить время поворота и паузы.

#define move_forward_time 3000    //время прямого хода в мсек

#define move_back_time 3000       //время обратного хода в мсек

#define pause_time 4000           //время паузы в мсек

#define frequency 2250            //Время между импульсами в мксек.

 

Определяем переменную для хранения времени.

//Таймер для millis()

uint32_t timer = 0;

 

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

//Логический флаг для рабочего режима

bool flag = 0;

 

После определения переменных необходимо настроить микроконтроллер для работы.

Раздел setup в программе как раз делает это:

void setup() {

  pinMode(start_button, INPUT_PULLUP);  //Подтягиваем кнопку к питанию

 

  pinMode(STEP_PIN   , OUTPUT);       //Настраиваем пины управления

  pinMode(DIR_PIN    , OUTPUT);

  pinMode(ENABLE_PIN , OUTPUT);

 

  digitalWrite(ENABLE_PIN , HIGH);    //Выключаем мотор, чтобы не грелся

}

 

Здесь мы задаём режим работы пинов, к которым мы подключили кнопку и плату расширения драйвера двигателя.  Обратите внимание на последнюю строчку кода, данной командой мы выключаем двигатель. Шаговик будет выключен тогда, когда мы подаём напряжение на Pin ENABLE. В противном случае мотор будет греться.

Далее в программе следует основной цикл loop, где происходит вся обработка событий. Напомню, что смысл нашей задачи сводится к тому, что при нажатии на кнопку двигатель совершил вращение. Поэтому первым условием в основном цикле будет проверка нажата ли кнопка. Соответственно, если кнопка нажата, то переменная flag становится равна единице. Это будет означать, что у нас рабочий режим. В этом же условии мы включаем мотор и запускаем таймер присваивая переменной timer значения функции millis().

 

void loop () {

  if (!digitalRead(start_button)) {       //Если нажали на кнопку

    digitalWrite(ENABLE_PIN , LOW);       //Включаем мотор

    flag = 1;                             //Активируем флаг рабочего режима

    timer = millis();                     //Запускаем таймер

  }

Управление по времени при нажатии на кнопку

 

Уточняем нашу задачу. Сделаем так, чтобы при нажатии на кнопку двигатель начинал вращение по часовой стрелке три секунды, потом делал бы паузу и после совершил несколько оборотов назад за то же время.

Эти параметры мы настроили в самом начале программы:

  • move_forward_time 3000 время прямого хода в мсек по часовой стрелке.
  • define move_back_time 3000 время обратного хода в мсек против часовой стрелки.
  • define pause_time 4000 время паузы в мсек.
  • define frequency 2250 Время между импульсами в мксек.

Эти параметры можно менять в зависимости от условия задачи.

 

Далее будет следующий цикл:

 

if (flag) {                                 //Если флаг активирован

    digitalWrite(DIR_PIN    , HIGH);         //Задаем направление вращения

 

Если мы нажали на кнопку и у нас включился рабочий режим, то есть переменная flag равна единице, то сначала задаём направление вращения двигателю подавая на управляющий Pin DIR напряжение.

Далее в цикле будем использовать ещё один цикл do while, условие которого проверяется в конце цикла.

 

do {                                      //Крутим движок move_forward_time мсек

      digitalWrite(STEP_PIN    , HIGH);

      delayMicroseconds(frequency);

      digitalWrite(STEP_PIN    , LOW);

    } while (millis() - timer < move_forward_time);

 

Задача этого цикла заставить двигатель вращаться три секунды по часовой стрелке. Мы попеременно подаём и отключаем напряжение на управляющем Pin STEP с задержкой frequency = 2250 микросекунд. Это примерно соответствует 10 оборотам в минуту для двигателя NEMA17, который мы используем в проекте. Чем меньше частота задержки, тем быстрее будет вращаться двигатель. Цикл будет работать до тех пор, пока заданное время в переменной move_forward_time будет больше величины millis() – timer. Такая формула применяется по причине того, что функция millis() уже запущена и в момент нажатия кнопки мы фиксируем её значение записывая в переменную timer. Именно от этого значения нам нужно отсчитать время три секунды. Таким образом функция millis() всё время увеличивает своё значение, а timer остаётся постоянной. Когда разница между millis() – timer составит три секунды – то условие сработает и цикл завершится.

Обратите ваше внимание на то, что все эти операции происходят в цикле if и далее тоже. После того, как двигатель совершил вращение по часовой стрелке в течении трёх секунд, по условию задачи мы должны сделать паузу.

delay(pause_time);                        //Пауза pause_time мсек

timer = millis();                         //Снова запускаем таймер

digitalWrite(DIR_PIN    , LOW);        //Крутим движок move_back_time мсек

 

Пауза у нас задавалась переменной pause_time. Для паузы используем функцию delay. Далее снова фиксируем новое значение функции millis() в момент начала следующего цикла. Теперь нам необходимо поменять направление вращения двигателя подавая на управляющий Pin DIR сигнал LOW – это будет соответствовать вращению двигателя против часовой стрелки.

do {

      digitalWrite(STEP_PIN    , HIGH);

      delayMicroseconds(frequency);

      digitalWrite(STEP_PIN    , LOW);

    } while (millis() - timer < move_back_time);

    flag = 0;                                 //Гасим флаг

    digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся

  }

}

Данный цикл вращения практически повторяет предыдущий за исключением последних двух строк. После завершения вращения в обратную сторону, нам необходимо обнулить переменную flag, чтобы основной цикл программы не повторялся и снова ждал нажатия на кнопку. Для этого присваиваем переменной flag значение ноль. Этим мы даём понять программе, что двигатель завершил программу и находится в нерабочем режиме. И в целях экономии энергии выключаем двигатель.

Поздравляем! Вы научились управлять шаговым двигателем задавая ему параметры времени и направление вращения.

 

Управление по числу шагов

 

А теперь научимся управлять двигателем с заданным количеством шагов. Для этого поменяем основный цикл программы на такой:

void loop () {

  if (!digitalRead(start_button)) {       //Если нажали на кнопку

    digitalWrite(ENABLE_PIN , LOW);       //Включаем мотор

    flag = 1;                             //Активируем флаг рабочего режима

    timer = millis();                     //Запускаем таймер

  }

 

  if (flag) {                                 //Если флаг активирован

    digitalWrite(DIR_PIN    , HIGH);         //Задаем направление вращения

 

    for (int i = 0; i < 200; i++) {          //Выполняем нужное число шагов 200*16 = 3200 шагов оборот

    digitalWrite(STEP_PIN    , HIGH);

    delayMicroseconds(frequency);

    digitalWrite(STEP_PIN    , LOW);

    }

    flag = 0;

 

  }

}

 

Новым в этом коде станет только часть основного цикла, следующая за включением кнопки. То есть, когда программа обнаружила, что кнопка нажата, то активируется рабочий режим, включается мотор и срабатывает следующий код:

if (flag) {                                 //Если флаг активирован

    digitalWrite(DIR_PIN    , HIGH);         //Задаем направление вращения

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

for (int i = 0; i < 3200; i++) {         

Цикл for будет выполняться до тех пор, пока переменная i будет меньше 3200. Откуда взялась цифра 3200 и что она означает? Наш двигатель работает с расчётом, что один шаг равен 1,8 градуса. Соответственно полный оборот двигателя будет совершён за 200 шагов. Поскольку мы переключили режим работы двигателя в микрошаговый режим, а это 1/16 шага, то, соответственно, умножаем 200 шагов на 16 и получаем 3200 шагов за оборот. Таким образом нижеследующий код, который попеременно подаёт и отключает напряжение на управляющем Pin STEP с задержкой frequency = 2250 микросекунд, будет выполнен 3200 раз и цикл for завершится, а двигатель совершит один оборот.

    digitalWrite(STEP_PIN    , HIGH);

    delayMicroseconds(frequency);

    digitalWrite(STEP_PIN    , LOW);

    }

Как только цикл for завершился, то необходимо присвоить переменной flag нулевое значение, чтобы завершить рабочий режим.

    flag = 0;

  }

 

Теперь вы научились управлять шаговым двигателем задавая количество шагов!

Для работы данного скетча не нужно устанавливать дополнительных библиотек. Скетч вы можете скачать по этой ссылке.

Комментарии (0)
Пока нет комментариев
Вы не представились
Не правильно введен e-mail
Нам интересно Ваше мнение
Все поля обязательны к заполнению
Перед публикацией комментарии проходят модерацию

Главное меню

Каталог

Полезные ссылки

Цена
от
до
0 Корзина: 0 руб.