На производстве и в быту при автоматической работе каких-либо механизмов часто требуется точное позиционирование рабочего органа или оснастки. Для этого могут использоваться серво приводы и шаговые двигатели. Эти два вида электропривода значительно отличаются, как по конструкции, так и по особенности работы и управления. В этой статье мы затронем тему работы с шаговыми двигателями с помощью Arduino и модуля для управления электродвигателями на базе ИМС ULN2003.
Что такое шаговый двигатель?
Прежде чем перейти к статье, давайте сразу договоримся, что статья не направлена на специалистов, а её цель – донести любознательным любителям техники и технологий о таком устройстве, как шаговый двигатель и об основах работы с ними. Поэтому умников и критиков, жаждущих поговорить о великом многообразии управляемого и регулируемого электропривода, прошу идти общаться на тематические ресурсы по ЧПУ-станкам и 3D-принтерам.
Итак, для начала сформулируем определение. Согласно Википедии: «Шаговый электродвигатель — синхронный бесщёточный электродвигатель с несколькими обмотками, в котором ток, подаваемый в одну из обмоток статора, вызывает фиксацию ротора. Последовательная активация обмоток двигателя вызывает дискретные угловые перемещения (шаги) ротора».
Формулировка достаточно понятна, но её последнее предложение может вызвать некоторое недопонимание. Поэтому я предлагаю провести небольшое сравнение.
Всем известно что ротор «обычного» электродвигателя, будь то асинхронного, синхронного, коллекторного или любого другого будет вращаться до тех пор, пока на него подают напряжение питания, и после отключения питания он будет вращаться еще какое-то время по инерции, если же не используются какие-либо средства для его торможения.
Ротор такого двигателя вращается просто вокруг своей оси без каких-либо ограничений, на 360 градусов, и остановится он в любом месте. Зафиксировать его положением можно только механически (тормозом). По этой причине не получится добиться точного позиционирования исполнительных механизмов, что требуется в робототехнике, ЧПУ-станках и другом автоматизированном оборудовании.
Но шаговые двигатели разработаны для применения в механизмах, где детали поворачиваются точно на требуемый угол.
В приведенном выше определении было сказано «…вызывает дискретные угловые перемещения (шаги) ротора…» — это значит, что ротор шагового двигателя не вращается в обычном понимании, а поворачивается на какой-то определенный, «дискретный» угол. Этот угол называется шагом, отсюда и название «шаговый двигатель». Мне нравится еще одно название этих устройств — «двигатель с конечным числом положений ротора».
Питание такого двигателя невозможно без системы управления, или как его еще называют, драйвера — он подаёт импульсы в нужные обмотки, чтобы повернуть ротор на нужный угол. Это наглядно иллюстрирует приведенная ниже анимация.
Кроме того, что можно поворачивать двигатель на определенный угол и фиксировать его в этом положении, делать это всё можно без схемы обратной связи (датчиков положения и прочего).
Рассматривать типы шаговых двигателей в пределах этой статьи мы не будем, лишь кратко перечислим, какими они бывают. По конструкции:
- Реактивные.
- С постоянными магнитами.
- Гибридные.
По способу питания:
- Униполярные (однополярные — ток пропускают через обмотки только в одну сторону).
- Биполярные (ток пропускают через обмотки в обе стороны). Здесь драйвер должен подавать напряжение различной полярности, что несколько усложняет схемотехнику. При тех же размерах развивают бОльшую мощность по сравнению с униполярными.
В униполярном двигателе зачастую 5 проводов — 1 общий, от середины каждой из двух обмоток, и 4 от концов обмоток. Иногда говорят «4 обмотки» – это также правильно, поскольку фактически мы получаем 4 обмотки соединенных в общей точки.
Также ШД могут отличаться и по количеству проводов, это зависит от того, как соединены обмотки и какое питание предполагается, некоторые варианты вы видите в таблице ниже.
Управление шаговым двигателем
Различают два способа управления шаговым двигателем:
- Полношаговое. Одновременно включается только пара обмоток (без перекрытия с другими). Достигается максимальный момент на валу, но точность установления угла меньше, чем в других способах.
- Полушаговое. В этом случае увеличивается количество шагов, соответственно повышается точность установки положения вала. На каждый первый шаг включается одна обмотка, на каждый второй шагами (полушаг) – пара обмоток. Но когда включена одна обмотка момент на валу снижается вдвое.
На анимациях ниже наглядно продемонстрировано
Полношаговое управление
Полушаговое управление
В некоторых источниках отдельно обозначают микрошаговое управление. Используется, когда необходимо максимальное количество шагов и точность управления. По способу управления оно похоже на полушаговый режим, между шагами включаются две обмотки, а отличие в том, что токи в них распределяются не равномерно. Главный недостаток такого подхода — усложняется коммутация (система управления).
к содержанию ↑Перейдем к практике
Теория всегда запутана и непонятна, чтобы разобраться, что и как, нужно брать и делать. Поэтому перейдем к практической стороне вопроса.
Итак, из рассмотренного ранее набора у меня есть:
- Arduino UNO;
- Модуль ULN2003;
- Шаговый двигатель 28BYJ-48 5V DC;
- Куча перемычек, бредборд и источник питания для него.
Модуль ULN2003 – предназначен для управления униполярным шаговым двигателем. Схематически это транзисторная сборка Дарлингтона с 7-ю каналами и, в принципе, ею можно управлять чем угодно. Технические характеристики приведены ниже:
- Номинальный ток коллектора одного ключа — 0,5А;
- Максимальное напряжение на выходе до 50 В;
- Защитные диоды на выходах;
- Вход адаптирован к разным видам логики;
- Возможность применения для управления реле.
В модуле, кроме самой микросхемы ULN2003, есть светодиоды для индикации напряжения на выходе, колодка для подключения и перемычка для отключения питания.
Двигатель 28BYJ-48 5V DC подключается штатным разъёмом к белой колодке на плате. У него 5 проводов — красный общий, и 4 от обмоток.
Основные характеристики:
- 32 шага за один оборот ротора;
- Встроенный редуктор с передаточным отношением 63.68395:1, благодаря этому вал делает 1 оборот за 2048 шагов, при полношаговом режиме и 4096 при полушаговом;
- Cкорость вращения: номинальная 15 об/мин, максимальная 25 об/мин;
- Напряжение питания 5 В;
- Ток одной обмотки 160 мА;
- Полный ток: в 4-шаговом режиме 320 мА, при быстром вращении 200 мА.
- Коэффициент редукции: 1/63,68395
- Угол шага ротора (без учета редуктора): при 4-ступенчатой последовательности сигналов управления 11,25 ° (32 шага на оборот); при 8-ступенчатой — 5,625 ° (64 шага на оборот)
- Крутящий момент не менее: 34,3 мНм (120 Гц);
- Тормозящий момент: 600–1200 гсм;
- Тяга: 300 гсм;
- Вес:33 г.
Итак, рассмотрим простейшие примеры управления двигателем без использования библиотек. Как нам известно на обмотки нужно подавать импульсы определенной последовательности.
Значит, попробуем выдать такие сигналы с ардуино. Для этого я подключаю модуль ULN2003 по такой схеме (пин ардуино – контакт модуля)
- 13 – IN1;
- 12 – IN2;
- 11 – IN3;
- 10 – IN4.
Дальше напишем в Arudino IDE код, который будет подавать на выходы сигналы в соответствии с таблицей выше.
// назначим переменные с номерами портов
int in1 = 13;
int in2 = 12;
int in3 = 11;
int in4 = 10;
const int dl = 2; // переменная для задержки
// назначим указанные пины как выходы
void setup() {
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
}
void loop() {
//сформируем сигналы для первого шага
digitalWrite( in1, HIGH );
digitalWrite( in2, HIGH );
digitalWrite( in3, LOW );
digitalWrite( in4, LOW );
delay(dl); //Задержка между шагами, чем она меньше – тем быстрее вращение вала.
//сформируем сигналы для второго шага
digitalWrite( in1, LOW );
digitalWrite( in2, HIGH );
digitalWrite( in3, HIGH );
digitalWrite( in4, LOW );
delay(dl);
//сформируем сигналы для третьего шага
digitalWrite( in1, LOW );
digitalWrite( in2, LOW );
digitalWrite( in3, HIGH );
digitalWrite( in4, HIGH );
delay(dl);
//сформируем сигналы для четвертого шага
digitalWrite( in1, HIGH );
digitalWrite( in2, LOW );
digitalWrite( in3, LOW );
digitalWrite( in4, HIGH );
delay(dl);
}
Двигатель начнет вращаться, скорость вращения задаётся переменной dl. Я её ввёл только для того, чтобы в каждом шаге не вводить задержку вручную. Ниже я приложу видео и в нём для наглядности я показал как вращение с задержкой между шагами равной 2 мс (на 1 мс двигатель просто пищит и не вращается…), и с задержкой в полсекунды, что позволяет наглядно увидеть, в какой последовательности подаются сигналы на обмотки, что позволяет убедиться в том, что напряжение подаётся на две обмотки сразу, согласно таблице выше. При задержке в 2 мс светодиоды светятся как будто все вместе.
Перейдем к полушаговому управлению. В таблице ниже приведен порядок подачи сигналов на обмотки рассматриваемого двигателя для его реализации.
Тогда код будет таким:
// назначим переменные с номерами портов
int in1 = 13;
int in2 = 12;
int in3 = 11;
int in4 = 10;
const int dl = 2; // переменная для задержки
// назначим указанные пины как выходы
void setup() {
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
}
void loop() {
//сформируем сигналы для первого шага
digitalWrite( in1, HIGH );
digitalWrite( in2, LOW );
digitalWrite( in3, LOW );
digitalWrite( in4, LOW );
delay(dl); //Задержка между шагами, чем она меньше – тем быстрее вращение вала.
//сформируем сигналы для второго шага
digitalWrite( in1, HIGH );
digitalWrite( in2, HIGH );
digitalWrite( in3, LOW );
digitalWrite( in4, LOW );
delay(dl);
//сформируем сигналы для третьего шага
digitalWrite( in1, LOW );
digitalWrite( in2, HIGH );
digitalWrite( in3, LOW );
digitalWrite( in4, LOW );
delay(dl);
//сформируем сигналы для четвертого шага
digitalWrite( in1, LOW );
digitalWrite( in2, HIGH );
digitalWrite( in3, HIGH );
digitalWrite( in4, LOW );
delay(dl);
//сформируем сигналы для пятого шага
digitalWrite( in1, LOW );
digitalWrite( in2, LOW );
digitalWrite( in3, HIGH );
digitalWrite( in4, LOW );
delay(dl);
//сформируем сигналы для шестого шага
digitalWrite( in1, LOW );
digitalWrite( in2, LOW );
digitalWrite( in3, HIGH );
digitalWrite( in4, HIGH );
delay(dl);
//сформируем сигналы для седьмого шага
digitalWrite( in1, LOW );
digitalWrite( in2, LOW );
digitalWrite( in3, LOW );
digitalWrite( in4, HIGH );
delay(dl);
//сформируем сигналы для восьмого шага
digitalWrite( in1, HIGH );
digitalWrite( in2, LOW );
digitalWrite( in3, LOW );
digitalWrite( in4, HIGH );
delay(dl);
}
Но на практике такой подход к управлению шаговым двигателем не используется. Для этого есть готовые библиотеки, в Arduino IDE есть встроенная «Stepper». Возьмем из библиотеки готовый пример «Stepper_oneRevolution» и изменим его под наш двигатель, код привожу ниже и в комментариях опишу основные особенности:
#include <Stepper.h>
const int stepsPerRevolution = 2048; // изменить в соответствии с количеством
//шагов вашего двигателя. Вообще здесь задаём количество шагов, на которые повернется двигатель
// мы указали для 1 полного оборота
// назначаем пины, к которым подключен драйвер ШД
Stepper myStepper(stepsPerRevolution, 13, 12, 11, 10);
void setup() {
// указываем номинальную скорость 15 об.мин:
myStepper.setSpeed(15);
// включаем последовательный пор:
Serial.begin(9600);
}
void loop() {
// делаем оборот по часовой стрелке:
Serial.println(“clockwise”); // сообщение в монитор порта
myStepper.step(stepsPerRevolution);
delay(500);
// делаем оборот против часовой стрелке:
Serial.println(“counterclockwise”); // сообщение в монитор порта
myStepper.step(-stepsPerRevolution);
delay(500);
}
Первое что бросается в глаза – код занимает значительно меньше времени, количество шагов для полного оборота ротора задаётся первым аргументом функции Stepper, с её помощью объявляются пины, к которым подключен двигатель и количество шагов в полном обороте вала её синтаксис такой:
Stepper название (количество шагов в полном обороте, пин 1, пин 2, пин 3, пин 4).
Ну а когда нам нужно вращать сам двигатель мы обращаемся к двигателю название которого мы написали в Stepper с приставкой «.step», у нас это myStepper.step. В видео ролике я для наглядности вставил фрагмент, где по часовой стрелке двигатель делает пол оборота, а против – целый оборот. Он в самом конце. Код я для этого изменил следующим образом:
void loop() {
// делаем оборот по часовой стрелке:
Serial.println(“clockwise”); // сообщение в монитор порта
myStepper.step(1024);
delay(500);
// делаем оборот против часовой стрелке:
Serial.println(“counterclockwise”); // сообщение в монитор порта
myStepper.step(-stepsPerRevolution);
delay(500);
}
В мониторе порта микроконтроллер нам «говорит» в какую сторону вращается двигатель.
Ну и, наконец, предлагаю посмотреть видео, в котором демонстрируются работа всех примеров кода из этой статьи.
Предыдущая