Raspberry Pi Pico: управление двигателем постоянного тока с драйвером L298N (MicroPython)
Узнайте, как управлять скоростью и направлением вращения двигателя постоянного тока (DC мотора) с помощью драйвера L298N и Raspberry Pi Pico, запрограммированного на MicroPython. DC моторы широко используются в электронике для проектов роботов и не только. Вы узнаете, как заставить двигатель вращаться вперед, назад, останавливаться и управлять его скоростью, создав собственный модуль MicroPython.
Впервые работаете с Raspberry Pi Pico? Прочитайте следующее руководство: Начало работы с Raspberry Pi Pico (и Pico W).
В этом руководстве мы рассмотрим следующие темы:
Предварительные требования
Прежде чем продолжить, убедитесь, что выполнены следующие предварительные требования.
Прошивка MicroPython
Для выполнения этого руководства вам необходима прошивка MicroPython, установленная на плату Raspberry Pi Pico. Вам также потребуется IDE для написания и загрузки кода на плату.
Рекомендуемая IDE для MicroPython на Raspberry Pi Pico – это Thonny IDE. Следуйте следующему руководству, чтобы узнать, как установить Thonny IDE, прошить MicroPython и загрузить код на плату.
Кроме того, если вам нравится программировать с помощью VS Code, вы можете начать со следующего руководства:
Необходимые компоненты
Вам также понадобятся следующие компоненты:
Raspberry Pi Pico
Драйвер двигателя L298N
Миниатюрный DC мотор
Керамический конденсатор 0.1 мкФ
Соединительные провода
Батарейный отсек 4x AA
Знакомство с драйвером L298N
Существует несколько способов управления DC моторами. Мы будем использовать драйвер L298N, но подойдет любой аналогичный драйвер двигателя.
Драйвер L298N показан на следующем изображении:
Использование драйвера L298N подходит для большинства любительских моторов, которым для работы требуется от 6 В до 12 В. Кроме того, он позволяет управлять двумя DC моторами одновременно, что идеально подходит, если вы хотите собрать робота.
Уже знакомы с драйвером L298N? Перейдите к разделу подключения.
Распиновка драйвера L298N
Давайте рассмотрим распиновку драйвера L298N и разберемся, как он работает.
Драйвер имеет клеммную колодку с двумя контактами на каждой стороне для каждого мотора. OUT1 и OUT2 слева и OUT3 и OUT4 справа.
OUT1: DC мотор A, клемма +
OUT2: DC мотор A, клемма -
OUT3: DC мотор B, клемма +
OUT4: DC мотор B, клемма -
Внизу находится клеммная колодка с тремя контактами: +12V, GND и +5V. Клемма +12V используется для питания моторов. Клемма +5V используется для питания микросхемы L298N. Однако если перемычка установлена, микросхема питается от источника питания моторов, и вам не нужно подавать 5 В на клемму +5V.
Важно: несмотря на название клеммы +12V, вы можете подавать любое напряжение от 5 В до 35 В (но рекомендуемый диапазон составляет от 6 В до 12 В).
Примечание: если вы подаете более 12 В, необходимо снять перемычку и подать 5 В на клемму +5V.
В этом руководстве мы будем использовать 4 батарейки AA по 1.5 В, которые в сумме дают приблизительно 6 В, но вы можете использовать любой другой подходящий источник питания. Например, вы можете использовать лабораторный источник питания для тестирования этого руководства.
Итого:
+12V: клемма +12V – это место, куда вы должны подключить ваш источник питания
GND: GND источника питания
+5V: подайте 5 В, если перемычка снята. Действует как выход 5 В, если перемычка установлена
Перемычка: перемычка установлена – микросхема питается от источника питания моторов. Перемычка снята: необходимо подать 5 В на клемму +5V. Если вы подаете более 12 В, следует снять перемычку
Внизу справа расположены четыре входных контакта и два контакта разрешения (enable). Входные контакты используются для управления направлением вращения DC моторов, а контакты разрешения – для управления скоростью каждого мотора.
IN1: Вход 1 для мотора A
IN2: Вход 2 для мотора A
IN3: Вход 1 для мотора B
IN4: Вход 2 для мотора B
EN1: Контакт разрешения для мотора A
EN2: Контакт разрешения для мотора B
По умолчанию на контактах разрешения установлены перемычки. Вам нужно снять эти перемычки, чтобы управлять скоростью моторов. В противном случае они будут либо остановлены, либо вращаться на максимальной скорости.
Управление DC моторами с помощью L298N
Теперь, когда вы знакомы с драйвером L298N, давайте рассмотрим, как использовать его для управления DC моторами.
Контакты разрешения (Enable)
Контакты разрешения работают как переключатель ВКЛ/ВЫКЛ для моторов. Например:
Если вы отправите сигнал HIGH на контакт разрешения 1, мотор A готов к управлению и работает на максимальной скорости;
Если вы отправите сигнал LOW на контакт разрешения 1, мотор A выключается;
Если вы отправите ШИМ-сигнал, вы можете управлять скоростью мотора. Скорость мотора пропорциональна скважности (duty cycle). Однако обратите внимание, что при малых значениях скважности моторы могут не вращаться и издавать непрерывный жужжащий звук.
Сигнал на контакте разрешения |
Состояние мотора |
|---|---|
HIGH |
Мотор включен |
LOW |
Мотор выключен |
ШИМ (PWM) |
Мотор включен: скорость пропорциональна скважности |
Входные контакты (Input)
Входные контакты управляют направлением вращения моторов. Входы 1 и 2 управляют мотором A, а входы 3 и 4 управляют мотором B.
Если вы подадите LOW на вход 1 и HIGH на вход 2, мотор будет вращаться вперед;
Если вы подадите питание в обратном порядке: HIGH на вход 1 и LOW на вход 2, мотор будет вращаться назад. Мотором B можно управлять тем же способом, подавая HIGH или LOW на вход 3 и вход 4.
Например, для мотора A логика следующая:
Направление |
Вход 1 |
Вход 2 |
Разрешение 1 |
|---|---|---|---|
Вперед |
0 |
1 |
1 |
Назад |
1 |
0 |
1 |
Стоп |
0 |
0 |
0 |
Управление двумя DC моторами – идеально для сборки робота
Если вы хотите собрать робота-машинку с использованием 2 DC моторов, они должны вращаться в определенных направлениях, чтобы робот ехал влево, вправо, вперед или назад.
Например, если вы хотите, чтобы робот двигался вперед, оба мотора должны вращаться вперед. Чтобы он ехал назад, оба мотора должны вращаться назад.
Чтобы повернуть робота в одном направлении, нужно, чтобы противоположный мотор вращался быстрее. Например, чтобы робот повернул направо, включите мотор слева и выключите мотор справа. В следующей таблице показаны комбинации состояний входных контактов для направлений робота.
Направление |
Вход 1 |
Вход 2 |
Вход 3 |
Вход 4 |
|---|---|---|---|---|
Вперед |
0 |
1 |
0 |
1 |
Назад |
1 |
0 |
1 |
0 |
Направо |
0 |
1 |
0 |
0 |
Налево |
0 |
0 |
0 |
1 |
Стоп |
0 |
0 |
0 |
0 |
Подключение DC мотора к Raspberry Pi Pico
Для выполнения этого руководства вам нужно подключить один DC мотор к Raspberry Pi Pico через драйвер L298N. Рекомендуется питать мотор от независимого источника питания. Здесь мы будем использовать 4 батарейки AA по 1.5 В, которые в сумме дают приблизительно 6 В. Вы можете использовать любой подходящий источник питания, не превышающий 12 В.
Подключение драйвера L298N к Raspberry Pi Pico
В следующей таблице показаны подключения, которые мы сделаем между Raspberry Pi Pico и драйвером L298N.
Драйвер L298N |
Input 1 |
Input 2 |
Input 3 |
GND |
|---|---|---|---|---|
Raspberry Pi Pico |
GPIO 3 |
GPIO 4 |
GPIO 2 |
GND |
Вы можете использовать любые другие цифровые контакты. Узнайте больше о GPIO Raspberry Pi Pico в нашем руководстве: Распиновка Raspberry Pi Pico и Pico W: описание GPIO.
Используйте следующую схему в качестве справочника для подключения DC мотора и драйвера L298N к Raspberry Pi Pico.
Примечание: мы рекомендуем припаять керамический конденсатор 0.1 мкФ к положительной и отрицательной клеммам каждого мотора, как показано на рисунке ниже, чтобы сгладить возможные скачки напряжения.
Кроме того, вы можете припаять ползунковый переключатель к красному проводу, идущему от батарейного отсека. Таким образом, вы сможете включать и выключать питание, поступающее к моторам и драйверу.
Raspberry Pi Pico следует питать от другого источника питания (для целей тестирования используйте USB-порт вашего компьютера).
Создание модуля MicroPython для управления DC мотором
Написание кода для управления DC мотором не является сложным, но требует некоторых повторяющихся команд. Мы создадим простой Python-модуль с базовыми командами для инициализации мотора и управления его скоростью и направлением.
Создание модуля dcmotor
Прежде чем писать код для этого модуля, важно описать его функциональность:
Библиотека будет называться dcmotor.py, и она будет содержать единственный класс DCMotor с несколькими методами.
Мы должны иметь возможность инициализировать мотор, используя вход 1, вход 2 и контакт разрешения (enable) следующим образом:
motor1 = DCMotor(Pin1, Pin2, enable)
Pin1 и Pin2 должны быть инициализированы как выходные контакты, а enable должен быть инициализирован как контакт ШИМ (PWM).
Чтобы двигатель вращался вперед, мы хотим использовать метод forward() объекта DCMotor, который принимает скорость в качестве параметра. Например:
motor1.forward(speed)
Скорость должна быть целым числом от 0 до 100, где 0 соответствует остановленному мотору, а 100 – максимальной скорости.
Аналогично, чтобы мотор вращался назад, мы хотим метод backwards():
motor1.backwards(speed)
Также удобно иметь команду для остановки мотора:
motor1.stop()
Импорт модуля dcmotor.py
Создайте новый файл с именем dcmotor.py и скопируйте в него следующий код.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-dc-motor-micropython/
class DCMotor:
def __init__(self, pin1, pin2, enable_pin, min_duty=15000, max_duty=65535):
self.pin1 = pin1
self.pin2 = pin2
self.enable_pin = enable_pin
self.min_duty = min_duty
self.max_duty = max_duty
def forward(self, speed):
self.speed = speed
self.enable_pin.duty_u16(self.duty_cycle(self.speed))
self.pin1.value(1)
self.pin2.value(0)
def backwards(self, speed):
self.speed = speed
self.enable_pin.duty_u16(self.duty_cycle(self.speed))
self.pin1.value(0)
self.pin2.value(1)
def stop(self):
self.enable_pin.duty_u16(0)
self.pin1.value(0)
self.pin2.value(0)
def duty_cycle(self, speed):
if speed <= 0 or speed > 100:
duty_cycle = 0
else:
duty_cycle = int(self.min_duty + (self.max_duty - self.min_duty) * (speed / 100))
return duty_cycle
Загрузите этот файл на вашу плату Raspberry Pi Pico с именем: dcmotor.py.
Если вы используете Thonny IDE, выполните следующие шаги:
1) Скопируйте предоставленный код в новый файл в Thonny IDE.
2) Загрузите код на плату. Если вы используете Thonny IDE, перейдите в File > Save as… и затем выберите Raspberry Pi Pico.
3) Сохраните файл как dcmotor.py.
4) Наконец, нажмите OK для продолжения. Модуль dcmotor.py должен быть успешно загружен на вашу плату.
Как работает модуль dcmotor
Модуль dcmotor содержит единственный класс DCMotor.
class DCMotor:
Мы используем метод-конструктор (__init__) для инициализации данных сразу после создания объекта класса DCMotor.
def __init__(self, pin1, pin2, enable_pin, min_duty=15000, max_duty=65535):
self.pin1 = pin1
self.pin2= pin2
self.enable_pin = enable_pin
self.min_duty = min_duty
self.max_duty = max_duty
Объект DCMotor принимает следующие параметры:
pin1: GPIO (выход), подключенный к контакту input 1 драйвера L298N.
pin2: GPIO (выход), подключенный к контакту input 2 драйвера L298N.
enable_pin: GPIO (контакт ШИМ), подключенный к контакту enable 1 драйвера L298N.
min_duty: минимальный коэффициент заполнения для запуска мотора. Этот параметр необязательный, и по умолчанию он равен 15000. Вам может потребоваться изменить этот параметр в зависимости от выбранной частоты управления DC мотором.
max_duty: максимальный коэффициент заполнения для работы мотора. По умолчанию этот параметр равен 65535.
Затем мы создаем несколько методов для управления DC мотором: forward(), backwards() и stop(). Методы forward() и backwards() заставляют мотор вращаться вперед и назад соответственно. Метод stop() останавливает мотор. Методы forward() и backwards() принимают скорость в качестве параметра. Скорость должна быть целым числом от 0 до 100.
Давайте подробнее рассмотрим метод forward():
def forward(self, speed):
self.speed = speed
self.enable_pin.duty_u16(self.duty_cycle(self.speed))
self.pin1.value(1)
self.pin2.value(0)
Чтобы мотор двигался вперед, pin1 устанавливается в 1, а pin2 – в 0. Коэффициент заполнения контакта разрешения устанавливается в соответствии с указанной скоростью. Скорость – это целое число от 0 до 100, но коэффициент заполнения должен быть числом между max_duty и min_duty. Поэтому у нас есть еще один метод в конце кода, называемый duty_cycle(), который вычисляет соответствующее значение коэффициента заполнения на основе скорости.
def duty_cycle(self, speed):
if self.speed <= 0 or self.speed > 100:
duty_cycle = 0
else:
duty_cycle = int (self.min_duty + (self.max_duty - self.min_duty)*((self.speed - 1)/(100-1)))
return duty_cycle
Метод backwards() работает аналогично, но pin1 устанавливается в 0, а pin2 – в 1.
def backwards(self, speed):
self.speed = speed
self.enable_pin.duty_u16(self.duty_cycle(self.speed))
self.pin1.value(0)
self.pin2.value(1)
Метод stop() устанавливает коэффициент заполнения, pin1 и pin2 в 0.
def stop(self):
self.enable_pin.duty_u16(0)
self.pin1.value(0)
self.pin2.value(0)
Управление DC мотором с Raspberry Pi Pico – код MicroPython
Теперь, когда мы понимаем, как работает модуль dcmotor, мы можем создать новый скрипт для управления DC мотором с использованием функциональности библиотеки.
Следующий код демонстрирует, как использовать функциональность библиотеки для управления DC мотором.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-dc-motor-micropython/
from dcmotor import DCMotor
from machine import Pin, PWM
from time import sleep
frequency = 1000
pin1 = Pin(3, Pin.OUT)
pin2 = Pin(4, Pin.OUT)
enable = PWM(Pin(2), frequency)
dc_motor = DCMotor(pin1, pin2, enable)
# Set min duty cycle (15000) and max duty cycle (65535)
#dc_motor = DCMotor(pin1, pin2, enable, 15000, 65535)
try:
print('Forward with speed: 50%')
dc_motor.forward(50)
sleep(5)
dc_motor.stop()
sleep(5)
print('Backwards with speed: 100%')
dc_motor.backwards(100)
sleep(5)
print('Forward with speed: 5%')
dc_motor.forward(5)
sleep(5)
dc_motor.stop()
except KeyboardInterrupt:
print('Keyboard Interrupt')
dc_motor.stop()
Импорт библиотек
Чтобы использовать функциональность библиотеки, необходимо импортировать её в свой код. Мы импортируем класс DCMotor из библиотеки dcmotor, которую создали ранее.
from dcmotor import DCMotor
Вам также нужно импортировать классы Pin и PWM для управления GPIO, а также метод sleep().
from machine import Pin, PWM
from time import sleep
Установка частоты
Установите частоту ШИМ-сигнала на 1000 Гц. Вы можете выбрать другие значения частоты. Обратите внимание, что при более низких значениях частоты вам может потребоваться скорректировать параметр минимального коэффициента заполнения (min_duty).
frequency = 1000
Инициализация GPIO
Мы создаем три переменные, которые относятся к контактам pin1, pin2 и enable драйвера. Контакты pin1 и pin2 являются выходными контактами, а enable – контактом ШИМ.
pin1 = Pin(3, Pin.OUT)
pin2 = Pin(4, Pin.OUT)
enable = PWM(Pin(2), frequency)
Затем инициализируем объект DCMotor с определенными ранее pin1, pin2 и enable:
dc_motor = DCMotor(pin1, pin2, enable)
Примечание: вам может потребоваться передать параметры min_duty и max_duty в зависимости от используемого мотора и платы. Например:
dc_motor = DCMotor(pin1, pin2, enable, 15000, 65535)
Теперь у вас есть объект DCMotor под названием dc_motor. Вы можете использовать методы для управления мотором. Запуск мотора вперед на скорости 50%:
dc_motor.forward(50)
Остановка мотора:
dc_motor.stop()
Вращение мотора назад на максимальной скорости:
dc_motor.backwards(100)
Вращение мотора вперед на скорости 5%:
dc_motor.forward(5)
Тестирование кода
Запустите предыдущий код на вашем Raspberry Pi Pico. Если вы используете Thonny IDE, просто нажмите зеленую кнопку запуска.
Если вы хотите загрузить этот код на плату и запускать его при включении, вам нужно сохранить его как main.py. Перейдите в File > Save as… > Raspberry Pi Pico. Сохраните файл с именем main.py.
Мотор будет вращаться в разных направлениях и с разной скоростью.
Вы можете экспериментировать с методами и передавать различные скорости в качестве аргумента, чтобы увидеть, как ведет себя ваш DC мотор. Теперь вы можете использовать эту библиотеку в своих проектах для создания объектов DCMotor и применения методов библиотеки для управления мотором: forward(), backwards() и stop().
Заключение
В этом руководстве вы узнали, как управлять DC мотором с помощью драйвера L298N и Raspberry Pi Pico, запрограммированного на MicroPython. После понимания того, как работает драйвер L298N, управление DC мотором сводится к управлению цифровыми выходами для задания направления вращения моторов и генерации ШИМ-сигналов для управления их скоростью.
Мы надеемся, что это руководство было для вас полезным. У нас есть аналогичные руководства для других микроконтроллерных плат: