Программирование, радиоэлектроника,
саморазвитие и частичка из моей жизни здесь...

Управляем шаговыми движками и DC моторами, L298 и Raspberry Pi

Рассмотрим драйвер электродвигателей на транзисторах и микросхеме L298, разберемся с принципом работы H-моста. Узнаем особенности подключения драйверов на L298 к разным двигателям и источникам питания, проведем простые эксперименты с шаговыми движками и двигателями постоянного напряжения. Подключение к Raspberry Pi и простейшие программы для теста управления драйвером.

Содержание:

  1. Что такое H-мост
  2. Схема простого H-моста на кремниевых транзисторах
  3. Микросхема L298, характеристики и возможности
  4. Схема драйвера на микросхеме L298
  5. Готовые модули на L298
  6. L298 + DC двигатели + Raspberry Pi
  7. Что такое шаговый двигатель, типы шаговиков
  8. L298 + шаговый двигатель + Raspberry Pi
  9. Заключение

Что такое H-мост

При проектировании станков, роботов и других автоматизированных устройств возникает необходимость управлять электродвигателем постоянного тока или же катушками шагового движка. Для того, чтобы иметь возможность управлять обмоткой двигателя и заставить его вал вращаться в разные стороны, необходимо выполнять коммутацию с переполюсовкой. Для подобной цели используется так называемый "H-мост".

Почему такое название? - потому что схема включения двигателя и переключателей для коммутации напоминает латинскую букву H. Принципы работы H-моста показан нарисунке ниже.

Как работает H-мост

Рис. 1. Как работает H-мост, принцип коммутации двигателя для вращения в разные стороны.

Как видим, при помощи 4х переключателей мы можем подключать мотор к источнику питания в разной полярности, что в свою очередь заставит вращаться его вал в разные стороны. Переключатели можно заменить на реле, или же на мощные электронные ключи на транзисторах.

Важно заметить что НЕЛЬЗЯ допускать замыкания двух ключей на одной стороне H-моста, поскольку получится короткое замыкание, при проектировании схемы моста нужно заложить это правило в логику и таким образом реализовать защиту.

Схема простого H-моста на кремниевых транзисторах

Собрать простой драйвер двигателя постоянного тока (или для обмотки шагового двигателя) можно на распространенных кремниевых транзисторах.

Принципиальная схема простого драйвера для электродвигателя

Рис. 2. Принципиальная схема простого драйвера электродвигателя на кремниевых транзисторах.

Такой драйвер позволяет управлять электродвигателем постоянного тока с питающим напряжением до 25В (для КТ817А, КТ816А) и до 45В (для КТ817Б-Г, КТ816Б-Г) с током не более 3А. При большом рабочем и нагрузочном токе двигателя выходные транзисторы КТ817 и КТ816 должны быть установлены на радиаторы достаточного размера.

Установка диодов VD1-VD2 обязательна, они нужны для защиты выходных транзисторов от обратного тока. На их место можно поставить отечественные КД105А или другие на больший ток.

Собрав две такие схемки (2х6 транзисторов) можно также управлять шаговым двигателем или же двумя двигателями постоянного тока.

Для того чтобы не городить огород из 12 транзисторов можно применить специализированные микросхемы, ниже мы рассмотрим пример с микросхемой L298 и готовым блоком на ее основе.

Микросхема L298, характеристики и возможности

Интегральная микросхема L298 - это мощный универсальный мостовой драйвер для управления двигателями постоянного тока, шаговыми движками, электромагнитными реле и электромагнитами (соленоидами). В микросхеме содержится два H-моста, выполненных на мощных транзисторах, а также логика совместимая с TTL.

Микросхема L298 в корпусах Multiwatt15 PowerSO20

Рис. 3. Микросхема L298 в корпусах Multiwatt15 PowerSO20.

Основные технические характеристики:

  • Рабочее напряжение - до 46В;
  • Максимальный постоянный ток - 4А (с радиатором);
  • Низкое напряжение насыщения;
  • Защита от перегрева;
  • Логический "0" = напряжение до 1,5В.

Где можно применить драйвер на микросхеме L298? - несколько идей:

  • Управление шаговым двигателем;
  • Управление двумя двигателями постоянного тока (DC motors);
  • Коммутация катушек мощных реле;
  • Управление соленоидами (электромагнитами).

Если посмотреть на структурную схему микросхему L298 то мы можем увидеть что-то на подобии схемы на рисунке 2, только с дополнительными логическими элементами.

Внутренняя схема микросхемы L298N

Рис. 4. Внутренняя схема микросхемы L298N - мощный двойной H-мост.

Для каждого H-моста мы имеем по 3 входа: In1 - для подачи напряжения в одном направлении, In2 - в противоположном, и еще один вход En для подачи питания на выходные транзисторы моста.

Таким образом мы можем установить направление прохождения тока и управлять его подачей (включено или выключено, а также ШИМ).

Схема драйвера на микросхеме L298

Ниже представлена простая схема для драйвера двигателей на микросхеме L298N. Управление осуществляется по четырем проводам (вместо шести у L298) благодаря использованию дополнительных инверторов в микросхеме CD4011.

Принципиальная схема драйвера электродвигателей на микросхеме L298N

Рис. 5. Принципиальная схема драйвера электродвигателей на микросхеме L298N.

Для питания логики обеих микросхем нужно стабилизированное напряжение +5В (P2), можно использовать интегральный стабилизатор, например L7805 или же питать логику от имеющейся линии питания +5В. Для подачи питающего напряжения на двигатели используется отдельная линия питания P1.

Выводы P4, P5 используются для установки полярности каждого из каналов, а выводы P6, P7 - разрешают подачу питания на  каскады (ключи) внутреннего H-моста для каждого канала.

Микросхему CD4011 можно заменить на отечественную К176ЛА7. Диоды Шоттки можно поставить другого номинала, на 35В/4А и более. Если не планируется ограничивать ток обмоток двигателя(двигателей) то низкоомные ограничивающие резисторы R9-R10 можно исключить из схемы, заменив их на перемычки.

Готовые модули на L298

В интернете можно заказать готовый модуль на L298, правда в нем будет 6 входов для управления.

Готовые модули на L298

Рис. 6. Готовые модули на L298.

Я для своих нужд приобрел готовый модуль по типу как на рисунке слева. В нем присутствует микросхема L298 и небольшой стабилизатор для подачи +5В на логику микросхемы.

Для подключения данной платки важно четко уяснить одну особенность:

  • Если для питания двигателей используется напряжение более чем 12В то перемычку нужно убрать и подавать отдельно 5В на выделенный для этого коннектор
  • Если питание двигателей будет осуществляться от напряжения 5-12В то перемычку нужно утсановить и дополнительное питание 5В не понадобится.

Если же подать на двигатели, например 20В и оставить перемычку установленной, то на модуле выгорит микросхемка-стабилизатор на 5В. Почему разработчики не установили интегральный стабилизатор с более широким диапазоном входных напряжений - не понятно.

Для того чтобы сэкономить два входа при подключении такого блока к Arduino или Raspberry Pi можно добавить часть схемы на CD4001, как на рисунке 5.

L298 + DC двигатели + Raspberry Pi

Для данного эксперимента к модулю на L298 были подключены два двигателя постоянного тока. Питание всего модуля осуществляется от одного аккумулятора на 6В. Поскольку это напряжение меньше 12В (смотрим выше описание) то перемычку внутреннего стабилизатора оставляем установленной и дополнительное питание +5В для логики не потребуется.

Перемычки "ENA" и "ENB", которые разрешают подачу питания на выходные мосты, оставлены установленными. Таким образом, для управления каждым из двигателей используем оставшиеся четыре входа: IN1, IN2, IN3, IN4.

После подключения питания на модуле загорится светодиод, теперь можем подать на каждый из входов поочередно +5В и посмотреть как будут вращаться наши движки.

Где взять +5В? - в данном случае это напряжение присутствует на разъеме питания, справа возле GND. Для теста можно воспользоваться кусочком проволоки - перемычкой.

Теперь подключим наш модуль к Raspberry Pi и напишем простую тестовую программу на Python. Для подключения модуля я использовал выводы GPIO вот в таком соответствии:

Raspberry Pi GPIO Модуль L298
Вывод 7 (GPIO4) IN1
Вывод 9 (GND) GND (разъем питания)
Вывод 11 (GPIO17) IN2
Вывод 13 (GPIO27) IN3
Вывод 15 (GPIO22) IN4

L298 + Raspberry Pi + электродвигатели постоянного тока

Рис. 7. L298 + Raspberry Pi + электродвигатели постоянного тока.

Мини-компьютер у меня питается через понижающий импульсный стабилизатор от второго аккумулятора на 6В. Перейдем к написанию программы для нашего эксперимента, наша цель - управлять вращением вала каждого из двигателей при помощи клавиатуры, которая подключена к Raspberry Pi или же удаленно по SSH, VNC.

Теперь испробуем простую программу, написанную на Python, которая поможет понять принцип управления электродвигателем постоянного тока.

Загружаем малинку, открываем Терминал или же подключаемся к ней удаленно при помощи SSH. Создаем новый файл и открываем его для редактирования при помощи команды:

nano /home/pi/l298_dc_motors_test.py

Вставляем в редактор код скрипта на Python, который приведен ниже:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import RPi.GPIO as GPIO

# Подготавливаем пины GPIO.
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)

GPIO.setup(4, GPIO.OUT)
GPIO.output(4, GPIO.LOW)

GPIO.setup(17, GPIO.OUT)
GPIO.output(17, GPIO.LOW)

# Включаем вращение двигателя 1 в одну сторону.
GPIO.output(4, GPIO.HIGH)

# ждем 5 секунд.
time.sleep(5)

# Выключаем двигатель 1.
GPIO.output(4, GPIO.LOW)

# ждем 10 секунд.
time.sleep(10)

# Включаем вращение двигателя 1 в другую сторону.
GPIO.output(17, GPIO.HIGH)

# ждем 5 секунд.
time.sleep(5)

# Выключаем двигатель 1.
GPIO.output(17, GPIO.LOW)

Выходим из редактора и сохраняем файл. Делаем скрипт исполняемым и запускаем его:

chmod +x /home/pi/l298_dc_motors_test.py
/home/pi/l298_dc_motors_test.py

После запуска скрипта один из двигателей начнет вращаться в одну сторону на протяжении пяти секунд, потом он выключится и через 10 секунд начнет вращаться в другую сторону на протяжении 5-ти секунд.

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

Важно чтобы в данном примере кода соблюдались отступы, об этом я уже писал раньше вот тут.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import curses
import time
import RPi.GPIO as GPIO

# Установим номера пинов GPIO, с которыми будем работать
M1_RIGHT = 4
M1_LEFT = 17
M2_RIGHT = 27
M2_LEFT = 22

# Функция для подготовки пинов GPIO
def setup(*ports):
    GPIO.cleanup()
    # Режим именования пинов по названию, а не по номеру на плате 
    GPIO.setmode(GPIO.BCM)
    for port in ports:
        # Установка пина на вывод + низкий уровень "0"
        GPIO.setup(port, GPIO.OUT)
        GPIO.output(port, GPIO.LOW)

# Функция для установки низкого уровня на всех пинах (выключение)
def stop_all():
    GPIO.output(M1_LEFT, GPIO.LOW)
    GPIO.output(M1_RIGHT, GPIO.LOW)
    GPIO.output(M2_LEFT, GPIO.LOW)
    GPIO.output(M2_RIGHT, GPIO.LOW)

# Функция для управления вращением движков
def rotate(motor=1, mode='s'):
    # Выключаем все пины
    stop_all()
    # Для мотора 1
    if motor == 1:
        if mode == 'r':
	    # Устанавливаем высокий уровень на пине M1_RIGHT (4)
            GPIO.output(M1_RIGHT, GPIO.HIGH)
        elif mode == 'l':
	    # Устанавливаем высокий уровень на пине M1_LEFT (17)
            GPIO.output(M1_LEFT, GPIO.HIGH)
    # Для мотора 2
    elif motor == 2:
        if mode == 'r':
            GPIO.output(M2_RIGHT, GPIO.HIGH)
        elif mode == 'l':
            GPIO.output(M2_LEFT, GPIO.HIGH)

# Выполним инициализацию пинов GPIO
setup(M1_RIGHT, M1_LEFT, M2_RIGHT, M2_LEFT)

# Инициализация экрана (модуль curses)
stdscr = curses.initscr()
# Реагировать на нажатие клавиш без подтверждения при помощи ENTER
curses.cbreak()
# Разрешить использование стрелочек на клавиатуре
stdscr.keypad(1)
# Не блокировать программу по времени при опросе событий
stdscr.nodelay(1)

# Отобразим на экране данные по умолчанию
stdscr.addstr(0, 10, "Hit 'q' to quit")
stdscr.addstr(2, 10, "A - M1 Left, D - M1 Right")
stdscr.addstr(3, 10, "< - M2 Left, > - M2 Right")
stdscr.addstr(4, 10, "S - stop")
stdscr.refresh()

# Главный цикл
while True:
    # Получаем код нажатия клавиши и проверяем его
    key = stdscr.getch()
    if key != -1:
        # Если клавиша "стрелка влево" то вращаем движок 2 влево
        if key == curses.KEY_LEFT:
	    # Выводим на экран строку "M2 <---" в позиции 6, 10
            stdscr.addstr(6, 10, "M2 <---")
            rotate(2, 'l')
        # Если клавиша "стрелка вправо" то вращаем движок 2 вправо
        elif key == curses.KEY_RIGHT:
            stdscr.addstr(6, 10, "M2 --->")
            rotate(2, 'r')
        # Если клавиша "а" то вращаем движок 1 влево
        elif key == ord('a'):
            stdscr.addstr(6, 10, "M1 <---")
            rotate(1, 'l')
        # Если клавиша "d" то вращаем движок 1 вправо
        elif key == ord('d'):
            stdscr.addstr(6, 10, "M1 --->")
            rotate(1, 'r')
        # Если клавиша "s" то останов всех движков
        elif key == ord('s'):
            stdscr.addstr(6, 10, "STOP 12")
            stop_all()
        # Если клавиша "s" то выходим из программы
        elif key == ord('q'):
	    # Восстановление прежних настроек терминала
            stdscr.keypad(0)
            curses.echo()
            curses.endwin()
            # Очистка и выход
            os.system('clear')
            sys.exit()
        # Обновляем текст на экране и делаем небольшую задержку
        stdscr.refresh()
        time.sleep(0.01)

Запустив скрипт можно понажимать стрелочки клавиатуры "влево" и "вправо", а также клавиши с буквами "A" и "D" - двигатели должны вращаться поочередно и в разные стороны, а программа будет отображать их текущий режим работы.

Программа на Python под Raspberry Pi для управления двигателями при помощи драйвера L298

Рис. 8. Программа на Python для управления двигателями при помощи драйвера L298 (терминал Konsole, KDE).

Краткая видео-демонстрация работы данного эксперимента приведена ниже:

Хочу заметить, что управлять скоростью вращения вала электродвигателя постоянного тока можно с использованием широтно-импульсной модуляции (ШИМ, PWM), как использовать этот метод для GPIO вы можете узнать из подробной статьи, посвященной модулю "RPi.GPIO".

Что такое шаговый двигатель, типы шаговиков

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

Шаговые двигатели надежны, стойки к износу и позволяют контролировать вращение на определенный угол, применяются в автоматизации процессов, на производстве, в электронно-вычислительной аппаратуре(CD-DVD приводы, принтеры, копиры) и т.п.

Такие двигатели бывают следующих видов:

  • Биполярный - 2 обмотки, по одной на каждую фазу, для управления можно использовать схему на 2 H-моста или один полу-мост с двуполярным питанием;
  • Униполярный  - 2 обмотки, каждая с отводом от середины, удобно переключать фазы сменой половинок каждой из обмоток, упрощает схему драйвера (4 ключа), а также использовать как быполярный без использования отводов от обмоток;
  • С четирьмя обмотками - универсальный, подключив обмотки соответствующим образом можно использовать как быполярный или униполярный движок.

Типы шаговых двигателей

Рис. 9. Типы шаговых двигателей: биполярный, униполярный, с четырьмя обмотками.

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

L298 + шаговый двигатель + Raspberry Pi

Теперь давайте подключим шаговый двигатель, в моем случае применен биполярный мощный шаговый двигатель, извлеченный из старого матричного принтера.

Для подключения одного биполярного двигателя потребуется два выхода драйвера на L298 (два H-моста). Для данного эксперимента модуль L298 нужно подключить к Raspberry Pi так же, как и в варианте с DC-двигателями.

Прежде можете поэкспериментировать без малинки - подавать поочередно на входы модуля L298 напряжение 5В и посмотреть как вал двигателя будет выполнять шаги.

По сути дела, при помощи малинки, мы будем поочередно и с некоторой задержкой подавать импульсы на обмотки движка, чем заставим его вал вращаться в нужную нам сторону и с нужной скоростью.

Подключение биполярного шагового двигателя к L298, Raspberry Pi

Рис. 10. Подключение биполярного шагового двигателя к модулю L298 для управления через Raspberry Pi.

Если все уже подключено, то переходим к экспериментам с простой тестовой программой на Python, которая поможет понять как работать с шаговыми двигателем используя L298 + Raspberry Pi.

Создадим файл для скрипта и откроем его для редактирования:

nano /home/pi/l298_stepper_motor_test.py

Вставляем в редактор следующий код скрипта на Python:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import RPi.GPIO as GPIO

# Подготавливаем пины GPIO.
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)

GPIO.setup(4, GPIO.OUT)
GPIO.output(4, GPIO.LOW)

GPIO.setup(17, GPIO.OUT)
GPIO.output(17, GPIO.LOW)

GPIO.setup(27, GPIO.OUT)
GPIO.output(27, GPIO.LOW)

GPIO.setup(22, GPIO.OUT)
GPIO.output(22, GPIO.LOW)

# Временная задержка между шагами, сек.
step_timeout = 0.0105
# Длительность импульса, сек.
impulse_timeout = 0.008

# Шаг 1.
GPIO.output(4, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(4, GPIO.LOW)
time.sleep(step_timeout)

# Шаг 2.
GPIO.output(17, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(17, GPIO.LOW)
time.sleep(step_timeout)

# Шаг 3.
GPIO.output(27, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(27, GPIO.LOW)
time.sleep(step_timeout)

# Шаг 4.
GPIO.output(22, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(22, GPIO.LOW)
time.sleep(step_timeout)

# Ждем 10 секунд.
time.sleep(10)

# 20 раз по 4 шага в цикле.
for i in range(0,20):
    GPIO.output(4, GPIO.HIGH)
    time.sleep(impulse_timeout)
    GPIO.output(4, GPIO.LOW)
    time.sleep(step_timeout)

    GPIO.output(17, GPIO.HIGH)
    time.sleep(impulse_timeout)
    GPIO.output(17, GPIO.LOW)
    time.sleep(step_timeout)

    GPIO.output(27, GPIO.HIGH)
    time.sleep(impulse_timeout)
    GPIO.output(27, GPIO.LOW)
    time.sleep(step_timeout)

    GPIO.output(22, GPIO.HIGH)
    time.sleep(impulse_timeout)
    GPIO.output(22, GPIO.LOW)
    time.sleep(step_timeout)

Делаем файл со скриптом исполняемым и запускаем его на исполнение:

chmod +x /home/pi/l298_stepper_motor_test.py
/home/pi/l298_stepper_motor_test.py

осле запуска скрипта, шаговый двигатель должен совершить 4 шага (вращение в одну сторону), потом подождав 10 секунд он снова начнет свое вращение и сделает уже 20*4 шагов.

А теперь рассмотрим пример интерактивной программы, которая позволяет управлять направлением и скоростью вращения (последовательные шаги) шагового двигателя с использованием клавиатуры.

Вы можете сохранить ниже приведенный скрипт в отдельный файл и сделав его исполняемым запустить, или же заменить исходный код программы в уже созданном скрипте из предыдущего примера.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import curses
import time
import RPi.GPIO as GPIO

# Функция для подготовки пинов GPIO
def setup(*ports):
    GPIO.cleanup()
    # Режим именования пинов по названию, а не по номеру на плате
    GPIO.setmode(GPIO.BCM)
    for port in ports:
        # Установка пина на вывод + низкий уровень "0"
        GPIO.setup(port, GPIO.OUT)
        GPIO.output(port, GPIO.LOW)

# Функция для подачи импульса на пин с некоторой задержкой (1 шаг)
def impulse(port=0):
    GPIO.output(port, GPIO.HIGH)
    # Set the timeout value to be anough for one step
    time.sleep(0.008)
    GPIO.output(port, GPIO.LOW)
    time.sleep(timeout)

# Выполняем установку нужных нам пинов GPIO
setup(4, 17, 27, 22)

# Задержка между шагами (по умолчанию)
timeout = 0.0105
# Направление вращения (по умолчанию)
direction = 'r'

# Инициализация экрана (модуль curses)
stdscr = curses.initscr()
# Реагировать на нажатие клавиш без подтверждения при помощи ENTER
curses.cbreak()
# Разрешить использование стрелочек на клавиатуре
stdscr.keypad(1)
# Не блокировать программу по времени при опросе событий
stdscr.nodelay(1)

# Отобразим на экране данные по умолчанию
stdscr.addstr(0, 10, "Hit 'q' to quit")
stdscr.addstr(2, 10, "--->")
stdscr.addstr(3, 10, "Timeout: " + str(timeout))
stdscr.refresh()

# Главный цикл
while True:
    # Набор импульсов для вращения вала мотора вправо
    if direction == 'r':
        impulse(4)
        impulse(17)
        impulse(27)
        impulse(22)
    # Набор импульсов для вращения вала мотора влево
    elif direction == 'l':
        impulse(22)
        impulse(27)
        impulse(17)
        impulse(4)
    # Считываем код нажатия клавиши и проверяем его
    key = stdscr.getch()
    if key != -1:
        # Клавиша "влево" меняет направление вращения: ВЛЕВО
       if key == curses.KEY_LEFT:
	    # отображаем текст "<---" в позиции экрана 2, 10
            stdscr.addstr(2, 10, "<---")
            # Изменим значение переменной с направлением вращения
            direction = 'l'
        # Клавиша "вправо" меняет направление вращения: ВПРАВО
        elif key == curses.KEY_RIGHT:
            stdscr.addstr(2, 10, "--->")
            direction = 'r'
        # Клавиша "вверх" ускоряет вращение
        elif key == curses.KEY_UP:
	    # Уменьшаем задержку между шагами
            timeout = timeout - 0.0005
        # Клавиша "вниз" замедляет вращение
        elif key == curses.KEY_DOWN:
	    # Увеличиваем задержку между шагами
            timeout = timeout + 0.0005
        # Клавиша "q" выполняет выход из программы
        elif key == ord('q'):
            stdscr.keypad(0)
            curses.echo()
            curses.endwin()
            os.system('clear')
            sys.exit()
        # Смотрим чтобы время задержки не перешло границу 0 
        if timeout <= 0:
            timeout = 0.0005
        # Обновляем текст на экране
        stdscr.addstr(3, 10, "Timeout: " + str(timeout))
        stdscr.refresh()
        time.sleep(0.01)

Теперь клацаем клавиши стрелок влево и вправо и смотрим как будет изменяться направление вращения вала двигателя, а при нажатии клавиш вверх и вниз скорость будет увеличиваться и уменьшаться соответственно.

Если же двигатель не вращается, то возможно что потребуется сменить полярность подключения одной из обмоток к модулю на L298.

Программа управления биполярным шаговым двигателем, L298, Raspberry Pi

Рис. 11. Программа управления биполярным шаговым двигателем, L298, Raspberry Pi.

Видео-демонстрация работы шагового двигателя:

Заключение

Надеюсь вы получили ответ на вопрос "что такое H-мост и как он работает", из экспериментов должно быть понятно как применять драйвер на микросхеме L298 и подключать к нему разные движки.

Важно заметить что в интернете можно найти готовые библиотеки и скрипты на Python для удобного управления двигателями при помощи H-моста на L298 с использованием Raspberry Pi.

Литература:

1 1773 Железо
Комментарии к публикации (14):
Александр #1Александр
14 Март 2017 22:13

Здравствуйте, спасибо за статью, на англоязычных форумах пишут что GND не нужно подключать к малинке, у вас в схеме подключено, в чем сокральный смысл подключения земли?

0
ph0en1x #2ph0en1x
14 Март 2017 22:42

В моем эксперименте малинка запитана от одного аккумулятора через DC-DC преобразователь, а модуль на L298 питается от другого аккумулятора.
"Земля" малинки и модуля L298 должны быть соединены, иначе при подаче с GPIO пина малинки высокого уровня модуль на L298 его просто не "почувствует". Чтобы не соединять минусы батарей (по сути землю малинки и модуля) отдельным проводом я просто подсоединил вывод GPIO 9 (GND) к клеме GND на модуле, вот и весь сакральный смысл.

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

0
Сергей #3Сергей
24 Июль 2017 16:16

Уважаемый автор, подскажите пожалуйста про первую программу "l298_dc_motors_test.py" в ней у меня получилось управлять двигателями поочередно, а у меня нужно чтобы они могли работать и совместно. Как это реализовать в программе?

0
ph0en1x #4ph0en1x
25 Июль 2017 11:54

Сергей, здесь можно поступить вот так:
При нажатии клавиши "f" оба движка будут вращаться в одну сторону, а при нажатии "g" - в другую.
В главный цикл демонстрационной программы нужно всего лишь добавить два блока с проверкой состояния указанных клавиш и вызовом процедур для включения двух движков совместно.

        # Если клавиша "g" то вращаем оба движка вправо
        elif key == ord('g'):
            stdscr.addstr(6, 10, "MM --->") 
            rotate(1, 'r') # вращаем движок 1 вправо
            rotate(2, 'r') # вращаем движок 2 вправо
        # Если клавиша "f" то вращаем оба движка влево
        elif key == ord('f'):
            stdscr.addstr(6, 10, "MM <---")
            rotate(1, 'l')
            rotate(2, 'l')

Также при нажатии данных клавиш на экране будет отображено направление вращения и указано что вращаются оба движка - "MM --->" (здесь можно написать что угодно).

+1
Сергей #5Сергей
26 Июль 2017 15:29

Спасибо за ответ и за просмотр коментариев.Good

+1
Dodop #6Dodop
15 Октябрь 2017 11:41

Здравствуйте, сделал все, как у вас, движок подключён правильно, но он не проворачивается, дергается и все. Биполярный ШЭД у меня.

0
ph0en1x #7ph0en1x
15 Октябрь 2017 14:00
но он не проворачивается, дергается и все.

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

Нужно отключить платку драйвера от Raspberry Pi и проводником, подключенным через резистор 1КОм к плюсу питания (+5В), пройтись по входам модуля, наблюдая за шагами вала двигателя.

Когда последовательности подачи импульсов для вращения движка определены, можно исправить номера пинов в следующих блоках кода программы:

    # Набор импульсов для вращения вала мотора вправо
    if direction == 'r':
        impulse(4)
        impulse(17)
        impulse(27)
        impulse(22)
    # Набор импульсов для вращения вала мотора влево
    elif direction == 'l':
        impulse(22)
        impulse(27)
        impulse(17)
        impulse(4)
0
Аноним #8Аноним
19 Ноябрь 2017 19:55

Здравствуйте,спасибо за статью) А если вместо драйвера L298 взять l293d и управлять 2мя биполярными ШД,то как писать программу,и с подключением будет иначе или как?)

0
ph0en1x #9ph0en1x
20 Ноябрь 2017 12:51

Здравствуйте.

Микросхема L293D содержит четыре одинаковых блока, каждый из которых - это половинка H-моста. Она является более слабым и миниатюрным вариантом L298.

Для самостоятельной сборки драйвера на основе L293 можно использовать схему из даташита:

/uploads/Image/comments/l293-driver-electronic-circuit.png

Для активации выходных каскадов каждого H-моста, нужно установить высокий уровень на ножках 1 и 9 (подключены к +5В через резистор 10кОм). Ножки 2, 7, 10, 15 - это входы каждой половинки H-мостов.

На вывод 16 подается напряжение питания логики +5В, а на 8 - напряжение питания для двигателя. Ножки 3,6 и 11,14 - это выходы H-мостов. И напоследок, 4,5,12,13 - земля, минус питания.

Микросхема L293D уже содержит в себе защитные диоды, а L293 потребует дополнительной установки внешних защитных диодов.

Ограничения по выходным токам:

  • L293 - 1A;
  • L293D - 600mA.

Даташит на микросхему L293 - Скачать (275 КБ).

Для экспериментов можно использовать ту же самую программу, что и для L298. Нужно будет лишь изменить в ней порядок подачи импульсов на выходы GPIO (подключены к входам драйвера L293), чтобы вал движка начал вращаться в нужные стороны. Номера выходов в коде программы задаются числовыми значениями, например: "impulse(22)".

0
ph0en1x #10ph0en1x
22 Февраль 2018 16:45

Добавлены примеры простейших скриптов (без использования функций и интерфейса взаимодействия) для экспериментов с коллекторным и шаговым двигателем постоянного тока, который подключен к модулю L298.

+2
Strannik #11Strannik
31 Июль 2018 17:54

Здравствуйте, Автор! Скажите а есть ли варианты плавного запуска двигателя на python скрипте? И если в скрипте много повторяющегося кода, есть ли варианты добавить его куданить один раз, и потом вызывать меньжим куском кода? Что бы не городить портянку одного и того же кода. И еще возможно ли сделать вариант запуска двигателя в режиме микрошага? Или через raspberry это плохая затея? Заметил что при работе двигатель инога непроизвольно выдает "стуки", как будто в какой то позиции иногда резко притормаживается, толи это помехи от малинки толи вращающий момент попадает в пустое пространство...Не бывало ли у вас подобного?я

0
ph0en1x #12ph0en1x
31 Июль 2018 22:24

Здравствуйте!

Если под плавным запуском подразумевается постепенное увеличение скорости вращения вала шагового движка - то подобное реализовано в примере из статьи. Скоростью можно управлять изменяя временные задержки между импульсами. Чтобы сделать постепенное увеличение скорости - после старта можно в цикле и с некоторой скоростью уменьшать время задержки между импульсами.

Если же нужно плавно увеличивать ток на обмотках движка, то здесь все сложнее. На выходах GPIO может быть только логический 0 или 1, соответственно на выходах драйвера, к которым подключены обмотки шагового двигателя, будет или 0В или +12В. Для эмуляции спадания и возрастания напряжения на выходе драйвера L298 можно применить широтно-импульсную модуляцию (в статье по этой ссылке также описаны все текущие возможности модуля RPi.GPIO).

Еще можно собрать небольшую электронную схему, которая будет управлять, например, током через линию питания выходных каскадов драйвера L298, которая в свою очередь будет управляться несколькими пинами GPIO или же через шину I2C.

Если в работе движка нужна точность и стабильность, то для управления L298 здесь пожалуй что лучше собрать небольшой блочек на AVR-микроконтроллере, который в свою очередь будет получать команды с малинки и выполнять раздачу импульсов на драйвер L298 из своей внутренней программы.

Насчет повторяющегося кода - его нужно собирать в функции или классы, а потом уже эти объекты использовать в других участках программы. В статье специально приведены простые примеры программ с повторяющимися блоками чтобы начинающий смог понять как и куда генерируются импульсы. После ознакомления с каким-то базовым курсом по программированию на Python, подобные вопросы сразу же отпадут.

Насчет стуков и притормаживаний. Нужно понимать что Raspbian (GNU/Linux) не является операционной системой реального времени, ресурсы платформы распределяются между большим количеством разных процессов и прерываний для периферийных устройств. Есть вероятность того, что ваша программа на Python конкурирует за ресурсы микропроцессора и иногда не вкладывается в прописанное в ней время выполнения задержки или подачи импульса через GPIO.

Также причиной появления стуков и "пробоин" между шагами может быть слабый источник питания, к которому подключены выходные каскады (+12В...30В) модуля L298. Шаговый двигатель, в зависимости от габаритов и модели, может потреблять несколько Ампер тока при удержании вала в фиксированной позиции, это нужно учитывать.

Ну и программная составляющая - для разных двигателей нужно подбирать разные таймауты между импульсами чтобы добиться хороших результатов. Приведенные в статье программы являются экспериментальными. Попробуйте подбирать значения связки переменных "step_timeout" и "impulse_timeout" для лучшего результата.

0
Strannik #13Strannik
01 Август 2018 07:58

Здравствуйте! Спасибо за ответ.

По поводу повторяющегося кода оно понятно и наглядно приведено в статье, но что если повторяется многострочный код:

for i in range(0,20):
GPIO.output(4, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(4, GPIO.LOW)
time.sleep(step_timeout)

GPIO.output(17, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(17, GPIO.LOW)
time.sleep(step_timeout)

GPIO.output(27, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(27, GPIO.LOW)
time.sleep(step_timeout)

GPIO.output(22, GPIO.HIGH)
time.sleep(impulse_timeout)
GPIO.output(22, GPIO.LOW)
time.sleep(step_timeout)

Как можно целиком вот этот кусок когда загнать в массив или переменную? Я немножко запутался, или это все так же через подобные функции делается?:
step_timeout = 0.0105
# Длительность импульса, сек.
impulse_timeout = 0.008

Можете показать пример?

0
ph0en1x #14ph0en1x
01 Август 2018 09:22

Собираем этот многострочный код в функцию и вызываем ее, передав нужные аргументы:

step_timeout = 0.0105
impulse_timeout = 0.008

def impulse(channel=0):
    """ Generate impulse. """
    GPIO.output(channel, GPIO.HIGH)
    time.sleep(impulse_timeout)
    GPIO.output(channel, GPIO.LOW)
    time.sleep(step_timeout)

for i in range(0,20):
    impulse(4)
    impulse(17)
    impulse(27)
    impulse(22)

Аналогичным способом все реализовано уже во втором примере программы из статьи.

0