Драйвер L298N используется радиолюбителями для многофункционального управления двигателями постоянного тока. Схема модуля, состоящая из двух H-мостов, позволяет подключать к нему один биполярный шаговый двигатель или одновременно два щёточных двигателя постоянного тока. При этом есть возможность изменять скорость и направление вращения моторов. Управление осуществляется путём подачи соответствующих сигналов на командные входы, выполненные в виде штыревых контактов. На рисунке ниже показан внешний вид модуля с кратким описанием всех его составляющих.
Внешний вид модуля L298N
- OUT1 и OUT2 – разъёмы для подключения первого щёточного двигателя или первой обмотки шагового двигателя;
- OUT3 и OUT4 – разъёмы для подключения второго щёточного двигателя или второй обмотки шагового двигателя;
- VSS – вход для питания двигателей (максимальный уровень +35V);
- GND – общий провод (не забываем соединить с аналогичным входом Arduino!!!);
- Vs – вход для питания логики +5V. Через него непосредственно запитывается сама микросхема L298N. Есть ещё второй способ питания, при котором 5V для L298N берётся от встроенного в модуль стабилизатора напряжения. В таком случае на разъём подаётся только питание для двигателей (Vss), контакт Vs остаётся не подключенным, а на плате устанавливается перемычка питания от стабилизатора, который ограничит питающее моторы напряжение до приемлемых 5V.
- IN1, IN2 – контакты управления первым щёточным двигателем или первой обмоткой шагового двигателя.
- IN3, IN4 – контакты управления вторым щёточным двигателем или второй обмоткой шагового двигателя.
- ENA, ENB – контакты для активации/деактивации первого и второго двигателей или соответствующих обмоток ШД. Подача логической единицы на эти контакты разрешает вращение двигателей, а логический ноль – запрещает. Для изменения скорости вращения щёточных моторов на эти контакты подаётся ШИМ-сигнал. Для работы с шаговым двигателям, как правило, на эти контакты ставят перемычки, обеспечивающие постоянную подтяжку к +5V.
Электрическая схема модуля L298N
Как видно из вышеприведенной схемы, основным элементом модуля является микросхема L298N, в состав которой входят два полноценных H-моста. Каждый H-мост выполнен в виде сборки из четырёх транзисторных ключей с включённой в центре нагрузкой в виде обмотки двигателя. Такой подход позволяет менять полярность в обмотке и как следствие направление вращения двигателя путём чередования пар открытых и закрытых ключей.
Транзисторные мосты Н-типа
На рисунке изображены два транзисторных моста Н-типа. В первом случае на вход IN1 подаётся логическая единица, а на вход IN2 – логический ноль. Так как транзисторы в схеме моста имеют разный тип проводимости, то при таком входном сигнале транзисторы Т1 и Т4 останутся в закрытом состоянии, в то время, как через транзисторы Т2 и Т3 потечёт ток. Ввиду того, что единственный путь протекания тока лежит через обмотку двигателя, то последний окажется подключен правой клеммой к плюсу питания, а левой к минусу. Всё это приведёт к вращению мотора в определённом направлении. Абсолютно противоположная картина показана на нижнем рисунке. Здесь IN3 установлен в логический ноль, а IN4 в логическую единицу. Теперь ток течёт в обратном направлении (левая клемма – плюс, правая – минус), заставляя второй двигатель крутиться в противоположную сторону.
Технические характеристики
- Напряжение питания логики: 5В
- Потребляемый логикой ток: 36мА
- Напряжение питания моторов: от 5 до 35В
- Рабочий ток драйвера: 2А
- Пиковый ток драйвера 3А
- Максимальная мощность: 20Вт (при температуре 75оС)
- Диапазон рабочих температур: -25оС…+135оС
- Размеры модуля: 43.5 х 43.2 х 29.4мм
Подключение L298N к плате Arduino
Работать с модулем L298N довольно просто и комфортно. Здесь не придётся изучать тонны литературы с описанием замороченных протоколов. Все сводится к простому переключению логических уровней на выводах Arduino плюс к генерации ШИМ, если требуется управлять скоростью вращения.
Так как драйвер способен управлять двумя типами моторов (щёточным или шаговым), то и работа с ним строится по-разному. Рассмотрим для начала подключение обычных щёточных моторов постоянного тока и управление ими с помощью платы Arduino Nano. На рисунке показана соответствующая схема подключения.
Схема подключения двух щёточных двигателей постоянного тока
Следует обратить внимание, что в схеме предусмотрена возможность управления скоростью вращения, поэтому выводы ENA и ENB драйвера подключены к пинам Arduino, способным выдавать ШИМ-сигнал. Arduino питается от отдельного источника 7-12В. Если напряжение питания моторов лежит в этом же диапазоне, то можно объединить питающие цепи в одну общую. Также необходимо следить за тем, чтобы минусовые провода всех элементов схемы были соединены между собой.
Для демонстрации возможностей модуля, напишем скетч, который будет вращать моторы с различной скоростью и периодически менять направления их вращения. Ниже приведена программа с подробными комментариями, которая реализует задуманный алгоритм.
#define PIN_ENA 9 // Вывод управления скоростью вращения мотора №1
#define PIN_ENB 3 // Вывод управления скоростью вращения мотора №2
#define PIN_IN1 7 // Вывод управления направлением вращения мотора №1
#define PIN_IN2 6 // Вывод управления направлением вращения мотора №1
#define PIN_IN3 5 // Вывод управления направлением вращения мотора №2
#define PIN_IN4 4 // Вывод управления направлением вращения мотора №2
uint8_t power = 105; // Значение ШИМ (или скорости вращения)
void setup() {
// Установка всех управляющих пинов в режим выхода
pinMode(PIN_ENA, OUTPUT);
pinMode(PIN_ENB, OUTPUT);
pinMode(PIN_IN1, OUTPUT);
pinMode(PIN_IN2, OUTPUT);
pinMode(PIN_IN3, OUTPUT);
pinMode(PIN_IN4, OUTPUT);
// Команда остановки двум моторам
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, LOW);
digitalWrite(PIN_IN3, LOW);
digitalWrite(PIN_IN4, LOW);
}
void loop() {
// Вращаем моторы в одну сторону с разной скоростью
while(power < 255) {
analogWrite(PIN_ENA, power); // Устанавливаем скорость 1-го мотора
analogWrite(PIN_ENB, power); // Устанавливаем скорость 2-го мотора
// Задаём направление для 1-го мотора
digitalWrite(PIN_IN1, HIGH);
digitalWrite(PIN_IN2, LOW);
// Задаём направление для 2-го мотора
digitalWrite(PIN_IN3, HIGH);
digitalWrite(PIN_IN4, LOW);
delay(3000); // Пауза 3 секунды
power += 30; // Увеличиваем скорость
}
power = 225;
// Вращаем моторы в другую сторону с разной скоростью
while(power > 105) {
analogWrite(PIN_ENA, power); // Устанавливаем скорость 1-го мотора
analogWrite(PIN_ENB, power); // Устанавливаем скорость 2-го мотора
// Задаём направление для 1-го мотора
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, HIGH);
// Задаём направление для 2-го мотора
digitalWrite(PIN_IN3, LOW);
digitalWrite(PIN_IN4, HIGH);
delay(3000); // Пауза 3 секунды
power -= 30; // Уменьшаем скорость
}
power = 105;
}
В самом верху программы задаются макроопределения всех выводов, используемых в проекте. В функции Setup() все выводы Arduino Nano, участвующие в управлении, задаются в качестве выхода. На выводах IN1-IN4 выставляются логические нули, чтобы двигатели гарантированно не вращались в момент старта программы. В главном цикле, программа обеспечивает вращение двигателей в одном направлении, увеличивая их скорость каждые 3 секунды. Когда разгон вырастает до максимального, моторы начинают вращаться в обратном направлении, постепенно замедляя скорость. На пике сбавления скорости, алгоритм повторяется заново. Как видим, сложного здесь ничего нет. Теперь разберёмся с шаговым двигателем и его подключением к плате Arduino Nano.
Схема подключения шагового двигателя к Arduino Nano
В качестве демонстрационной модели использован популярный шаговый двигатель NEMA17. Он способен вращаться с частотой до 60 оборотов в минуту и имеет разрешающую способность 200 шагов на один оборот. Следует обратить внимание, что выводы ENA и ENB должны быть подтянуты к +5V путём установки перемычек на самом модуле. Таким образом управляющему сигналу будет разрешено проходить на обмотки шагового двигателя. Также, в случае использования двигателя NEMA17, напряжение его питания не должно превышать 12V. Ниже приведён пример кода с комментариями, который заставит двигатель вращаться в разные стороны, меняя своё направление после каждого полного оборота. В программе использована стандартная библиотека Stepper.h, которая значительно упрощает процесс разработки ПО для проектов с шаговыми двигателями.
#include <Stepper.h> // Подключение библиотеки для работы с ШД
#define steps 200 // Количество шагов на один оборот
// Создание экземпляра класса для работы с ШД. указываем кол-во шагов на один оборот
// и пины Arduino, к которым подключены обмотки двигателя
Stepper myStepper(steps, 7, 6, 5, 4);
void setup() {
myStepper.setSpeed(60); // Устанавливаем скорость вращения об./мин.
}
void loop() {
myStepper.step(steps); // Вращаем двигатель в одну сторону на 200 шагов
delay(1000); // Ждём одну секунду
myStepper.step(-steps); // Вращаем двигатель в обратную сторону на 200 шагов
delay(1000); // Ждём одну секунду
}
Пример использования
Модуль L298N применяется в устройствах, где есть необходимость управления двигателями. Такими устройствами могут быть различного рода ЧПУ, 3D принтеры, роботы, механизмы вендинговых аппаратов и т.п. Для того, чтобы глубже вникнуть в тему работы с драйвером, создадим небольшой проект роботизированной платформы, которая будет передвигаться по командам с любого ИК-пульта дистанционного управления. Робот будет иметь два мотор-редуктора, связанных напрямую с колёсами, а также ИК-приёмник, способный воспринимать команды пульта ДУ. В качестве “мозга” выступит плата Arduino Nano.
Электрическая схема робота-машинки
Для приёма управляющих сигналов с ИК-пульта, в проекте будет использоваться популярная микросхема TSOP-1738. Удобство её заключается в том, что она напрямую подключается к плате Arduino и поддерживает большое разнообразие пультов управления. Цифра 38 в конце маркировки означает несущую частоту (кГц), с которой ваш пульт передаёт сигнал. Существует несколько модификаций данной микросхемы на разные несущие частоты. Ниже приведён список возможных вариантов.
- TSOP-1730 (30 кГц)
- TSOP-1733 (33 кГц)
- TSOP-1736 (36 кГц)
- TSOP-1737 (37.6 кГц)
- TSOP-1738 (38 кГц)
- TSOP-1740 (40 кГц)
- TSOP-1756 (56 кГц)
Следует помнить, что помимо несущей частоты, каждая кнопка пульта дистанционного управления имеет свой уникальный код, который предварительно необходимо считать и вставить в текст основного скетча. В данном проекте будет использоваться всего 4 кнопки: “вперёд”, “назад”, “вправо” и “влево”. Определить коды поможет библиотека IRremote.
Итак, собираем всё по вышеприведенной схеме, устанавливаем библиотеку IRremote, и для начала заливаем в Arduino этот скетч.
#include <IRremote.h>
#define RECV_PIN 13;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
irrecv.resume();
}
delay(100);
}
После запуска, в мониторе будут отображаться коды клавиш, нажатые на пульте ДУ. Нам необходимо выбрать 4 кнопки для управления движением робота и выписать их коды для дальнейшего использования в основной программе. У меня получилось следующее:
- Кнопка “Вперёд” — 0xB4B4E21D
- Кнопка “Назад” — 0xB4B412ED
- Кнопка “Вправо” — 0xB4B45AA5
- Кнопка “Влево” — 0xB4B49A65
На этом подготовка к реализации проекта завершена, можно приступать к сборке шасси. Здесь можно дать волю своей фантазии. В нашем случае получилось следующее.
Пример реализации шасси для робота
В пластиковом корпусе удалось разместить все необходимые элементы схемы, а именно: источник питания, Arduino Nano и модуль L298N. ИК-приемник TSOP-1738 был вынесен на верх корпуса, чтобы обеспечить надёжную связь с пультом ДУ. Ведущие колёса с моторами закреплены снизу при помощи двухстороннего скотча. В качестве переднего колеса используется поворотный ролик от кресла.
Робот готов к программированию
Ниже приведён исходный код управления роботом-машинкой с подробными комментариями.
#define PIN_RECV 13 // Вывод, к которому подключен ИК-приёмник
#define PIN_IN1 7 // Вывод управления правого колеса
#define PIN_IN2 6 // Вывод управления правого колеса
#define PIN_IN3 5 // Вывод управления левого колеса
#define PIN_IN4 4 // Вывод управления левого колеса
#define PIN_ENA 9 // Вывод управления скоростью правого колеса
#define PIN_ENB 3 // Вывод управления скоростью левого колеса
#define SPEED 255 // Скорость бобо-машинки (0-255)
// Коды с пульта управления (необходимо вставить свои!!!)
#define BUTTON_FORWARD 0xB4B4E21D // Код кнопки ВПЕРЁД
#define BUTTON_LEFT 0xB4B49A65 // Код кнопки ВЛЕВО
#define BUTTON_RIGHT 0xB4B45AA5 // Код кнопки ВПРАВО
#define BUTTON_BACK 0xB4B412ED // Код кнопки НАЗАД
#include <IRremote.h> // Библиотека для работы с ИК-приёмником
IRrecv irrecv(PIN_RECV); // Создание объекта работы с ИК-приёмником
decode_results results; // Переменная для хранения результата декодирования
void setup() {
irrecv.enableIRIn(); // Инициализация ИК-приёмника
// Настройка на выход всех управляющих пинов Arduino
pinMode(PIN_IN1, OUTPUT);
pinMode(PIN_IN2, OUTPUT);
pinMode(PIN_IN3, OUTPUT);
pinMode(PIN_IN4, OUTPUT);
pinMode(PIN_ENA, OUTPUT);
pinMode(PIN_ENB, OUTPUT);
// Остановка моторов
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, LOW);
digitalWrite(PIN_IN3, LOW);
digitalWrite(PIN_IN4, LOW);
analogWrite(PIN_ENA, SPEED);
analogWrite(PIN_ENB, SPEED);
}
void loop() {
// Ждём поступления сигнала с пульта ДУ
if (irrecv.decode(&results)) {
// Анализируем полученный результат
switch(results.value) {
case BUTTON_FORWARD: // Движение ВПЕРЁД
digitalWrite(PIN_IN1, HIGH);
digitalWrite(PIN_IN2, LOW);
digitalWrite(PIN_IN3, LOW);
digitalWrite(PIN_IN2, HIGH);
break;
case BUTTON_LEFT: // Поворот ВЛЕВО
digitalWrite(PIN_IN1, HIGH);
digitalWrite(PIN_IN2, LOW);
digitalWrite(PIN_IN3, LOW);
digitalWrite(PIN_IN2, LOW);
break;
case BUTTON_RIGHT: // Поворот ВПРАВО
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, LOW);
digitalWrite(PIN_IN3, LOW);
digitalWrite(PIN_IN2, HIGH);
break;
case BUTTON_BACK: // Движение НАЗАД
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, HIGH);
digitalWrite(PIN_IN3, HIGH);
digitalWrite(PIN_IN2, LOW);
break;
}
irrecv.resume();
}
}
Часто задаваемые вопросы
Какое минимальное напряжение можно подавать на вход питания двигателей модуля?
Напряжение питания силовой части не рекомендуется опускать ниже 7В. Согласно документации, оно должно быть выше напряжения логики на 2,5В.
Какой ток может обеспечить внутренний стабилизатор 5В?
Внутренний 5-вольтовый стабилизатор модуля может выдать ток до 0.5А.
Можно ли управлять выводами ENA и ENB без использования ШИМ?
Можно управлять функцией digitalWrite, но в таком случае регулировка скорости будет невозможна. Управление будет сводиться к двум состояниям: вкл./выкл.
Почему двигатель начинает вращаться при ШИМ больше чем 97, а до этого просто стоит на месте? Как сделать так, чтобы скорость могла регулироваться от 0?
Разные двигатели имеют разные технические характеристики и как следствие разную стартовую мощность. Поэтому для каждого конкретного случая будет своё минимальное значение ШИМ, при котором двигатель начнёт вращаться с начальной скоростью. Фактическая регулировка от 0 невозможна, так как двигатель попросту не хватит энергии. В таких случаях очень удобно использовать функцию map(). Например, оформить регулировку от 0 до 100% можно следующим образом:
uint8_t speed = 90; // Скорость двигателя в процентах
speed = map(speed, 96, 255, 0, 100); // Диапазон ШИМ 97-255 преобразуем в проценты 0-100
analogWrite(speed);
Как вы знаете, никакую нагрузку мощнее светодиода нельзя подключать к МК напрямую, особенно индуктивную — моторчики. Любой МК — цифровое устройство, которое может давать только логические сигналы другим железкам — драйверам, и уже они будут управлять мощной нагрузкой. Рассмотрим некоторые варианты.
Реле #
| В наборе 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])
- Поддержать автора за работу над уроками
Чтобы управлять вращением мотора, любому контроллеру необходимо специальное устройство, которое часто называют драйвером (от англ. driver — водитель). В уроке «управление двигателем постоянного тока» мы уже пробовали запускать и вращать в разные стороны мотор двумя способами: с помощью одного транзистора и с помощью микросхемы драйвера L293D.
На этот раз, попробуем использовать более мощный двухканальный драйвер L298N, который часто можно встретить в виде модуля красного цвета (хотя встречаются зеленые и синие модели).
Как и в случае L293N, драйвер представляет собой полный H-мост, главная функция которого — менять полярность на нагрузке. А если в качестве нагрузки будет мотор постоянного тока, то смена полярности приведет к смене направления его вращения. Это то, что нам нужно.
Спецификация модуля L298N:
- напряжение питания двигателей: до 35 В;
- рабочий ток (на каждый канал): 2 А;
- периодический ток (80% — вкл, 20% — выкл): 2,5 А;
- кратковременный ток: 3 А;
- вес: 33 г.
Драйвер L298N работает с более высоким током, чем L293D. С помощью L298N мы можем управлять и слабыми моторчиками типа n20 и мощными моторами, такими как JGA25 или даже JGA37 с крутящим моментом до 20-25 кг/см. Хватит для большинства DIY проектов!
Список необходимых компонентов
Для выполнения всех экспериментов в данном уроке, кроме самого драйвера, потребуются: Ардуино-совместимый контроллер, двигатель постоянного тока и питание для него, а также немного проводов вилка-розетка. Необходимые компоненты можно добавить в корзину прямо здесь, и затем оформить заказ в нашем интернет-магазине.
Код: 58
Код: 74
Код: 341
Код: 356
Код: 222
Посмотрим внимательнее на модуль и разберемся с его контактами.
Логика микросхемы L298N питается напряжением 5 Вольт. Для этого на модуле предусмотрен стабилизатор напряжения 78M05. На вход этого стабилизатора можно подавать напряжение до 35 В, а на выходе всегда получается 5 В. Рабочий ток у 78M05 небольшой — до 500 мА. Однако, при желании, от него можно питать и саму плату Ардуино Уно, к которой мы будем подключать драйвер.
Тройная клемма снизу отвечает за питание модуля. Самый левый контакт — питание моторов. Сюда можно подавать до 35 В. Средний контакт — земля, которая должна быть общей для модуля и контроллера. Правый контакт имеет двоякую функцию. Если на модуле стоит перемычка питания стабилизатора, то на этом контакте будет +5В и к нему можно ничего не подключать, либо питать от него контроллер. Но если перемычку убрать, то к этому контакту нужно будет непременно подключить +5В от контроллера, чтобы питать драйвер. В нашем примере мы будем ориентироваться именно на вариант без перемычки.
Две другие винтовые клеммы (OUT1/2 и OUT 3/4) служат для подключения моторов. Надо отметить, что моторы постоянного тока неполярные, но от того на какой контакт мотора подается плюс, а на какой минус, зависит направление их вращения.
Наконец, осталось разобраться с контактами управления. Их по три штуки на каждый мотор. Контакты ENA и ENB позволяют управлять моторами с помощью ШИМ сигнала. Если ENA и ENB подключить строго к +5 В, то моторы будут всегда вращаться с максимальной возможной скоростью. Именно для этого режима на модуле предусмотрены две перемычки рядом с ENA и ENB.
С помощью контактов IN1,IN2,IN3,IN4 задаётся режим работы моторов. Таблица режимов для двигателя A имеет вид:
| Режим | IN1 | IN2 |
| Вращение в одну сторону | 1 | 0 |
| Вращение в обратную сторону | 0 | 1 |
| Блокировка мотора | 1 | 1 |
| Отключение мотора | 0 | 0 |
Тут следует пояснить последние два режима. Если нам необходимо резко остановить мотор, то выбираем режим блокировки. Для плавной остановки — выбираем «отключение мотора»
Подключение драйвера L298N к Ардуино Уно
Чтобы попробовать драйвер в деле, подключим его к контроллеру Ардуино Уно и к любому, попавшему под руку, небольшому мотору постоянного тока. В данном уроке мы используем самый простой мотор с напряжением питания 1,5-3 Вольта. Для питания этого мотора нам будет достаточно двух пальчиковых батареек. В такой схеме просто невозможно запитать микросхему драйвера от встроенного стабилизатора, поэтому питание +5В будем брать от Ардуино.
Также отметим, что при данной схеме подключения с внешним питанием +5 В, нам нужно убрать соответствующую перемычку, о которой мы говорили выше (перемычка питания от стабилизатора)!
Ну и раз уж мы планируем управлять скоростью вращения, уберем перемычку с контакта ENA.
Принципиальная схема
Внешний вид макета
Программа для драйвера мотора L298N
Напишем простую программу, которая будет вращать мотор в одну сторону 3 секунды с максимальной скоростью, и затем 3 секунды в обратную сторону с более медленной скоростью.
byte ena = 3;
byte in1 = 4;
byte in2 = 5;
void setup() {
pinMode( ena, OUTPUT );
pinMode( in1, OUTPUT );
pinMode( in2, OUTPUT );
}
void loop() {
// выставляем 100% мощность на моторе А - 255 из 255
analogWrite( ena, 255 );
// выставляем режим мотора - вращение по часовой
digitalWrite( in1, HIGH );
digitalWrite( in2, LOW );
delay(3000); // пауза 3сек
// выставляем мощность на мотора А - 150 из 255
analogWrite( ena, 150 );
// режим мотора - вращение против часовой
digitalWrite( in1, LOW );
digitalWrite( in2, HIGH );
delay(3000); // пауза 3сек
}
Загружаем программу на Ардуино, затем подключаем к драйверу элементы питания и смотрим как ведёт себя моторчик.
Следует отметить, что данная программа не гарантирует вращение мотора с какой-то конкретной скоростью. Мы лишь можем менять мощность, передаваемую на мотор, с помощью изменения коэффициента заполнения ШИМ сигнала (duty cycle). Подробнее о ШИМ сигнале можно узнать в одном из наших уроков.
Заключение
Итак, модуль драйвера L298N оказался не таким сложным, как могло показаться. Все драйверы имеют практически схожие контакты управления: EN, IN1, IN2. Бывает, что отдельный вход EN отсутствует, и тогда ШИМ сигнал подается на IN1,IN2. Разобравшись с одним драйвером, мы можем с легкостью применять в своих проектах и другие модели.
Как уже было написано, L298N является достаточно мощным чтобы потянуть большинство моторов, применяемых в DIY проектах. Это и популярные пластиковые желтые моторы с редуктором и более мощные металлические JGA25 и JGA37.
Отдельно следует отметить и ещё одно распространенное применение L298N. С помощью этого драйвера можно управлять биполярными шаговыми двигателями, хотя и не настолько эффективно, как это делают специализированные драйвера типа A4988.
Пример 27. Драйвер двигателей на L298N
Примеры
Модуль драйвера L298N является двуканальным драйвером двигателей постоянного тока и основан на двух H-мостовых драйверах. Через этот модуль вы можете управлять двумя двигателями постоянного тока, либо одним четырехпроводным двухфазным шаговым двигателем. При управлении двумя двигателями постоянного тока имеется возможность одновременно с направлением их вращения управлять и скоростью с помощью подачи ШИМ-сигнала на соответствующие выводы. Если управление скоростью не требуется, то выводы ENA и ENB можно замкнуть перемычкой на соответствующие выводы +5V.
Модуль драйвера имеет 6 выводов:
- ENA – вывод для управления скоростью мотора A с помощью ШИМ;
- IN1 – вывод 1 мотора А;
- IN2 – вывод 2 мотора А;
- IN3 – вывод 1 мотора B;
- IN4 – вывод 2 мотора B;
- ENB – вывод для управления скоростью мотора B с помощью ШИМ.
Обратите внимание на данный клеммник на драйвере:
Описание:
В данном примере с помощью Arduino и драйвера на L298N будем управлять двумя двигателями постоянного тока. Установим скорость и направление вращения, поменяем их. В теле функции demoOne() (см. скетч ниже) будем включать двигатели и начинаем с ними работать при ШИМ-значении 100. Через некоторое время двигатели начинают вращаться в противоположном направлении (благодаря смене HIGH и LOW в теле функции digitalWrite()). Для демонстрации возможностей изменения скорости вращения, используем доступный ШИМ-диапазон в теле функции demoTwo(). Сигнал на пине меняется от 0 до 255 и вновь до нуля.
Компоненты:
- 1 × Плата Arduino
- 1 × USB-кабель
- 1 × Драйвер двигателей на L298N
- 2 × Двигатель постоянного тока (с редуктором) или (без редуктора)
- 1 × Клемма для 9 В батареи (Кроны)
- 1 × 9 В цинковая батарея (типа Крона)
- Соединительные провода
Схема:
Скетч:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
// подключите пины контроллера к цифровым пинам Arduino // первый двигатель int enA = 9; int in1 = 7; int in2 = 6; // второй двигатель int enB = 3; int in3 = 5; int in4 = 4; void setup() { // инициализируем все пины для управления двигателями как outputs pinMode(enA, OUTPUT); pinMode(enB, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); } // эта функция обеспечит вращение двигателей в двух направлениях на установленной скорости void demoOne() { // запуск двигателя A digitalWrite(in1, HIGH); digitalWrite(in2, LOW); // устанавливаем скорость 100 из доступного диапазона 0~255 analogWrite(enA, 100); // запуск двигателя B digitalWrite(in3, HIGH); digitalWrite(in4, LOW); // устанавливаем скорость 100 из доступного диапазона 0~255 analogWrite(enB, 100); delay(2000); // меняем направление вращения двигателей digitalWrite(in1, LOW); digitalWrite(in2, HIGH); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); delay(2000); // выключаем двигатели digitalWrite(in1, LOW); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, LOW); } // эта функция обеспечивает работу двигателей во всем диапазоне возможных скоростей void demoTwo() { // обратите внимание, что максимальная скорость определяется самим двигателем и напряжением питания // ШИМ-значения генерируются функцией analogWrite() // и зависят от вашей платы управления // запускаем двигатели digitalWrite(in1, LOW); digitalWrite(in2, HIGH); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); // ускорение от нуля до максимального значения for (int i = 0; i < 256; i++) { analogWrite(enA, i); analogWrite(enB, i); delay(20); } // торможение от максимального значения к минимальному for (int i = 255; i >= 0; —i) { analogWrite(enA, i); analogWrite(enB, i); delay(20); } // теперь отключаем моторы digitalWrite(in1, LOW); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, LOW); } void loop() { demoOne(); delay(1000); demoTwo(); delay(1000); } |
Статья о четырехканальном драйвере моторов RKP-MDS-L293D на двух микросхемах L293D. Электрическая схема, функциональная диаграмма, подключение к Ардуино, подключение DC-моторов, примеры программного кода.
Подключение драйвера RKP-MDS-L293D Motor Shield L293D к Arduino UNO
Модуль управления моторами RKP-MDS-L293D на микросхемах L293D предназначен для управления различными типами двигателей — постоянного тока (до 4-х шт.), сервомоторов (до 2-х шт.) и шаговых двигателей (до 2-х шт.) совместно с Arduino.
Электрическая схема драйвера.
На электрической схеме драйвера RKP-MDS-L293D Motor Driver L293D видно, что режимы управление двигателями постоянного тока и шаговыми двигателями осуществляется через микросхему 74HCT595N (см. рис. 1).
Функциональная диаграмма микросхемы 74HCT595N
Это регистр последовательного сдвига с защелкой.
Скачать библиотеку AFMotor Motor shield =>>
В библиотеке AFMotor Motor shield определены pin для драйвера RKP-MDS-L293D по которым осуществляется установка режимов управление моторами:
// Arduino pin names for interface to 74HCT595 latch #define MOTORLATCH 12 = DIR_LATCH // pin 12 Arduino #define MOTORCLK 4 = DIR_CLK // pin 4 Arduino #define MOTORENABLE 7 = DIR_EN // pin 7 Arduino #define MOTORDATA 8 = DIR_SER // pin 8 Arduino
За изменение скорости вращения двигателей отвечаю цепи PWM0A, PWM0B, PWM1A, PWM1B, PWM2A и PWM2B микросхем драйверов двигателей L293D (см. рис. 2).
Соответствие pin драйвера моторов L293D и pin Arduino Uno приведены в таблице 1.
А назначение управляющих битов регистра 74HCT595N для моторов 1- 4 в таблице 2.
Из таблицы 2 видно, чтобы заставить Мотор 1 работать на max скорости нужно в регистр передать byte у которого bit 2 = 1 и bit 3 = 0, а чтобы поменять вращение на противоположное – bit 2 = 0 и bit 3 = 1.
!!Еще одна важная особенность!!!
Питание сервомоторов осуществляется от платы Arduino 5 Вольт. Если сервомоторы потребляют больший ток чем может выдать источник питания Arduino, то всё устройство начинает «глючить».
Это может случиться даже с небольшими серводвигателями, если их где-то заклинит. Тогда ток потребления может возрасти до 0,8-1А. Поэтому питать серводвигатели лучше от дополнительного источника питания.
Подключение питания
Питание моторов подключенных к драйверу RKP-MDS-L293D может осуществляется не сколькими способами:
1. От одного источника питания.
В этом случае питание подается на разъем Arduino 6-12В и с выхода линейного стабилизатора происходит питание цифровых схем Arduino и сервомоторов. Далее питание 6-12В через контакт Vin и установленный джампер, подается на драйвер RKP-MDS-L293D для питания остальных типов моторов.
2. От двух источников питания.
Для этого необходимо снять джампер источника питания. В этом случае источник питания подключенный к разъем у Arduino 6-12В обеспечивает ее работу, цифровых схем драйвера RKP-MDS-L293D и питание серво двигателей. А второй источник питания 4.5-25В — питание двигателей постоянного тока и шаговых двигателей (см. рис. 3).
Схема подключения двигателей к драйверу RKP-MDS-L293D Motor Driver L293D
Подключение моторов постоянного тока (4 DC Motors)
Драйвер RKP-MDS-L293D позволяет одновременно подключить до 4-х двигателей постоянного тока (см. рис. 4).
Подключение шаговых двигателей к драйверу RKP-MDS-L293D Motor Driver L293D
Драйвер Motor Shield L293D позволяет одновременно подключить до 2-х шаговых двигателей (см. рис. 5).
