Урок 03Легко30 минOʻZ · РУ · ENЕсть в симуляторе

Моторы и драйвер L298N

Почему мотор нельзя подключить прямо к пину, как H-мост L298N задаёт направление и скорость, как безопасно питать от него Uno и что делает setMotor() строка за строкой.

Видеона YouTube

Главное

  • Пин даёт 20 мА, а мотору TT нужно около 0,3 А в езде и до 1 А, когда его вал заблокирован.
  • H-мост меняет направление тока через мотор, поэтому мотор может крутиться в обе стороны.
  • IN1 и IN2 задают направление, а ШИМ на ENA (перемычка с него снята) задаёт скорость от 0 до 255.
  • L298N теряет внутри около 1,8 В: из 6 В моторам достаётся около 4,2 В.
  • +5V драйвера L298N питает пин 5V платы Uno; нужна общая земля (GND), и никогда не подавайте батарею на пин 5V.

Мотору нужен гораздо больший ток, чем может дать пин Arduino. Поэтому между ними стоит драйвер моторов L298N. Uno посылает слабые сигналы, а L298N подаёт на моторы питание от батареи: включает и выключает их, крутит вперёд или назад, быстро или медленно.

Почему мотор нельзя подключить прямо к пину

Мотор-редуктор TT: маленький мотор постоянного тока с редуктором 1:48. Колесо 65 мм надевается на белый вал.

Фото: Lukas Ruge · CC0

Сравните числа:

Что Ток
Пин Uno, безопасно 20 мА
Пин Uno, абсолютный максимум 40 мА
Мотор TT крутится свободно около 100–150 мА
Мотор TT везёт робота около 300 мА
Мотор TT, вал заблокирован (застопорен) примерно до 1000 мА (1 А)

Даже мотору, который крутится свободно, нужно как минимум в пять раз больше тока, чем пин может безопасно дать. А заблокированному колесу — в пятьдесят раз больше.

Есть и вторая проблема. Мотор — это катушка из провода. Когда ток через катушку резко прекращается, она выдаёт короткий выброс высокого напряжения. Такой выброс может вывести из строя пин или транзистор. В модуле L298N есть диоды, которые гасят эти выбросы. Поэтому никогда не подключайте мотор прямо к пину Arduino.

Идея H-моста

Чтобы мотор постоянного тока закрутился в другую сторону, нужно пустить через него ток в обратном направлении. H-мост делает это с помощью четырёх ключей (выключателей).

Представьте букву H. Мотор — это перекладина посередине. На каждой из двух вертикальных палочек стоит один ключ выше мотора и один ниже. Верхние концы подключены к плюсу батареи, а нижние — к GND.

  • Замкните левый верхний и правый нижний ключи. Ток пойдёт через мотор слева направо, и мотор закрутится в одну сторону.
  • Замкните правый верхний и левый нижний ключи. Ток пойдёт справа налево, и мотор закрутится в другую сторону.
  • Замкните оба нижних ключа. Теперь оба провода мотора соединены между собой. Вращающийся мотор работает как генератор, и такое короткое замыкание быстро его замедляет: мотор тормозит.
  • Разомкните все четыре ключа. Мотор отключён. Он вращается по инерции, пока его не остановит трение.

Если замкнуть оба ключа на одной палочке буквы H, плюс батареи окажется соединён прямо с GND. Никакое сочетание сигналов на входах этого не сделает. В микросхеме L298N два H-моста, поэтому один модуль управляет двумя моторами. Её ключи — это транзисторы, поэтому они могут включаться и выключаться очень быстро.

Клеммы и пины L298N

L298N стоит между батареей и двумя моторами. Uno управляет им через ENA, IN1–IN4 и ENB.
Клемма или пин Для чего В робот-машине
+12V Питание моторов, 5–35 В (название условное) Плюс батареи (красный провод), около 6 В
GND Земля для питания и для сигналов Минус батареи (чёрный провод) и пин GND платы Uno
+5V Выход собственного стабилизатора модуля на 5 В, пока надета маленькая перемычка стабилизатора (часто подписана 5V-EN) Пин 5V платы Uno, а на роботах с HC-SR04 — ещё и VCC датчика
OUT1, OUT2 Мотор A Левый мотор
OUT3, OUT4 Мотор B Правый мотор, выводы переставлены (см. ниже)
ENA, ENB Разрешение (enable): включают и выключают моторы A и B и задают их скорость D5 и D6 (с широтно-импульсной модуляцией, ШИМ)
IN1, IN2 Направление мотора A D4 и D7
IN3, IN4 Направление мотора B D8 и D12

Каждый канал может дать до 2 А, а без дополнительного охлаждения — около 1 А. Мотору TT во время езды нужно около 0,3 А.

На новом модуле на ENA и ENB надеты маленькие колпачки — перемычки (джамперы). Перемычка соединяет пин с 5 В. Тогда мотор всегда включён: он крутится на полной скорости всякий раз, когда на IN1 и IN2 разные уровни. Чтобы управлять скоростью, снимите обе перемычки и подключите ENA и ENB к пинам Uno с ШИМ. В симуляторе провод от ENA к пину Uno означает, что перемычка снята.

Таблица истинности

Для мотора A:

ENA IN1 IN2 Мотор
HIGH HIGH LOW крутится вперёд
HIGH LOW HIGH крутится назад
HIGH HIGH HIGH тормозит
HIGH LOW LOW тормозит
LOW любой любой вращается по инерции (свободно)

Мотор B работает так же через ENB, IN3 и IN4. «Вперёд» здесь означает направление, в котором мотор крутится, когда на OUT1 плюс, а на OUT2 минус. А куда покатится робот, зависит ещё и от того, как установлен мотор.

Скорость и ШИМ

ШИМ: analogWrite 64, 128 и 191 включают пин на 25%, 50% и 75% времени, и мотор крутится быстрее.

analogWrite(ENA, value) включает и выключает ENA примерно 980 раз в секунду. Значение от 0 до 255 задаёт, какую долю времени мотор получает питание. Мотор и колесо слишком тяжёлые, чтобы успевать за такими быстрыми импульсами. Они откликаются на среднее значение:

analogWrite(ENA, ...) Доля времени «включено» Среднее напряжение на моторе
255 100 % около 4,2 В
200 78 % около 3,3 В
128 50 % около 2,1 В
0 0 % нет: мотор вращается по инерции

При малых значениях мотор только гудит и не крутится: среднее напряжение слишком мало, чтобы преодолеть трение в редукторе. С какого значения это начинается, зависит от мотора, батареек и пола. Поэтому в проекте «Робот, который держит дистанцию» скетч никогда не задаёт скорость меньше 90.

Куда уходят вольты

В L298N ключами служат биполярные транзисторы. Ток мотора всегда проходит через два из них: один вверху буквы H и один внизу. Вместе они забирают около 1,8 В. Поэтому от батареи на 6 В моторам достаётся только около 4,2 В. Симулятор использует те же числа.

Моторы TT рассчитаны на 3–6 В, так что 4,2 В им подходит. Но робот едет медленнее, чем при полных 6 В.

Как быстро едет робот? За один оборот колесо диаметром 65 мм продвигает его на π × 65 мм, то есть примерно на 20 см. Значит, если колесо делает 150 оборотов в минуту, робот проезжает около 30 м в минуту, или 0,5 м/с.

Питание Uno от L298N

У робота только одна батарея. Собственный стабилизатор L298N на 5 В питает ещё и Uno: клемма +5V драйвера соединена с пином 5V платы Uno.

Чтобы выдавать полные 5 В, стабилизатору нужно около 7 В на входе. От четырёх батареек AA он выдаёт около 4,4 В. Это немного низковато, но для работы Uno этого хватает.

Не подключайте +5V драйвера L298N и к VIN. VIN ведёт к собственному стабилизатору Uno, которому нужно 7–12 В. Если на его входе около 4,4 В, микросхема получает слишком мало напряжения, чтобы работать. Симулятор проверяет обе эти ошибки.

Общая земля

Напряжение всегда измеряют между двумя точками. Когда Uno выставляет на D4 HIGH, пин D4 оказывается на несколько вольт выше GND платы Uno. L298N заметит это, только если будет отсчитывать напряжение от того же GND. Вот почему GND драйвера L298N соединён проводом с пином GND платы Uno. В робот-машине по этому проводу ещё и возвращается к батарее ток, которым питается Uno. Если провода нет, симулятор сообщает, что нет общей земли.

Почему выводы правого мотора переставлены

Оба мотора одинаковые, но правый установлен развёрнутым — зеркально левому. При таком же подключении тот же сигнал «вперёд» крутил бы правое колесо назад, и робот вертелся бы на месте. Поэтому выводы правого мотора специально переставлены: M+ идёт на OUT4, а M- — на OUT3. Теперь при одном и том же сигнале оба колеса катятся вперёд. Это исправлено в подключении, поэтому в коде с обоими моторами можно обращаться одинаково.

Подключение

Вот полное подключение робота с этой страницы.

ОткудаКудаЗачем
Батарея +L298N +12VПитание моторов: около 6 В от четырёх батареек AA
Батарея -L298N GNDМинус батареи
L298N +5VUno 5VСтабилизатор драйвера питает Uno: около 4,4 В
L298N GNDUno GNDОбщая земля: сигналам нужен общий 0 В
Uno D5L298N ENAСкорость левого мотора (ШИМ); перемычка ENA снята
Uno D4L298N IN1Направление левого мотора
Uno D7L298N IN2Направление левого мотора
Uno D8L298N IN3Направление правого мотора
Uno D12L298N IN4Направление правого мотора
Uno D6L298N ENBСкорость правого мотора (ШИМ); перемычка ENB снята
Левый мотор M+L298N OUT1
Левый мотор M-L298N OUT2
Правый мотор M+L298N OUT4Переставлено специально: этот мотор стоит зеркально
Правый мотор M-L298N OUT3Переставлено специально: этот мотор стоит зеркально
Детали для урока

Скетч MotorTest

MotorTest.ino
// Motor test: both motors speed up, slow down, then the same backwards.
// L298N: ENA -> D5, IN1 -> D4, IN2 -> D7 (left), ENB -> D6, IN3 -> D8, IN4 -> D12 (right)

const byte ENA = 5, IN1 = 4, IN2 = 7;
const byte ENB = 6, IN3 = 8, IN4 = 12;

// speed from -255 (full backwards) to 255 (full forwards); 0 lets the motor coast
void setMotor(byte enablePin, byte inA, byte inB, int speed) {
  speed = constrain(speed, -255, 255);
  digitalWrite(inA, speed > 0);        // IN1 high, IN2 low: forwards
  digitalWrite(inB, speed < 0);        // IN1 low, IN2 high: backwards
  analogWrite(enablePin, abs(speed));  // PWM on ENA: how fast
}

void drive(int left, int right) {
  setMotor(ENA, IN1, IN2, left);
  setMotor(ENB, IN3, IN4, right);
}

void ramp(int direction) {
  for (int s = 0; s <= 255; s += 5) {
    drive(direction * s, direction * s);
    delay(30);
  }
  for (int s = 255; s >= 0; s -= 5) {
    drive(direction * s, direction * s);
    delay(30);
  }
}

void setup() {
  const byte pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
  for (byte pin : pins) pinMode(pin, OUTPUT);
}

void loop() {
  ramp(1);       // forwards
  delay(500);
  ramp(-1);      // backwards
  delay(500);
}

ramp(1) поднимает скорость обоих моторов от 0 до 255 шагами по 5, по одному шагу каждые 30 мс. Затем опускает скорость обратно до 0. Это 52 шага в каждую сторону: около 1,6 секунды на разгон и 1,6 секунды на замедление. После паузы в полсекунды ramp(-1) делает то же самое, но назад. Полный проход loop() занимает около 7 секунд. setup() делает шесть управляющих пинов выходами с помощью короткого цикла for по массиву.

setMotor() строка за строкой

Все скетчи на этом сайте, которые управляют моторами, используют одни и те же две функции. Вот первая из них:

void setMotor(byte enablePin, byte inA, byte inB, int speed) {
  speed = constrain(speed, -255, 255);
  digitalWrite(inA, speed > 0);        // IN1 high, IN2 low: forwards
  digitalWrite(inB, speed < 0);        // IN1 low, IN2 high: backwards
  analogWrite(enablePin, abs(speed));  // PWM on ENA: how fast
}
  • Строка 1. Функция получает три пина одного мотора и скорость от -255 (полный ход назад) до 255 (полный ход вперёд).
  • Строка 2. constrain() удерживает скорость в этих пределах. Скорость 300 превращается в 255.
  • Строка 3. speed > 0 — это сравнение, поэтому его результат — true или false. true здесь означает HIGH, а false — LOW. Значит, на IN1 будет HIGH, только когда скорость положительная.
  • Строка 4. Точно так же на IN2 будет HIGH, только когда скорость отрицательная.
  • Строка 5. abs() убирает знак минус: -160 превращается в 160. Это значение идёт на ШИМ пина ENA и задаёт, как быстро крутится мотор.

Три примера для левого мотора:

Вызов IN1 IN2 ENA Мотор
setMotor(ENA, IN1, IN2, 200) HIGH LOW ШИМ 200 вперёд, быстро
setMotor(ENA, IN1, IN2, -160) LOW HIGH ШИМ 160 назад, медленнее
setMotor(ENA, IN1, IN2, 0) LOW LOW всё время LOW по инерции

При скорости 0 мотор вращается по инерции, потому что на ENA LOW. Он не тормозит.

Вторая функция, drive(left, right), вызывает setMotor() дважды: с ENA, IN1 и IN2 для левого мотора и с ENB, IN3 и IN4 для правого. drive(200, 200) — это езда прямо вперёд, drive(-160, -160) — назад, а drive(170, -170) — разворот вправо на месте.

Попробуйте в симуляторе

Запустите робота на арене. Он медленно трогается вперёд, разгоняется, замедляется и останавливается. Через полсекунды он делает то же самое задним ходом. Показания моторов на панели в реальном времени растут и падают вместе с каждым разгоном и замедлением. В начале каждого разгона колёса ещё не крутятся: напряжение пока слишком мало.

Дальше в проекте «Первый заезд» та же функция drive() ведёт машину по квадрату.

Проверьте себя

1Почему мотор TT нельзя подключить прямо к пину Arduino?

Пин безопасно отдаёт 20 мА, а мотору нужно около 0,3 А в езде и до 1 А, когда вал заблокирован. К тому же выброс напряжения от выключенного мотора может повредить пин.

2На ENA HIGH, а на IN1 и IN2 — LOW. Что делает мотор?

Он тормозит. Оба провода мотора соединены с GND, поэтому мотор быстро останавливается.

3Почему от батареи на 6 В моторам достаётся только около 4,2 В?

Биполярные транзисторы L298N теряют около 1,8 В внутри моста.

Задание

В симуляторе подключите правый мотор так же, как левый: M+ к OUT3, а M- к OUT4. Запустите MotorTest на арене и посмотрите, что делает робот. Затем заставьте его снова ехать прямо, не трогая провода: для этого измените одну строку скетча.

Подсказка

В какую сторону крутится мотор, зависит только от того, на каком из двух его пинов IN стоит HIGH.