View Categories

Драйверы коллекторных моторов

Как вы знаете, никакую нагрузку мощнее светодиода нельзя подключать к МК напрямую, особенно индуктивную - моторчики. Любой МК - цифровое устройство, которое может давать только логические сигналы другим железкам - драйверам, и уже они будут управлять мощной нагрузкой. Рассмотрим некоторые варианты.

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

Реле #

В наборе 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. Простейший вариант - просто скрутить провод к мотору в "косичку" - уже станет гораздо лучше.

Видео #

Полезные страницы #

5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх