Управление двигателями постоянного тока, шаговыми и серво с помощью шилда L293D и Arduino
Если вы когда-нибудь мечтали построить собственного робота, машинку на дистанционном управлении или любой проект, который движется, вам нужно будет научиться управлять двигателями. Существуют три основных типа двигателей, с которыми вы столкнётесь: двигатели постоянного тока, шаговые двигатели и сервоприводы. Каждый из них работает по-разному и подходит для разных задач.
Хорошая новость в том, что шилд L293D Motor Driver Shield упрощает управление всеми этими двигателями с помощью Arduino. Он может управлять:
В этом руководстве вы узнаете всё, что нужно знать о шилде L293D Motor Driver Shield, научитесь управлять всеми этими типами двигателей и запустите своего робота в кратчайшие сроки.
Начнём!
Обзор оборудования
Чипсет драйвера
Шилд использует две важные микросхемы, которые работают вместе для управления двигателями: драйверы двигателей L293D и сдвиговый регистр 74HC595.
L293D — это двухканальный драйвер двигателя на базе H-моста. Каждая микросхема может управлять двумя двигателями постоянного тока или одним шаговым двигателем. Поскольку на шилде установлены две таких микросхемы, вы можете одновременно управлять до четырёх двигателями постоянного тока или двумя шаговыми двигателями.
Сдвиговый регистр 74HC595 действует как вспомогательная микросхема. Arduino имеет ограниченное количество доступных управляющих выводов, поэтому эта микросхема принимает сигналы с четырёх выводов Arduino и расширяет их для управления всеми восемью выводами направления, необходимыми двум микросхемам L293D. Это умное решение позволяет не расходовать все выводы Arduino.
Подключение питания двигателей
Двигатели потребляют много энергии, особенно недорогие, поскольку они менее эффективны. Первое, что вам нужно знать — какое напряжение требуется для работы двигателя. Разным двигателям нужно разное напряжение. Некоторые маленькие любительские двигатели рассчитаны на работу от 1,5 В. Однако гораздо чаще используются двигатели, которым нужно от 6 до 12 В. Хорошая новость — шилд L293D Motor Driver Shield может работать с широким диапазоном напряжений, от 4,5 В до 25 В, что делает его подходящим для многих различных типов двигателей.
Вы можете подать это высоковольтное питание для двигателей двумя способами: либо через разъём DC на плате Arduino, либо через двухконтактную клеммную колодку на шилде с надписью EXT_PWR.
Если вы хотите упростить задачу и использовать один источник питания для Arduino и двигателей — например, если вы строите двухколёсного робота, питающегося от одной батареи — вы можете просто подключить источник питания к разъёму DC на Arduino:
или к двухконтактной колодке EXT_PWR на шилде:
Затем установите перемычку PWR на шилде. Этот способ проще в настройке, но есть важное ограничение: использовать этот метод можно только когда напряжение питания двигателей не превышает 12 В.
Если вы предпочитаете использовать два отдельных источника питания — один для Arduino и один для двигателей — подключите источник питания Arduino к его разъёму DC или просто используйте USB-кабель для питания. Затем подключите источник питания двигателей к колодке EXT_PWR на шилде. При использовании этого метода обязательно снимите перемычку PWR с шилда.
Это в целом рекомендуемый и более безопасный метод питания моторных проектов, поскольку он изолирует питание двигателей от питания Arduino.
Предупреждение:
Никогда не подавайте питание одновременно на клемму EXT_PWR и на плату Arduino, пока перемычка PWR установлена. Это соединит два источника питания вместе, что может вызвать короткое замыкание и повредить как шилд, так и Arduino.
Подключение двигателей постоянного тока
Шилд имеет четыре точки подключения двигателей, обозначенных M1, M2, M3 и M4 по его краям. Вы можете подключить до четырёх двигателей постоянного тока, работающих при напряжении от 4,5 В до 25 В.
Каждый канал двигателя может обеспечить до 600 миллиампер (мА) непрерывного тока и выдерживать кратковременные пики до 1,2 ампер (А) на канал.
Подключение шаговых двигателей
Вы также можете использовать шилд для подключения двух шаговых двигателей. Первый шаговый двигатель подключается к M1–M2, а второй — к M3–M4.
Подключение сервоприводов
Шилд также включает два 3-контактных разъёма для подключения сервоприводов.
Однако при работе с сервоприводами есть один нюанс. Они получают питание непосредственно от 5-вольтового выхода Arduino, а не от внешнего источника питания двигателей. Это не идеально, потому что сервоприводы могут потреблять довольно много энергии, что может привести к перегреву стабилизатора напряжения Arduino или создать электрические помехи. На шилде есть небольшой конденсатор ёмкостью 100 мкФ для смягчения этой проблемы, но лучше перестраховаться. Если вы хотите использовать сервоприводы с этим шилдом, ограничьтесь маленькими лёгкими сервоприводами, например, популярным SG90.
Дополнительные особенности
Шилд также имеет несколько полезных функций:
На нём установлена матрица подтягивающих резисторов, которая удерживает двигатели в выключенном состоянии при первом включении, предотвращая неожиданное движение.
Также есть небольшой встроенный светодиод, который сигнализирует о корректной работе источника питания двигателей.
На шилде расположена кнопка RESET, которая является просто удобно расположенной копией кнопки сброса самого Arduino.
В нижнем правом углу находятся подключения для всех шести аналоговых выводов Arduino, а также выводы питания и заземления. Вы можете установить сюда штыревые разъёмы для подключения датчиков или других устройств при использовании шилда.
Подключение выводов Arduino к шилду
Важно знать, какие выводы Arduino использует шилд, чтобы случайно не попытаться использовать их для чего-то другого.
Для управления двигателями постоянного тока и шаговыми двигателями шилд использует цифровые выводы 3, 4, 5, 6, 7, 8, 11 и 12.
Для сервоприводов он использует выводы 9 и 10.
Выводы 2, 13 и все аналоговые выводы остаются полностью свободными, так что вы можете использовать их для других проектов или датчиков при использовании этого шилда.
Установка библиотеки AFMotor
Прежде чем мы сможем использовать шилд, нам нужно установить библиотеку AFMotor. Эта библиотека позволяет нам легко управлять двигателями постоянного тока, шаговыми двигателями и сервоприводами с помощью простых команд.
Для установки библиотеки:
Сначала откройте Arduino IDE. Затем нажмите на значок Менеджер библиотек на левой боковой панели.
Введите «Adafruit Motor Shield» в поле поиска для фильтрации результатов.
Найдите библиотеку Adafruit Motor Shield library (V1 Firmware) от Adafruit.
Нажмите кнопку Install, чтобы добавить её в Arduino IDE.
Эксперимент 1 — Управление двигателем постоянного тока с помощью шилда L293D
Теперь, когда всё настроено, давайте начнём наш первый эксперимент. В этом эксперименте мы научимся управлять двигателем постоянного тока с помощью шилда L293D Motor Driver Shield.
Схема подключения
Начните с аккуратной установки шилда поверх платы Arduino.
Далее вам нужно подать питание на двигатель. Для этого эксперимента мы используем BO-двигатели, которые обычно применяются в двухколёсных роботах. Эти двигатели работают при напряжении от 3 до 12 В, поэтому мы подключим батарею 9 В или источник питания к клемме EXT_PWR на шилде.
Вот важный шаг, который нельзя пропустить. Нужно снять перемычку PWR перед подачей питания. Это позволит разделить питание двигателей и питание Arduino и поможет предотвратить повреждение.
Наконец, возьмите провода двигателя и подключите их к одной из клемм M1, M2, M3 или M4 на шилде. В нашем примере мы подключаем к M4.
Код Arduino
Следующий скетч демонстрирует, как управлять скоростью и направлением вращения двигателя постоянного тока. Вы можете использовать эту программу как отправную точку для собственных экспериментов и проектов.
Скетч заставляет двигатель начать вращаться в одном направлении и постепенно разгоняться до максимальной скорости. Затем он медленно замедляется до полной остановки. После короткой паузы двигатель меняет направление вращения и повторяет весь процесс, вращаясь в противоположную сторону. Этот цикл повторяется снова и снова.
#include <AFMotor.h>
AF_DCMotor motor(4);
void setup() {
}
void loop() {
// Turn on motor
motor.run(FORWARD);
// Accelerate from zero to maximum speed
for (int i = 0; i < 255; i++) {
motor.setSpeed(i);
delay(10);
}
// Decelerate from maximum speed to zero
for (int i = 255; i != 0; i--) {
motor.setSpeed(i);
delay(10);
}
// Now turn off motor
motor.run(RELEASE);
delay(500);
// Now change motor direction
motor.run(BACKWARD);
// Accelerate from zero to maximum speed
for (int i = 0; i < 255; i++) {
motor.setSpeed(i);
delay(10);
}
// Decelerate from maximum speed to zero
for (int i = 255; i != 0; i--) {
motor.setSpeed(i);
delay(10);
}
// Now turn off motor
motor.run(RELEASE);
delay(500);
}
Объяснение кода
Программа начинается с подключения библиотеки AFMotor.h:
#include <AFMotor.h>
Далее мы создаём объект двигателя с помощью класса AF_DCMotor. При его настройке нужно указать, к какому порту на шилде подключён ваш двигатель. Если двигатель подключён к порту M1, используйте число 1. Для M2 — число 2, и так далее. В этом примере мы используем порт M4, поэтому указываем число 4.
AF_DCMotor motor(4);
Если вы хотите управлять несколькими двигателями одновременно, просто создайте дополнительные объекты двигателей для каждого из них. Например, если двигатели подключены к M1 и M2, вы создадите два отдельных объекта с соответствующими номерами портов.
AF_DCMotor motorA(1);
AF_DCMotor motorB(2);
После создания объекта программа использует две важные команды для управления двигателем.
setSpeed(speed) — эта функция управляет скоростью вращения двигателя. Значение speed может варьироваться от 0 до 255, где 0 означает, что двигатель полностью выключен, а 255 — что он работает на полной скорости. Вы можете изменять это значение в любой момент программы.
run(command) — эта функция указывает двигателю, в каком направлении вращаться. Возможные команды:
FORWARD— заставляет двигатель вращаться вперёд.BACKWARD— заставляет двигатель вращаться в обратном направлении.RELEASE— полностью останавливает двигатель, что аналогично установкеspeedв 0. Имейте в виду, что при такой остановке двигатель не остановится мгновенно, потому что шилд не имеет системы торможения. Двигатель будет постепенно замедляться до остановки.
Эксперимент 2 — Управление униполярным шаговым двигателем 28BYJ-48 с помощью шилда L293D
В этом эксперименте мы научимся управлять униполярным шаговым двигателем, таким как популярный 28BYJ-48, с помощью шилда драйвера двигателя L293D. 28BYJ-48 — это маленький шаговый двигатель на 5 В, которому требуется 2048 шагов для совершения одного полного оборота.
Схема подключения
Для подключения шагового двигателя можно использовать либо клеммы M1–M2 (порт #1), либо клеммы M3–M4 (порт #2) на шилде L293D Motor Driver Shield. В этом примере мы подключим двигатель к клеммам M3–M4. Одна обмотка шагового двигателя должна быть подключена к клемме M3, а другая — к клемме M4. Если ваш шаговый двигатель имеет общий провод (что типично для униполярных шаговых двигателей), этот провод можно оставить неподключённым.
Для правильного питания шагового двигателя необходимо подключить внешний источник питания 5 В к клемме EXT_PWR на шилде.
Как и раньше, обязательно снимите перемычку PWR с шилда перед включением. Этот шаг очень важен для предотвращения короткого замыкания между источниками питания.
Код Arduino
Следующий скетч демонстрирует, как управлять униполярным шаговым двигателем 28BYJ-48 несколькими различными способами.
#include <AFMotor.h>
// Number of steps per output rotation
// Change this as per your motor's specification
const int stepsPerRevolution = 2048;
// connect motor to port #2 (M3 and M4)
AF_Stepper motor(stepsPerRevolution, 2);
void setup() {
motor.setSpeed(10); // 10 rpm
}
void loop() {
// Single coil steps
motor.step(stepsPerRevolution, FORWARD, SINGLE);
motor.step(stepsPerRevolution, BACKWARD, SINGLE);
// Double coil steps
motor.step(stepsPerRevolution, FORWARD, DOUBLE);
motor.step(stepsPerRevolution, BACKWARD, DOUBLE);
// Interleave coil steps
motor.step(stepsPerRevolution, FORWARD, INTERLEAVE);
motor.step(stepsPerRevolution, BACKWARD, INTERLEAVE);
// Micrsostep steps
motor.step(stepsPerRevolution, FORWARD, MICROSTEP);
motor.step(stepsPerRevolution, BACKWARD, MICROSTEP);
}
Объяснение кода
Скетч начинается с подключения библиотеки AFMotor.h, как и в первом эксперименте.
#include <AFMotor.h>
Далее мы создаём переменную stepsPerRevolution, которая определяет, сколько шагов нужно двигателю для совершения одного полного оборота. Поскольку 28BYJ-48 требует 2048 шагов для полного оборота, мы устанавливаем это значение в 2048.
const int stepsPerRevolution = 2048;
После этого мы создаём объект шагового двигателя с помощью класса AF_Stepper. При создании этого объекта мы предоставляем две информации: количество шагов на оборот и номер порта, к которому подключён двигатель. В этом примере двигатель подключён к порту 2, что соответствует M3–M4.
AF_Stepper motor(stepsPerRevolution, 2);
В секции setup скетча скорость двигателя устанавливается с помощью функции setSpeed(). Эта функция определяет, насколько быстро вращается двигатель. Вместо шкалы скорости от 0 до 255, шаговые двигатели используют параметр RPM (обороты в минуту). Он указывает двигателю, сколько полных оборотов вы хотите сделать за одну минуту.
void setup() {
motor.setSpeed(10); // 10 rpm
}
В секции loop программа многократно вызывает функцию step() для перемещения двигателя различными способами. При каждом вызове этой функции нужно указать три параметра: количество шагов, направление (FORWARD или BACKWARD) и режим шагания.
Доступно несколько режимов шагания:
SINGLE— в каждый момент запитана только одна обмотка двигателя. Это потребляет меньше энергии, но обеспечивает меньший крутящий момент.DOUBLE— одновременно запитаны две обмотки, что даёт двигателю больший крутящий момент для тяжёлых нагрузок.INTERLEAVE— этот режим чередует одиночные и двойные шаги для получения удвоенного разрешения (но при этом скорость уменьшается вдвое).MICROSTEP— в этом режиме обмотки управляются с помощью ШИМ для создания плавного движения между шагами.
void loop() {
// Single coil steps
motor.step(stepsPerRevolution, FORWARD, SINGLE);
motor.step(stepsPerRevolution, BACKWARD, SINGLE);
// Double coil steps
motor.step(stepsPerRevolution, FORWARD, DOUBLE);
motor.step(stepsPerRevolution, BACKWARD, DOUBLE);
// Interleave coil steps
motor.step(stepsPerRevolution, FORWARD, INTERLEAVE);
motor.step(stepsPerRevolution, BACKWARD, INTERLEAVE);
// Micrsostep steps
motor.step(stepsPerRevolution, FORWARD, MICROSTEP);
motor.step(stepsPerRevolution, BACKWARD, MICROSTEP);
}
Эксперимент 3 — Управление биполярным шаговым двигателем NEMA 17 с помощью шилда L293D
В нашем третьем эксперименте мы будем управлять биполярным шаговым двигателем NEMA 17, который очень популярен в 3D-принтерах и станках ЧПУ. Он работает при 12 В и совершает 200 шагов для одного полного оборота.
Схема подключения
Как и с предыдущим двигателем, мы подключим NEMA 17 к клеммам M3–M4 (порт #2).
Для питания этого двигателя необходимо подключить внешний источник питания 12 В к клемме EXT_PWR на шилде. И снова не забудьте снять перемычку PWR перед включением.
Код Arduino
Следующий скетч демонстрирует, как управлять биполярным шаговым двигателем NEMA 17.
#include <AFMotor.h>
// Number of steps per output rotation
// Change this as per your motor's specification
const int stepsPerRevolution = 200;
// connect motor to port #2 (M3 and M4)
AF_Stepper motor(stepsPerRevolution, 2);
void setup() {
motor.setSpeed(10); // 10 rpm
}
void loop() {
// Single coil steps
motor.step(stepsPerRevolution, FORWARD, SINGLE);
motor.step(stepsPerRevolution, BACKWARD, SINGLE);
// Double coil steps
motor.step(stepsPerRevolution, FORWARD, DOUBLE);
motor.step(stepsPerRevolution, BACKWARD, DOUBLE);
// Interleave coil steps
motor.step(stepsPerRevolution, FORWARD, INTERLEAVE);
motor.step(stepsPerRevolution, BACKWARD, INTERLEAVE);
// Micrsostep steps
motor.step(stepsPerRevolution, FORWARD, MICROSTEP);
motor.step(stepsPerRevolution, BACKWARD, MICROSTEP);
}
Объяснение кода
Вы, вероятно, заметили, что эта программа выглядит почти идентично предыдущей. Единственное отличие — значение stepsPerRevolution. В предыдущем эксперименте мы установили его в 2048, потому что именно столько требовалось двигателю 28BYJ-48. Теперь, для двигателя NEMA 17, мы устанавливаем его в 200. Всё остальное в программе работает точно так же, используя те же функции setSpeed() и step() для управления скоростью, направлением и режимом шагания двигателя.
Эксперимент 4 — Управление сервоприводом с помощью шилда L293D
В нашем последнем эксперименте мы научимся управлять сервоприводом с помощью шилда L293D. Сервоприводы идеально подходят для таких вещей, как манипуляторы роботов или подвижные части, требующие точного позиционирования.
Схема подключения
На шилде есть два специальных 3-контактных разъёма для удобного подключения сервоприводов. Эти разъёмы подключены к ШИМ-выводам Arduino D9 и D10. Вывод D10 управляет Servo 1, а вывод D9 управляет Servo 2.
Одно из преимуществ работы с сервоприводами — они получают питание непосредственно от 5-вольтового выхода Arduino. Это означает, что вам не нужно беспокоиться о подключении внешнего источника питания к клемме EXT_PWR, как мы делали в предыдущих экспериментах.
Код Arduino
Программа ниже основана на встроенном примере Arduino Sweep, который плавно перемещает вал сервопривода вперёд-назад на 180 градусов.
#include <Servo.h>
int servoPin = 10;
Servo servo; // create servo object to control a servo
void setup() {
servo.attach(servoPin);
}
void loop() {
// sweeps from 0 degrees to 180 degrees
for (int angle = 0; angle < 180; angle++) {
servo.write(angle);
delay(15);
}
// sweeps from 180 degrees to 0 degrees
for (int angle = 180; angle > 0; angle--) {
servo.write(angle);
delay(15);
}
}
Объяснение кода
Скетч начинается с подключения библиотеки Servo, которая поставляется вместе с Arduino IDE. Эта библиотека предоставляет простые команды, позволяющие указать сервоприводу точную позицию, в которую мы хотим его переместить.
#include <Servo.h>
Далее мы указываем Arduino, к какому выводу подключён наш сервопривод. В этом примере мы используем вывод 10.
int servoPin = 10;
Затем мы создаём объект servo, который будем использовать для связи с сервоприводом и управления им.
Servo servo;
В функции setup() мы привязываем объект servo к выбранному ранее выводу. Это сообщает Arduino, какой вывод должен отправлять сигналы сервоприводу.
servo.attach(servoPin);
Теперь в функции loop() мы сначала перемещаем сервопривод от 0 до 180 градусов. Мы используем цикл for, который увеличивает угол на один градус за раз. При каждом проходе цикла команда servo.write(angle); перемещает сервопривод в новое положение. Для плавности движения мы добавляем небольшую паузу в 15 миллисекунд после каждого перемещения.
// sweeps from 0 degrees to 180 degrees
for (int angle = 0; angle < 180; angle++) {
servo.write(angle);
delay(15);
}
Как только сервопривод достигнет 180 градусов, мы перемещаем его обратно к 0 градусам. Мы делаем это с помощью ещё одного цикла for, который уменьшает угол на один градус за раз, пока мы не вернёмся к 0.
// sweeps from 180 degrees to 0 degrees
for (int angle = 180; angle > 0; angle--) {
servo.write(angle);
delay(15);
}
После достижения 0 градусов весь процесс начинается заново. Это заставляет сервопривод непрерывно перемещаться вперёд-назад между 0 и 180 градусами.