Как вы знаете, никакую нагрузку мощнее светодиода нельзя подключать к МК напрямую, особенно индуктивную - моторчики. Любой МК - цифровое устройство, которое может давать только логические сигналы другим железкам - драйверам, и уже они будут управлять мощной нагрузкой. Рассмотрим некоторые варианты.
Связанные уроки:
Реле #
| В наборе GyverKIT | Aliexpress | |
|---|---|---|
|  | 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 | Aliexpress | |
|---|---|---|
|  | START | Купить | 
Полевой транзистор (урок про них) позволяет управлять скоростью вращения мотора при помощи ШИМ сигнала. При использовании мосфета обязательно нужно ставить диод, иначе индуктивный выброс с мотора очень быстро убьёт транзистор. Скорость мотора можно задавать при помощи ШИМ сигнала - analogWrite(пин, скорость):
Вместо "голого" мосфета можно использовать модуль силового ключа (урок про них):
| В наборе GyverKIT | Aliexpress | |
|---|---|---|
|  | START IOT EXTRA | Купить | 
Реле и мосфет #
Если объединить реле и мосфет, то получим весьма колхозную, но рабочую схему управления скоростью и направлением мотора:
#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 | Aliexpress | |
|---|---|---|
|  | 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 - 255;
  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.setAccel(500);    // 500 единиц в секунду
}
void loop() {
  motor.tick();
  // переводим в диапазон -255.. 255
  // лучше делать это по таймеру на миллис
  int val = analogRead(POT_PIN) / 2 - 255;
  motor.setSpeed(val);
}Помехи и защита от них #
Индуктивный выброс #
Мотор - это индуктивная нагрузка, которая в момент отключения создаёт индуктивные выбросы с обратным напряжением:
- Если мотор коммутируется полевым транзистором (одиночным, в одну сторону), то в схему обязательно нужно добавить диод для защиты транзистора, подробнее см. в уроке про мосфеты
- Если мотор коммутируется драйвером, то диод не нужен: драйвер обычно состоит из 4х транзисторов, они установлены так, что защищают друг друга
Помехи от щёток #
Искрящиеся щетки мотора, особенно старого и разбитого, являются сильным источником электромагнитных помех, и здесь проблема решается установкой керамических конденсаторов с ёмкостью 0.1-1 uF на выводы мотора. Такие же конденсаторы можно поставить между каждым выводом и металлическим корпусом, это ещё сильнее погасит помехи. Для пайки к корпусу нужно использовать мощный паяльник и активный флюс, чтобы залудиться и припаяться как можно быстрее, не перегревая мотор:
Помехи по питанию, просадка #
Мотор потребляет ток не очень равномерно, особенно во время разгона или в условиях переменной нагрузки на вал, что проявляется в виде просадок напряжения по питанию всей схемы. Беды с питанием решаются установкой ёмких электролитических конденсаторов по питанию, логично что ставить их нужно максимально близко к драйверу, то есть до драйвера. Напряжение должно быть выше чем напряжение питания, а ёмкость уже подбирается по факту. Начать можно с 470 мкф и повышать, пока не станет хорошо.
Разделение питания #
Если описанные выше способы не помогают - остаётся только одно: разделение питания. Отдельный малошумящий хороший источник на МК и сенсоры/модули, и отдельный - для силовой части, в том числе мотора. Иногда ради стабильности работы приходится вводить отдельный БП или отдельный аккумулятор для надёжности функционирования устройства.
Экранирование #
В отдельных случаях критичными являются даже наводки от питающих проводов моторов, особенно при управлении ШИМ мощными моторами и шаговиками в станках. Такие наводки могут создавать сильные помехи на находящиеся рядом электронные компоненты, провода, аналоговые цепи, наводить помехи на линии измерения АЦП и радиосвязь. Защититься от таких помех можно при помощи экранирования силовых проводов: экранированные силовые провода не всегда удаётся купить, поэтому достаточно обмотать обычные провода фольгой и подключить экран на GND питания силовой части. Этот трюк часто используют RC моделисты, летающие по FPV. Простейший вариант - просто скрутить провод к мотору в "косичку" - уже станет гораздо лучше.
Видео #
Полезные страницы #
- Набор GyverKIT – наш большой стартовый набор Arduino, продаётся в России
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])
- Поддержать автора за работу над уроками
 














