Как вы знаете, никакую нагрузку мощнее светодиода нельзя подключать к МК напрямую, особенно индуктивную - моторчики. Любой МК - цифровое устройство, которое может давать только логические сигналы другим железкам - драйверам, и уже они будут управлять мощной нагрузкой. Рассмотрим некоторые варианты.
Связанные уроки:
Реле #
![]() |
В наборе GyverKIT | START | IOT | EXTRA |
---|---|---|---|---|
Модуль реле | ✔ | ✔ | ✔ |
При помощи обычного реле можно просто включать и выключать мотор в одну сторону по команде digitalWrite(пин, состояние)
, прямо как светодиод:
При помощи двух реле или двойного модуля реле можно включать мотор в одну или другую сторону на полную скорость, а также выключать (с активным торможением):
// пины реле
#define MOT_A 2
#define MOT_B 4
// 1 и -1: вращение в направлении
// 0: тормоз
void run(int dir) {
if (dir) {
digitalWrite(MOT_A, dir > 0);
digitalWrite(MOT_B, dir < 0);
} else {
digitalWrite(MOT_A, 0);
digitalWrite(MOT_B, 0);
}
}
Мосфет #
![]() |
В наборе GyverKIT | START | IOT | EXTRA |
---|---|---|---|---|
MOSFET | ✔ |
Полевой транзистор (урок про них) позволяет управлять скоростью вращения мотора при помощи ШИМ сигнала. При использовании мосфета обязательно нужно ставить диод, иначе индуктивный выброс с мотора очень быстро убьёт транзистор. Скорость мотора можно задавать при помощи ШИМ сигнала - analogWrite(пин, скорость)
:
Вместо "голого" мосфета можно использовать модуль силового ключа (урок про них):
![]() |
В наборе GyverKIT | START | IOT | EXTRA |
---|---|---|---|---|
MOSFET-модуль | ✔ | ✔ | ✔ |
Реле и мосфет #
Если объединить реле и мосфет, то получим весьма колхозную, но рабочую схему управления скоростью и направлением мотора:
#define MOT_A 2
#define MOT_PWM 3
#define MOT_B 4
// -255.. 255: вращение в направлении
// 0: тормоз
void run(int speed) {
if (speed) {
digitalWrite(MOT_A, speed > 0);
digitalWrite(MOT_B, speed < 0);
analogWrite(MOT_PWM, abs(speed));
} else {
digitalWrite(MOT_A, 0);
digitalWrite(MOT_B, 0);
digitalWrite(MOT_PWM, 0);
}
}
Специальный драйвер #
Лучше всего управлять мотором при помощи специального драйвера, они бывают разных форм и размеров и рассчитаны на разное напряжение и ток, но управляются практически одинаково.
![]() |
В наборе GyverKIT | START | IOT | EXTRA |
---|---|---|---|---|
Драйвер мотора | ✔ |
Рассмотрим основные драйверы с китайского рынка:
Драйвер | Напряжение | Ток (пик) | Aliexpress |
---|---|---|---|
L298N | 4-50V | 1A (2A) | Купить |
MX1508 | 2-9.6V | 1.5A (2.5A) | Купить |
TA6586 | 3-14V | 5A (7A) | Купить |
L9110S | 2.5-12V | 0.8A (1.5A) | Купить |
TB6612 | 4.5-13.5V | 1.2A (3A) | Купить |
BTS7960 | 5.5-27V | 10A (43A) | Купить |
Большой H мост | 3-36V | 10A (30A) | Купить |
Три пина на мотор #
У такого драйвера два пина задают направление, а третий - скорость (ШИМ). Код для управления такой же, как у примера с двумя реле и мосфетом выше. Пример таблицы (драйвер L293D):
EN | IN 1 | IN 2 | Состояние |
---|---|---|---|
1 | 0 | 1 | Вперёд |
1 | 1 | 0 | Назад |
1 | 0 | 0 | Тормоз |
1 | 1 | 1 | Тормоз |
0 | x | x | Стоп |
x
- не имеет значения
Данный тип драйверов может вырождаться в "два пина на мотор", который разобран ниже. Для этого нужно подать на EN
постоянный высокий сигнал (подключить к питанию)
Два пина на мотор #
В этом случае оба пина используются для управления скоростью и направлением вращения мотора. Здесь есть несколько нюансов.
Существует как минимум два варианта таких драйверов, рассмотрим их таблицы поведения:
- TA6586, DRV8833, DRV8871, MX1508
IN 1 | IN 2 | OUT 1 | OUT 2 |
---|---|---|---|
1 | 0 | 1 | 0 |
0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 |
0 | 0 | Z | Z |
- L9110S
IN 1 | IN 2 | OUT 1 | OUT 2 |
---|---|---|---|
1 | 0 | 1 | 0 |
0 | 1 | 0 | 1 |
1 | 1 | 1 | 1 |
0 | 0 | 0 | 0 |
Где
IN
- входOUT
- выход0
- низкий сигнал1
- высокий сигналZ
- высокоимпедансное состояние (вывод "отключен")
Подобная таблица есть в документации на любой драйвер
- При подаче разных сигналов (1 и 0, 0 и 1) мотор вращается
- При подаче одинаковых сигналов мотор либо активно тормозит, либо отключен от драйвера (сигнал Z на выходе)
Рассмотрим подключение по следующей схеме:
Релейно #
Для управления мотором "релейно" (на максимальной скорости с выбором направления) достаточно подать разные сигналы на пины драйвера:
IN 1 | IN 2 | Режим |
---|---|---|
0 | 1 | Вперёд |
1 | 0 | Назад |
1 | 1 | Тормоз |
0 | 0 | Тормоз / отключен |
#define MOTOR_A1 3 // ШИМ
#define MOTOR_A2 5 // ШИМ
#define MOTOR_B1 6 // ШИМ
#define MOTOR_B2 7 // просто пин
void setup() {
pinMode(MOTOR_A1, OUTPUT);
pinMode(MOTOR_A2, OUTPUT);
pinMode(MOTOR_B1, OUTPUT);
pinMode(MOTOR_B2, OUTPUT);
}
void loop() {
// мотор 1 - остановка
digitalWrite(MOTOR_A1, LOW);
digitalWrite(MOTOR_A2, LOW);
delay(2000);
// мотор 1 - вперёд
digitalWrite(MOTOR_A1, HIGH);
digitalWrite(MOTOR_A2, LOW);
delay(2000);
// мотор 1 - назад
digitalWrite(MOTOR_A1, LOW);
digitalWrite(MOTOR_A2, HIGH);
delay(2000);
}
Плавно #
Для плавного управления скоростью нужно использовать ШИМ сигнал на одном из пинов. Из-за индукционной природы мотора и внутреннего устройства драйвера есть два режима работы мотора - с высокой скоростью и высоким крутящим моментом:
IN 1 | IN 2 | Направление | Режим |
---|---|---|---|
~ШИМ | 1 | Вперёд | Момент |
1 | ~ШИМ | Назад | Момент |
0 | ШИМ | Вперёд | Скорость |
ШИМ | 0 | Назад | Скорость |
Под ШИМ
и ~ШИМ
подразумевается направление заполнения, т.е. если ШИМ 0.. 255
, то ~ШИМ - это 255.. 0
В общем случае рекомендуется вариант с высоким моментом, т.к. на нём мотор работает более стабильно и скорость линейно зависит от заполнения.
- Режим с высокой скоростью рекомендуется для ненагруженного мотора, от которого требуется вращаться быстро (вентилятор, POV дисплей)
- Режим с высоким моментом работает более стабильно и лучше управляет скоростью, что важно для применения в робототехнике (мотор в качестве привода)
Один ШИМ #
Как видно из таблицы выше, мотором можно управлять при помощи одного обычного пина, а второго - ШИМ. Но в одну сторону мотор будет крутиться с высоким моментом, а в другую - с высокой скоростью. Это экономит один ШИМ пин, но использовать такую схему для управления например "танком" будет не очень комфортно, а балансирующий робот скорее всего вообще не будет работать.
Стоп | Вперёд | Назад | |
---|---|---|---|
IN 1 | 0 | 0 | 1 |
IN 2 | 0 | 0.. 255 | 255.. 0 |
#define MOTOR_A1 3 // ШИМ
#define MOTOR_A2 5 // ШИМ
#define MOTOR_B1 6 // ШИМ
#define MOTOR_B2 7 // просто пин
void setup() {
pinMode(MOTOR_A1, OUTPUT);
pinMode(MOTOR_A2, OUTPUT);
pinMode(MOTOR_B1, OUTPUT);
pinMode(MOTOR_B2, OUTPUT);
}
void loop() {
// скорость мотора
int motorSpeed = 100;
// остановка
digitalWrite(MOTOR_B1, LOW);
digitalWrite(MOTOR_B2, LOW);
delay(2000);
// в одну сторону
digitalWrite(MOTOR_B1, LOW);
analogWrite(MOTOR_B2, motorSpeed);
delay(2000);
// в другую сторону
digitalWrite(MOTOR_B1, HIGH);
analogWrite(MOTOR_B2, 255 - motorSpeed);
delay(2000);
}
Два ШИМ #
Тут можно выбрать между высокой скоростью и моментом. Пример с режимом "скорости":
Стоп | Вперёд | Назад | |
---|---|---|---|
IN 1 | 0 | 0 | 0.. 255 |
IN 2 | 0 | 0.. 255 | 0 |
#define MOTOR_A1 3 // ШИМ
#define MOTOR_A2 5 // ШИМ
#define MOTOR_B1 6 // ШИМ
#define MOTOR_B2 7 // просто пин
void setup() {
pinMode(MOTOR_A1, OUTPUT);
pinMode(MOTOR_A2, OUTPUT);
pinMode(MOTOR_B1, OUTPUT);
pinMode(MOTOR_B2, OUTPUT);
}
void loop() {
// скорость мотора
int motorSpeed = 100;
// остановка
digitalWrite(MOTOR_A1, LOW);
digitalWrite(MOTOR_A2, LOW);
delay(2000);
// в одну сторону
digitalWrite(MOTOR_A1, LOW);
analogWrite(MOTOR_A2, motorSpeed);
delay(2000);
// в другую сторону
analogWrite(MOTOR_A1, motorSpeed);
digitalWrite(MOTOR_A2, LOW);
delay(2000);
}
Библиотеки #
Для управления мотором можно использовать библиотеку GyverMotor - она поддерживает все типы драйверов и имеет некоторые полезные возможности:
- Контроль скорости и направления вращения
- Работа с ШИМ любого разрешения
- Плавный пуск и изменение скорости
- Порог минимального ШИМ
Её можно установить/обновить из встроенного менеджера библиотек Arduino по названию GyverMotor. Краткая документация находится по ссылке выше, базовые примеры есть в самой библиотеке.
Управление потенциометром
// управление скоростью и направлением мотора потенциометром
#include <GyverMotor2.h> // вторая версия библиотеки
#define MOTOR_B1 6 // ШИМ
#define MOTOR_B2 7 // просто пин
#define POT_PIN 0
GMotor2<DRIVER2WIRE> motor(MOTOR_B2, MOTOR_B1); // (не ШИМ, ШИМ)
void setup() {
motor.setMinDuty(30); // минимальный ШИМ
//motor.reverse(1); // реверс
}
void loop() {
// переводим в диапазон -255.. 255
int val = analogRead(POT_PIN) / 2 - 512;
motor.setSpeed(val);
delay(30);
}
Плавное управление скоростью
// режим плавного управления скоростью
#include <GyverMotor2.h> // вторая версия библиотеки
#define MOTOR_B1 6 // ШИМ
#define MOTOR_B2 7
#define POT_PIN 0
GMotor2<DRIVER2WIRE> motor(MOTOR_B2, MOTOR_B1); // (не ШИМ, ШИМ)
void setup() {
motor.smoothMode(1); // плавный режим
}
void loop() {
motor.tick();
// переводим в диапазон -255.. 255
int val = analogRead(POT_PIN) / 2 - 512;
motor.setSpeed(val);
}
Помехи и защита от них #
Индуктивный выброс #
Мотор - это индуктивная нагрузка, которая в момент отключения создаёт индуктивные выбросы с обратным напряжением:
- Если мотор коммутируется полевым транзистором (одиночным, в одну сторону), то в схему обязательно нужно добавить диод для защиты транзистора, подробнее см. в уроке про мосфеты
- Если мотор коммутируется драйвером, то диод не нужен: драйвер обычно состоит из 4х транзисторов, они установлены так, что защищают друг друга
Помехи от щёток #
Искрящиеся щетки мотора, особенно старого и разбитого, являются сильным источником электромагнитных помех, и здесь проблема решается установкой керамических конденсаторов с ёмкостью 0.1-1 uF на выводы мотора. Такие же конденсаторы можно поставить между каждым выводом и металлическим корпусом, это ещё сильнее погасит помехи. Для пайки к корпусу нужно использовать мощный паяльник и активный флюс, чтобы залудиться и припаяться как можно быстрее, не перегревая мотор:
Помехи по питанию, просадка #
Мотор потребляет ток не очень равномерно, особенно во время разгона или в условиях переменной нагрузки на вал, что проявляется в виде просадок напряжения по питанию всей схемы. Беды с питанием решаются установкой ёмких электролитических конденсаторов по питанию, логично что ставить их нужно максимально близко к драйверу, то есть до драйвера. Напряжение должно быть выше чем напряжение питания, а ёмкость уже подбирается по факту. Начать можно с 470 мкф и повышать, пока не станет хорошо.
Разделение питания #
Если описанные выше способы не помогают - остаётся только одно: разделение питания. Отдельный малошумящий хороший источник на МК и сенсоры/модули, и отдельный - для силовой части, в том числе мотора. Иногда ради стабильности работы приходится вводить отдельный БП или отдельный аккумулятор для надёжности функционирования устройства.
Экранирование #
В отдельных случаях критичными являются даже наводки от питающих проводов моторов, особенно при управлении ШИМ мощными моторами и шаговиками в станках. Такие наводки могут создавать сильные помехи на находящиеся рядом электронные компоненты, провода, аналоговые цепи, наводить помехи на линии измерения АЦП и радиосвязь. Защититься от таких помех можно при помощи экранирования силовых проводов: экранированные силовые провода не всегда удаётся купить, поэтому достаточно обмотать обычные провода фольгой и подключить экран на GND питания силовой части. Этот трюк часто используют RC моделисты, летающие по FPV. Простейший вариант - просто скрутить провод к мотору в "косичку" - уже станет гораздо лучше.
Видео #
Полезные страницы #
- Набор GyverKIT – наш большой стартовый набор Arduino, продаётся в России
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])
- Поддержать автора за работу над уроками
