Посмотр рубрик

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

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

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

Реле #

В наборе GyverKIT Aliexpress
START
IOT
EXTRA
Купить

При помощи обычного реле можно просто включать и выключать мотор в одну сторону по команде digitalWrite(пин, состояние), прямо как светодиод. Здесь Arduino питается от внешнего блока питания:

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

// пины реле
#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:

EN IN 1 IN 2 Состояние
1 0 1 Вперёд
1 1 0 Назад
1 0 0 Тормоз
1 1 1 Тормоз
0 x x Стоп
  • x - не имеет значения

Плавно #

Для плавного управления скоростью нужно подавать на этот пин ШИМ сигнал:

EN IN 1 IN 2 Состояние
0-255 0 1 Вперёд
0-255 1 0 Назад
255 0 0 Тормоз
255 1 1 Тормоз
0 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 Вперёд Момент (brake)
1 ~ШИМ Назад Момент (brake)
0 ШИМ Вперёд Скорость (coast)
ШИМ 0 Назад Скорость (coast)

Под ШИМ и ~ШИМ подразумевается направление заполнения, т.е. если ШИМ 0.. 255, то ~ШИМ - это 255.. 0

Более правильно данные режимы называются drive/coast и drive/brake, где drive - момент когда ШИМ даёт высокий сигнал, на мотор подаётся напряжение и он разгоняется. Это происходит одинаково для обоих режимов. В момент, когда ШИМ даёт низкий сигнал, возможны 2 варианта:

  • coast (fast decay) - мотор отключается от драйвера, ток обмоток быстро падает и мотор свободно крутится по инерции:
    • Без нагрузки мотор вращается быстрее
    • Ток и момент сильнее пульсируют
    • На малых заполнениях мотор может работать менее устойчиво или вообще не запускаться
    • Зависимость скорости от заполнения нелинейная
  • brake (slow decay) - мотор замыкается сам на себя, ток продолжает циркулировать и мотор слегка тормозится:
    • Больший ток потребления
    • Больший и более стабильный момент при том же заполнении
    • Более плавная и стабильная работа на низких оборотах
    • Более линейная зависимость скорости от заполнения
    • Более быстрое торможение при уменьшении заполнения

Практические различия между этими режимами проявляются на малых и средних значениях заполнения ШИМ, т.е. на высоком заполнении разница уже не будет заметна. В общем случае рекомендуется вариант с высоким моментом.

В трёхпроводном подключении (2 направления + ШИМ) мотор работает в drive/brake режиме

  • Режим с высокой скоростью рекомендуется для ненагруженного мотора, от которого требуется вращаться быстро (вентилятор, 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);
}

Библиотеки #

Для управления мотором можно использовать библиотеку GyverMotor2 - она поддерживает все типы драйверов и имеет некоторые полезные возможности:

  • Контроль скорости и направления вращения
  • Работа с ШИМ любого разрешения
  • Плавный пуск и изменение скорости
  • Порог минимального ШИМ

Её можно установить/обновить из встроенного менеджера библиотек Arduino по названию GyverMotor2. Краткая документация находится по ссылке выше, базовые примеры есть в самой библиотеке.

Управление потенциометром
#include <GyverMotor2.h>

// GyverMotor2<GM2::DIR_DIR> motor(5, 6);
// GyverMotor2<GM2::DIR_PWM> motor(5, 6);
GyverMotor2<GM2::DIR_PWM_INV> motor(5, 6);
// GyverMotor2<GM2::PWM_PWM_SPEED> motor(5, 6);
// GyverMotor2<GM2::PWM_PWM_POWER> motor(5, 6);
// GyverMotor2<GM2::DIR_DIR_PWM> motor(5, 6, 7);

void setup() {
    // motor.setMinDuty(50);    // мин. шим
    // motor.setReverse(true);  // реверс
}

void loop() {
    int speed = map(analogRead(0), 0, 1023, -255, 255);
    motor.runSpeed(speed);
    delay(30);
}
Плавное управление скоростью
#include <GyverMotor2.h>

// GyverMotor2<GM2::DIR_DIR> motor(5, 6);
// GyverMotor2<GM2::DIR_PWM> motor(5, 6);
GyverMotor2<GM2::DIR_PWM_INV> motor(5, 6);
// GyverMotor2<GM2::PWM_PWM_SPEED> motor(5, 6);
// GyverMotor2<GM2::PWM_PWM_POWER> motor(5, 6);
// GyverMotor2<GM2::DIR_DIR_PWM> motor(5, 6, 7);

void setup() {
    // установка ускорения
    motor.setAccel(100);
}

void loop() {
    // вызов тикера
    motor.tick();

    // скорость будет применяться плавно
    int speed = map(analogRead(0), 0, 1023, -255, 255);
    motor.runSpeed(speed);
}

Помехи и защита от них #

Индуктивный выброс #

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

  • Если мотор коммутируется полевым транзистором или реле в одну сторону, то в схему обязательно нужно добавить диод для защиты ключа, подробнее см. в уроке про мосфеты. Диод нужно ставить ближе к мотору, можно прямо на клеммы - чтобы ток от выброса не создавал помех по проводам между мотором и ключом
  • Если мотор коммутируется драйвером, то диод не нужен: драйвер обычно состоит из 4х транзисторов - они установлены так, что защищают друг друга

Помехи от щёток #

Искрящиеся щетки мотора, особенно старого и разбитого, являются сильным источником электромагнитных помех - проблема решается установкой керамических конденсаторов с ёмкостью 0.1-1 uF на выводы мотора. Такие же конденсаторы можно поставить между каждым выводом и металлическим корпусом, это ещё сильнее погасит помехи. Для пайки к корпусу нужно использовать мощный паяльник и активный флюс, чтобы залудиться и припаяться как можно быстрее, не перегревая мотор:

Помехи по питанию, просадка #

Мотор потребляет ток не очень равномерно, особенно во время разгона или в условиях переменной нагрузки на вал, что проявляется в виде просадок напряжения по питанию всей схемы. Беды с питанием решаются установкой ёмких электролитических конденсаторов по питанию, логично что ставить их нужно максимально близко к драйверу, то есть до драйвера. Напряжение должно быть выше чем напряжение питания, а ёмкость уже подбирается по факту. Начать можно с 470 мкф и повышать, пока не станет хорошо.

Разделение питания #

Если описанные выше способы не помогают - остаётся только одно: разделение питания. Отдельный малошумящий хороший источник на МК и сенсоры/модули, и отдельный - для силовой части, в том числе мотора. Иногда ради стабильности работы приходится вводить отдельный БП или отдельный аккумулятор для надёжности функционирования устройства.

Экранирование #

В отдельных случаях критичными являются даже наводки от питающих проводов моторов, особенно при управлении ШИМ мощными моторами и шаговиками в станках. Такие наводки могут создавать сильные помехи на находящиеся рядом электронные компоненты, провода, аналоговые цепи, наводить помехи на линии измерения АЦП и радиосвязь. Защититься от таких помех можно при помощи экранирования силовых проводов: экранированные силовые провода не всегда удаётся купить, поэтому достаточно обмотать обычные провода фольгой и подключить экран на GND питания силовой части. Этот трюк часто используют RC моделисты, летающие по FPV. Простейший вариант - просто скрутить провод к мотору в "косичку" - уже станет гораздо лучше.

Видео #

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


(12 голосов)
Подписаться
Уведомить о
guest

5 комментариев
Старые
Новые Популярные
Прокрутить вверх