Библиотека управления мотором для Arduino

ОБНОВЛЕНИЯ


  • v3.1: мелкие исправления
  • v3.2: улучшена стабильность плавного режима
Предыдущие

  • v1.1 — убраны дефайны
  • v1.2 — возвращены дефайны
  • v2.0:
    • Программный deadtime
    • Отрицательные скорости
    • Поддержка двух типов драйверов и реле
    • Плавный пуск и изменение скорости
  • v2.1: небольшие фиксы и добавления
  • v2.2: оптимизация
  • v2.3: добавлена поддержка esp (исправлены ошибки)
  • v2.4: совместимость с другими библами
  • v2.5: добавлен тип DRIVER2WIRE_NO_INVERT
  • v3.0: переделана логика minDuty, добавлен режим для ШИМ любой битности

ТЕОРИЯ


Библиотека подходит для большинства драйверов, построенных по схеме H-мост, на два мотора они обычно имеют 4 входа (по 2 на каждый). Также на сайте есть отдельный подробный урок по работе с коллекторными моторами.

БИБЛИОТЕКА


Библиотека для удобного управления моторчиками через драйвер полного моста для Arduino

  • Контроль скорости и направления вращения
  • Работа с 10 битным ШИМом
  • Программный deadtime
  • Отрицательные скорости
  • Поддержка двух типов драйверов и реле
  • Плавный пуск и изменение скорости

Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции).

В версии 2.2 добавлена поддержка плат на базе ESP

УСТАНОВКА


  • Библиотеку можно найти и установить через менеджер библиотек по названию GyverMotor в:
    • Arduino IDE (Инструменты/Управлять библиотеками)
    • Arduino IDE v2 (вкладка «Library Manager»)
    • PlatformIO (PIO Home, вкладка «Libraries»)
  • Про ручную установку читай здесь

ДОКУМЕНТАЦИЯ


Инициализация


Библиотека поддерживает три типа драйверов:
  • DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ)
  • DRIVER2WIRE_NO_INVERT - двухпроводной драйвер, в котором при смене направления не нужна инверсия ШИМ
  • DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ)
  • RELAY2WIRE - реле в качестве драйвера (два пина направления)
Инициализация происходит следующим образом:
  • GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, level);
  • GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, level);
  • GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, level);
Где
  • dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК
  • PWM_pin - любой ШИМ пин МК
  • level - LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень

Настройки


  • setDeadtime(us) - установка программного deadtime на переключение направления, us в микросекундах. По умолчанию стоит 0: deadtime отключен
  • setDirection(dir) - ГЛОБАЛЬНАЯ смена направления вращения мотора например чтобы FORWARD совпадал с направлением движения "вперёд" у машинки. dir - REVERSE или NORMAL (умолч.)
  • setLevel(level) - смена уровня драйвера (аналогично при инициализации). Если при увеличении скорости мотор наоборот тормозит - смени уровень. level - LOW или HIGH
  • setMinDuty(duty) - минимальный сигнал (по модулю), который будет подан на мотор. Автоматически сжимает диапазон регулирования мотора: например minDuty поставили 50, и при сигнале 1 будет на мотор будет подано ~51, максимум останется прежним (диапазон сигнала  переведётся в 50.. 255 внутри библиотеки).

Режим работы


У мотора есть 5 режимов работы, устанавливаются при помощи setMode(mode), где mode:
  • FORWARD - вперёд
  • BACKWARD - назад
  • STOP - холостой (мотор отключен)
  • AUTO - отдать управление функции setSpeed()

Управление скоростью и направлением


Скорость устанавливается при помощи функции setSpeed(speed). Есть два варианта управления скоростью:
  • Направление в ручном режиме, скорость 0..255 (0..1023). В этом случае скорость должна быть положительной (setSpeed(0..255)), направление вращения задаётся при помощи setMode(). При направлении FORWARD частота оборотов растёт по мере увеличения setSpeed(speed), при направлении BACKWARD частота оборотов растёт в противоположную сторону по мере увеличения setSpeed(speed).
  • Направление в автоматическом режиме, скорость -255..255 (-1023..1023 для 10 бит). В этом случае устанавливаем  setMode(AUTO) и подаём скорость во всём диапазоне. При значении мотор -255 крутится с максимальной скоростью в направлении "назад", при 255 - в направлении "вперёд". При значении 0 (ноль) режим автоматически переключается на STOP. Если задан параметр minDuty (при помощи setMinDuty()), то режим STOP будет автоматически активирован при значении скорости в пределах (-minDuty, minDuty). Пример: у нас есть мотор, экспериментально установлено, что он начинает вращаться при величине скорости больше 50 (и, соответственно, меньше -50), при меньшем значении он просто "пищит" и стоит на месте. Если мы выставим setMinDuty(50), то в диапазоне -50..50 мотор автоматически будет находиться в режиме STOP и не будет пищать при "шуме" задающего сигнала.

Разрешение ШИМ


setSpeed(speed) может работать с ШИМ любого разрешения, для этого нужно
  • Перевести таймер в режим нужного разрешения. 8 битные таймеры можно запустить только на пониженном разрешении, а 16 битный - например на 10 битах (выводы D9 и D10), смотрите пример в библиотеке и урок по частоте ШИМ. По Arduino MEGA пока что такого готового набора у меня нет.
  • Настроить нужный объект класса GMotor на нужное разрешение при помощи setResolution(bit), где bit - разрешение ШИМ в битах (по умолчанию 8). Также не забыть подключить пин драйвера ШИМ к выводу настроенного в первом пункте таймера (смотри пример).
Несколько моторов могут работать на одной плате с разным разрешением, т.е. например 2 мотора на таймере 1 с разрешением 10 бит, и ещё два на таймере 2 с разрешением 8 бит.

Плавное управление скоростью


В библиотеке реализован готовый инструмент для плавного изменения скорости, что может обеспечить плавный пуск и остановку механизмов:
  • setSmoothSpeed(acc) - установка скорости изменения скорости (т.е. ускорения) мотора
  • smoothTick(speed) - данная функция сама меняет скорость мотора, плавно приближая её к указанной speed. Функция работает по встроенному таймеру на millis() с периодом 50 мс, то есть рекомендуется вызывать smoothTick(speed) не реже, чем каждые 50 мс.
В примере smooth_control можно открыть плоттер и посмотреть, как работает алгоритм.

Работа на esp8266


В esp8266 по умолчанию настроен 10-битный ШИМ, поэтому библиотеку нужно обязательно переключить в  режим 10 бит: motor.setResolution(10);
GMotor(driverType type, int8_t param1 = NC, int8_t param2 = NC, int8_t param3 = NC, int8_t param4 = NC);
// 4 варианта создания объекта в зависимости от драйвера:
// GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW/HIGH) )
// GMotor motor(DRIVER2WIRE_NO_INVERT, dig_pin, PWM_pin, (LOW/HIGH) )
// GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) )
// GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) )

// установка скорости 0-255 (8 бит) и 0-1023 (10 бит)
void setSpeed(int16_t duty);			

// сменить режим работы мотора:	
// FORWARD - вперёд
// BACKWARD - назад
// STOP - остановить
void setMode(workMode mode);

// направление вращения	
// NORM - обычное
// REVERSE - обратное
void setDirection(dir direction);

// установить разрешение ШИМ в битах (по умолч 8)
void setResolution(byte bit);		

// установить deadtime (в микросекундах). По умолч 0
void setDeadtime(uint16_t deadtime);	

// установить уровень драйвера (по умолч. HIGH)
void setLevel(int8_t level);			

// плавное изменение к указанной скорости
void smoothTick(int16_t duty);

// скорость изменения скорости
void setSmoothSpeed(uint8_t speed);

// дать прямую команду мотору (без смены режима)
void run(workMode mode, int16_t duty);	

// внутренняя переменная скважности для отладки
int16_t _duty = 0;

ПРИМЕРЫ


/*
  Пример управления мотором при помощи драйвера полного моста и потенциометра
*/
#include "GyverMotor.h"
GMotor motor(DRIVER2WIRE, 2, 3, HIGH);
// варианты инициализации в зависимости от типа драйвера:
// GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) )
// GMotor motor(DRIVER2WIRE_NO_INVERT, dig_pin, PWM_pin, (LOW / HIGH) )
// GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) )
// GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) )
/*
  DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ)
  DRIVER2WIRE_NO_INVERT - двухпроводной драйвер, в котором при смене направления не нужна инверсия ШИМ
  DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ)
  RELAY2WIRE - реле в качестве драйвера (два пина направления)
  dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК
  PWM_pin - любой ШИМ пин МК
  LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень
*/
void setup() {
  // установка программного deadtime на переключение направления, микросекунды
  // по умолчанию стоит 0: deadtime отключен
  // motor.setDeadtime(200);
  // ГЛОБАЛЬНАЯ смена направления вращения мотора
  // например чтобы FORWARD совпадал с направлением движения "вперёд" у машинки  
  motor.setDirection(REVERSE);
  motor.setDirection(NORMAL);   // умолч.
  // смена режима работы мотора
  motor.setMode(FORWARD);   // вперёд
  motor.setMode(BACKWARD);  // назад
  motor.setMode(STOP);      // стоп, холостой (мотор отключен)
  // смена уровня драйвера (аналогично при инициализации)
  // Если при увеличении скорости мотор наоборот тормозит - смени уровень
  motor.setLevel(LOW);
  motor.setLevel(HIGH);     // по умолч.
  
  
  // для работы в 10 бит необходимо также настроить ШИМ на 10 бит!!!
  // читай тут https://alexgyver.ru/lessons/pwm-overclock/
  // motor.setResolution(10);
  // минимальный сигнал (по модулю), который будет подан на мотор
  // Избавляет от ситуаций, когда мотор покоится и "пищит"
  motor.setMinDuty(150);
  // ключ на старт!
  motor.setMode(FORWARD);
}
void loop() {
  // потенциометр на А0
  // преобразуем значение в -255.. 255
  int val = 255 - analogRead(0) / 2;
  // установка скорости:
  // * (0..255) при ручном выборе направления (setMode: FORWARD/BACKWARD)
  // * (-255..255) при автоматическом (поставить setMode(FORWARD))
  // * (0..1023) в режиме 10 бит при ручном выборе направления (setMode: FORWARD/BACKWARD)
  // * (-1023..1023) в режиме 10 бит при автоматическом (поставить setMode(FORWARD))    
  
  motor.setSpeed(val);
  // в данном случае мотор будет остановлен в среднем положении рукоятки
  // и разгоняться в противоположные скорости в крайних её положениях
  
  delay(10);  // задержка просто для "стабильности"
}
/*
  Пример управления мотором при помощи драйвера полного моста и потенциометра
  на ШИМ 10 бит
*/
#include "GyverMotor.h"
GMotor motor(DRIVER2WIRE, 2, 9, HIGH);
// варианты инициализации в зависимости от типа драйвера:
// GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) )
// GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) )
// GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) )
/*
  DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ)
  DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ)
  RELAY2WIRE - реле в качестве драйвера (два пина направления)
  dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК
  PWM_pin - любой ШИМ пин МК
  LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень
*/
void setup() {
  // разгоняем ШИМ на пинах 9 и 10 (atmega328) до 16 кГц 10 бит
  // читай тут: https://alexgyver.ru/lessons/pwm-overclock/
  TCCR1A = 0b00000011;  // 10bit
  TCCR1B = 0b00001001;  // x1 fast pwm
  // активируем 10-битный режим библиотеки
  motor.setResolution(10);
  // ключ на старт!
  motor.setMode(FORWARD);
}
void loop() {
  // потенциометр на А0
  // преобразуем значение в -1023.. 1023
  int val = 1023 - analogRead(0) * 2;
  motor.setSpeed(val);
  // в данном случае мотор будет остановлен в среднем положении рукоятки
  // и разгоняться в противоположные скорости в крайних её положениях
  delay(10);  // задержка просто для "стабильности"
}
/*
  Пример плавного управления мотором при помощи драйвера полного моста и потенциометра
*/
#include "GyverMotor.h"
GMotor motor(DRIVER2WIRE, 2, 3, HIGH);
// варианты инициализации в зависимости от типа драйвера:
// GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) )
// GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) )
// GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) )
/*
  DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ)
  DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ)
  RELAY2WIRE - реле в качестве драйвера (два пина направления)
  dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК
  PWM_pin - любой ШИМ пин МК
  LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень
*/
void setup() {
  Serial.begin(9600);
  // установка скорости изменения скорости (ускорения) мотора
  motor.setSmoothSpeed(20);
  // ключ на старт!
  motor.setMode(FORWARD);
}
void loop() {
  // потенциометр на А0
  // преобразуем значение в -255.. 255
  int val = 255 - analogRead(0) / 2;
  // данную функцию рекомендуется вызывать чаще чем каждые 50 мс
  // (работает по встроенному таймеру)
  // она будет плавно менять скорость мотора к заданной
  motor.smoothTick(val);
  // отладка. Откройте Инструменты/Плоттер по последовательному порту
  Serial.print(val);            // первый график - установленная скорость
  Serial.print(',');
  Serial.println(motor._duty);  // второй график - реальный сигнал на мотор
  
  delay(10);  // задержка просто для "стабильности"
}

ВИДЕО


ПОДДЕРЖАТЬ


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

5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest

18 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх