Производительная библиотека для управления шаговыми моторами с Arduino
- Поддержка 4х пинового (шаг и полушаг) и STEP-DIR драйверов
- Автоматическое отключение питания при достижении цели
- Режимы работы:
- Вращение с заданной скоростью. Плавный разгон и торможение с ускорением
- Следование к позиции с ускорением и ограничением скорости
- Следование к позиции с заданной скоростью (без ускорения)
- Быстрый алгоритм управления шагами
- Поддержка "виртуальных" драйверов
- Встроенный многоосевой планировщик траекторий
Совместима со всеми Arduino платформами (используются Arduino-функции)
К библиотеке есть расширенная документация
- Установка
- StepperCore
- GyverStepper
- GyverStepper2
- GyverPlanner
- GyverPlanner2
- Версии
- Баги и обратная связь
Библиотека содержит набор инструментов для разных сценариев работы с шаговыми моторами
- StepperCore.h [класс Stepper]: ядро всех остальных классов, умеет быстро щёлкать пинами (AVR) и делать один шаг для настроенного типа драйвера. Поддерживает 4 фазы шаг/полушаг, а также step-dir драйверы.
- GyverStepper.h [класс GStepper]: основная тяжёлая библиотека, много настроек. Движение одного мотора с ускорением к заданной позиции или вращение с заданной скоростью. Не очень оптимальная работа в прерывании таймера.
- GyverStepper2.h [класс GStepper2]: новая облегченная версия GyverStepper, практически полностью с ней совместима. Более оптимальный целочисленный гибридный алгоритм движения с ускорением, лёгкий вес. Оптимизировано для работы в прерывании таймера.
- GyverPlanner.h [класс GPlanner]: многоосевой планировщик траектории, движение с ускорением (2 порядок). Остановка в каждой точке. Оптимальная работа в прерывании таймера.
- GyverPlanner2.h [класс GPlanner2]: многоосевой планировщик траектории, движение с ускорением (2 порядок). Планирование скорости на маршруте, оптимальное движение по точкам. Оптимальная работа в прерывании таймера.
- Библиотеку можно найти по названию GyverStepper и установить через менеджер библиотек в:
- Arduino IDE
- Arduino IDE v2
- PlatformIO
- Скачать библиотеку .zip архивом для ручной установки:
- Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
- Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
- Распаковать и положить в Документы/Arduino/libraries/
- (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
- Читай более подробную инструкцию по установке библиотек здесь
- Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
- Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
- Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
Ядро библиотеки для управления шаговыми моторами:
- 4 фазные и STEP DIR драйверы
- Поддержка пина EN
- Виртуальный драйвер
- Быстрый алгоритм IO для AVR
РАЗВЕРНУТЬ
Stepper<STEPPER2WIRE> stepper(step, dir); // драйвер step-dir
Stepper<STEPPER2WIRE> stepper(step, dir, en); // драйвер step-dir + пин enable
Stepper<STEPPER4WIRE> stepper(pin1, pin2, pin3, pin4); // драйвер 4 пин
Stepper<STEPPER4WIRE> stepper(pin1, pin2, pin3, pin4, en); // драйвер 4 пин + enable
Stepper<STEPPER4WIRE_HALF> stepper(pin1, pin2, pin3, pin4); // драйвер 4 пин полушаг
Stepper<STEPPER4WIRE_HALF> stepper(pin1, pin2, pin3, pin4, en); // драйвер 4 пин полушаг + enable
Stepper<STEPPER2WIRE, STEPPER_VIRTUAL> stepper; // виртуальный драйвер step-dir
Stepper<STEPPER4WIRE, STEPPER_VIRTUAL> stepper; // виртуальный драйвер 4 пин
void step(); // сделать шаг
void invertEn(bool val); // инвертировать поведение EN пина
void reverse(bool val); // инвертировать направление мотора
void disable(); // отключить питание и EN
void enable(); // включить питание и EN
void power(bool); // переключить питание
void attachStep(void (*handler)(uint8_t)); // подключить обработчик шага
void attachPower(void (*handler)(bool)); // подключить обработчик питания
int32_t pos; // текущая позиция в шагах
int8_t dir; // направление (1, -1)
Остальные примеры смотри в examples!
#include <StepperCore.h>
Stepper<STEPPER2WIRE> stepper(2, 3);
void setup() {
stepper.dir = 1; // или -1
stepper.pos = 0; // доступ к позиции
}
void loop() {
// крутим вручную
stepper.step(); // сделать шаг
delay(10);
}
- GStepper2 гораздо легче и сильнее оптимизирована
- GStepper2 больше предназначена для движения по точкам траектории, но "следящий" режим в ней также работает
- GStepper2 оптимизирована для работы в прерывании таймера
- GStepper2 использует плавный алгоритм движения мотора по умолчанию
- GStepper2 скорее всего будет чуть больше нагружать микроконтроллер во время работы, чем GStepper. Но гораздо меньше, чем GStepper в режиме SMOOTH_ALGORITHM
- Быстрый алгоритм (по умолчанию): в библиотеке заведено два таймера: таймер шагов (разный период) и таймер планировщика (10-30 миллисекунд). По таймеру планировщика производится перерасчёт траектории и вычисляется направление движения и текущая необходимая скорость. Из этой скорости получается новый период для таймера шагов.
- Плавный алгоритм (настройка SMOOTH_ALGORITHM): работает один таймер шагов, на каждом шаге производится перерасчёт скорости движения и времени до следующего шага.
- Плавный профиль (по умолчанию): здесь используется алгоритм плавного движения SMOOTH_ALGORITHM как в GStepper, но оптимизирован и ускорен в 2-3 раза. Все тяжёлые вычисления траектории производятся при задании новой целевой позиции в setTarget. Далее по таймеру шагов мотор шагает и быстро вычисляет новое время следующего шага. Это позволяет тратить минимум времени в прерывании таймера, если оно используется.
- Быстрый профиль (настройка GS_FAST_PROFILE): всё то же самое, но в таймере шагов происходит не вычисление, а выбор периода из заранее посчитанной таблицы, что позволяет двигаться с ускорением вплоть до скоростей 30000 шагов в секунду.
Библиотека для управления шаговыми моторами с Arduino
- Поддержка 4х пинового (шаг и полушаг) и STEP-DIR драйверов
- Автоматическое отключение питания при достижении цели
- Режимы работы:
- Вращение с заданной скоростью. Плавный разгон и торможение с ускорением
- Следование к позиции с ускорением и ограничением скорости
- Следование к позиции с заданной скоростью (без ускорения)
РАЗВЕРНУТЬ
// steps - шагов на один оборот вала (для расчётов с градусами)
// step, dir, pin1, pin2, pin3, pin4 - любые GPIO
// en - пин отключения драйвера, любой GPIO
GStepper<STEPPER2WIRE> stepper(steps, step, dir); // драйвер step-dir
GStepper<STEPPER2WIRE> stepper(steps, step, dir, en); // драйвер step-dir + пин enable
GStepper<STEPPER4WIRE> stepper(steps, pin1, pin2, pin3, pin4); // драйвер 4 пин
GStepper<STEPPER4WIRE> stepper(steps, pin1, pin2, pin3, pin4, en); // драйвер 4 пин + enable
GStepper<STEPPER4WIRE_HALF> stepper(steps, pin1, pin2, pin3, pin4); // драйвер 4 пин полушаг
GStepper<STEPPER4WIRE_HALF> stepper(steps, pin1, pin2, pin3, pin4, en); // драйвер 4 пин полушаг + enable
GStepper<STEPPER4WIRE, STEPPER_VIRTUAL> stepper(2048); // виртуальный драйвер, указать только количество шагов
// Примечание: далее по тексту под "по умолчанию" имеется в виду "даже если не вызывать функцию"
// Здесь происходит движение мотора, вызывать как можно чаще!
// Имеет встроенный таймер
// Возвращает true, если мотор движется к цели или крутится по KEEP_SPEED
bool tick();
// Возвращает то же самое, что tick, т.е. крутится мотор или нет
bool getState();
// Инвертировать направление мотора - true (по умолч. false)
void reverse(bool dir);
// инвертировать поведение EN пина - true (по умолч. false)
void invertEn(bool rev);
// Установка режима работы, mode:
// FOLLOW_POS - следование к позиции setTarget(...)
// KEEP_SPEED - удержание скорости setSpeed(...)
void setRunMode(GS_runMode mode);
// Установка текущей позиции мотора в шагах и градусах
void setCurrent(long pos);
void setCurrentDeg(float pos);
// Чтение текущей позиции мотора в шагах и градусах
long getCurrent();
float getCurrentDeg();
// установка целевой позиции в шагах и градусах (для режима FOLLOW_POS)
// type - ABSOLUTE или RELATIVE, по умолчанию стоит ABSOLUTE
void setTarget(long pos);
void setTarget(long pos, GS_posType type);
void setTargetDeg(float pos);
void setTargetDeg(float pos, GS_posType type);
// Получение целевой позиции в шагах и градусах
long getTarget();
float getTargetDeg();
// Установка максимальной скорости (по модулю) в шагах/секунду и градусах/секунду (для режима FOLLOW_POS)
// по умолч. 300
void setMaxSpeed(float speed);
void setMaxSpeedDeg(float speed);
// Установка ускорения в шагах и градусах в секунду (для режима FOLLOW_POS).
// При значении 0 ускорение отключается и мотор работает
// по профилю постоянной максимальной скорости setMaxSpeed().
// По умолч. 300
void setAcceleration(int accel);
void setAccelerationDeg(float accel);
// Автоотключение EN при достижении позиции - true (по умолч. false)
void autoPower(bool mode);
// Плавная остановка с заданным ускорением
void stop();
// Жёсткая остановка
void brake();
// Жёсткая остановка + сброс позиции в 0 (для концевиков)
void reset();
// Установка целевой скорости в шагах/секунду и градусах/секунду (для режима KEEP_SPEED)
void setSpeed(float speed);
void setSpeedDeg(float speed);
// Получение целевой скорости в шагах/секунду и градусах/секунду (для режима KEEP_SPEED)
float getSpeed();
float getSpeedDeg();
// Включить мотор (пин EN)
void enable();
// Выключить мотор (пин EN)
void disable();
// Возвращает минимальный период тика мотора в микросекундах при настроенной setMaxSpeed() скорости.
// Можно использовать для настройки прерываний таймера, в обработчике которого будет лежать tick() (см. пример timerISR)
uint16_t getMinPeriod();
// Текущий период "тика" для отладки и всего такого
uint16_t stepTime;
// подключить внешний обработчик для шага и переключения питания
void attachStep(handler)
void attachPower(handler)
Остальные примеры смотри в examples!
#include <GyverStepper.h>
GStepper<STEPPER4WIRE> stepper(2048, 5, 3, 4, 2);
void setup() {
Serial.begin(115200);
// режим поддержания скорости
stepper.setRunMode(KEEP_SPEED);
// можно установить скорость
stepper.setSpeed(120); // в шагах/сек
stepper.setSpeedDeg(80); // в градусах/сек
// режим следования к целевй позиции
stepper.setRunMode(FOLLOW_POS);
// можно установить позицию
stepper.setTarget(-2024); // в шагах
stepper.setTargetDeg(-360); // в градусах
// установка макс. скорости в градусах/сек
stepper.setMaxSpeedDeg(400);
// установка макс. скорости в шагах/сек
stepper.setMaxSpeed(400);
// установка ускорения в градусах/сек/сек
stepper.setAccelerationDeg(300);
// установка ускорения в шагах/сек/сек
stepper.setAcceleration(300);
// отключать мотор при достижении цели
stepper.autoPower(true);
// включить мотор (если указан пин en)
stepper.enable();
}
void loop() {
// просто крутим туды-сюды
if (!stepper.tick()) {
static bool dir;
dir = !dir;
stepper.setTarget(dir ? -1024 : 1024);
}
}
Облегчённая GyverStepper
- Легче на несколько кБ, всё целочисленное
- Повышенная точность позиционирования
- Более эффективный гибридный алгоритм движения
- Движение к цели с ускорением
- Вращение со скоростью
- Макс. скорость:
- Обычный режим: 37000 шаг/с на полной, 18000 шаг/с на разгоне
- Быстрый профиль: 37000 шаг/с на полной, 37000 шаг/с на разгоне
- Оптимизировано для работы по прерыванию таймера
- Наследует StepperCore
- setTarget()/setTargetDeg() отправляет мотор на указанную позицию
- Движение происходит в tick(), который нужно опрашивать постоянно. Либо в tickManual, который нужно вызывать с периодом, полученным из getPeriod() и пересчитывать на каждом шаге
- tick() вернёт true, если мотор крутится
- ready() однократно вернёт true, если мотор доехал до цели и остановился
- Во время движения к цели можно вызвать pause(), тогда мотор доедет до точки и остановится, ready() не вернёт true
- Во время движения к цели можно вызвать stop(), тогда мотор затормозит с заданным ускорением, ready() не вернёт true
- Во время движения к цели можно вызвать brake(), тогда мотор остановится, ready() не вернёт true
- После остановки можно вызвать resume(), мотор продолжит движение к цели
- Постоянное вращение задаётся setSpeed()/setSpeedDeg(). Остановиться можно резко - stop() или brake()
- Скорость и ускорение можно задать в любое время, но применяются они после остановки мотора!
РАЗВЕРНУТЬ
GStepper2<STEPPER2WIRE> stepper(шаговНаОборот, step, dir); // драйвер step-dir
GStepper2<STEPPER2WIRE> stepper(шаговНаОборот, step, dir, en); // драйвер step-dir + пин enable
GStepper2<STEPPER4WIRE> stepper(шаговНаОборот, pin1, pin2, pin3, pin4); // драйвер 4 пин
GStepper2<STEPPER4WIRE> stepper(шаговНаОборот, pin1, pin2, pin3, pin4, en); // драйвер 4 пин + enable
GStepper2<STEPPER4WIRE_HALF> stepper(шаговНаОборот, pin1, pin2, pin3, pin4); // драйвер 4 пин полушаг
GStepper2<STEPPER4WIRE_HALF> stepper(шаговНаОборот, pin1, pin2, pin3, pin4, en); // драйвер 4 пин полушаг + enable
GStepper2<STEPPER2WIRE, STEPPER_VIRTUAL> stepper; // виртуальный драйвер step-dir
GStepper2<STEPPER4WIRE, STEPPER_VIRTUAL> stepper; // виртуальный драйвер 4 пин
// === наследуется из Stepper ====
void step(); // сделать шаг
void invertEn(bool val); // инвертировать поведение EN пина
void reverse(bool val); // инвертировать направление мотора
void disable(); // отключить питание и EN
void enable(); // включить питание и EN
void attachStep(void (*handler)(uint8_t)); // подключить обработчик шага
void attachPower(void (*handler)(bool)); // подключить обработчик питания
int32_t pos; // текущая позиция в шагах
int8_t dir; // направление (1, -1)
// ========= GStepper2 ==========
// тикер
bool tick(); // тикер движения, вызывать часто. Вернёт true, если мотор движется
bool tickManual(); // ручной тикер для вызова в прерывании таймера с периодом getPeriod(). Вернёт true, если мотор движется
bool ready(); // однократно вернёт true, если мотор доехал до установленной позиции и остановился
// вращение
void setSpeed(int16_t speed); // установить скорость в шагах/сек и запустить вращение
void setSpeed(float speed); // установить скорость в шагах/сек (float) и запустить вращение
// движение к цели
void setTarget(int32_t ntar, GS_posType type = ABSOLUTE); // установить цель в шагах и опционально режим ABSOLUTE/RELATIVE
void setTargetDeg(int32_t ntar, GS_posType type = ABSOLUTE); // установить цель в градусах и опционально режим ABSOLUTE/RELATIVE
int32_t getTarget(); // получить целевую позицию в шагах
void setAcceleration(uint16_t nA); // установка ускорения в шаг/сек^2
void setMaxSpeed(int speed); // установить скорость движения при следовании к позиции setTarget() в шагах/сек
void setMaxSpeed(float speed); // установить скорость движения при следовании к позиции setTarget() в шагах/сек, float
void setMaxSpeedDeg(int speed); // установить скорость движения при следовании к позиции в град/сек
void setMaxSpeedDeg(float speed); // установить скорость движения при следовании к позиции в град/сек, float
void setCurrent(int32_t npos); // установить текущую позицию
int32_t getCurrent(); // получить текущую позицию
void reset(); // сбросить текущую позицию в 0
// всякое
void autoPower(bool mode); // автоотключение мотора при достижении позиции - true (по умолч. false)
uint32_t getPeriod(); // получить текущий период тиков
void brake(); // резко остановить мотор
void pause(); // пауза - доехать до заданной точки и ждать (ready() не вернёт true, пока ты на паузе)
void resume(); // продолжить движение после остановки/паузы
uint8_t getStatus(); // текущий статус: 0 - стоим, 1 - едем, 2 - едем к точке паузы, 3 - крутимся со скоростью, 4 - тормозим
// ===== ДЕФАЙНЫ НАСТРОЕК =====
// дефайнить перед подключением библиотеки
#define GS_NO_ACCEL // отключить модуль движения с ускорением (уменьшить вес кода)
#define GS_FAST_PROFILE размер_массива (например 10)
Включает быстрый планировщик скорости. Участок разгона/торможения разбивается
на указанное количество отрезков (+8 байт SRAM на участок), на них скорость будет одинаковая.
Это позволяет быстро вычислять скорость мотора и достигнуть 30000 шаг/с на участке разгона
(в обычном режиме в два раза меньше).
Остальные примеры смотри в examples!
// крутим туда сюда, тикаем в loop
#include "GyverStepper2.h"
GStepper2<STEPPER2WIRE> stepper(2048, 2, 3);
void setup() {
Serial.begin(9600);
//stepper.enable();
stepper.setMaxSpeed(100); // скорость движения к цели
stepper.setAcceleration(200); // ускорение
stepper.setTarget(300); // цель
}
bool dir = 1;
void loop() {
stepper.tick(); // мотор асинхронно крутится тут
// если приехали
if (stepper.ready()) {
dir = !dir; // разворачиваем
stepper.setTarget(dir * 300); // едем в другую сторону
}
// асинхронный вывод в порт
static uint32_t tmr;
if (millis() - tmr >= 30) {
tmr = millis();
Serial.println(stepper.pos);
}
}
Многоосевой планировщик траекторий для шаговых моторов и создания станка с ЧПУ
- ОСТАНОВКА В КАЖДОЙ ТОЧКЕ. БУФЕР НА ОДНУ СЛЕДУЮЩУЮ ПОЗИЦИЮ
- Макс. скорость:
- Обычный режим: 37000 шаг/с на полной, 14000 шаг/с на разгоне
- Быстрый профиль: 37000 шаг/с на полной, 37000 шаг/с на разгоне
- Трапецеидальный профиль скорости (планировщик 2-го порядка)
- Настройка скорости и ускорения
- Любое количество осей. Будут двигаться синхронно к заданным целям
- Быстрая целочисленная модель планирования траектории и скорости
- Режим постоянного вращения для одной оси (для движения к концевику например)
- Тормоз/плавная остановка/пауза на траектории планировщика
- Оптимизировано для работы по прерыванию таймера
- Быстрый контроль пинов шаговика для Arduino AVR
- Скорость и ускорение можно задать в любое время, но применяются они после остановки мотора!
Планировщик управляет любым количеством моторов, вращая их к указанной позиции. В данной версии остановка происходит в каждой точке траектории, после чего поднимается флаг ready() и ожидает установки следующей точки.
- Смотри симуляцию в Processing: папка Planner Simulation/Planner
РАЗВЕРНУТЬ
GPlanner<драйвер, количество осей> planner;
void addStepper(uint8_t axis, Stepper &stp); // подключить мотор класса Stepper на ось axis
// примечание: тип драйвера должен совпадать у планировщика и моторов
void setBacklash(uint8_t axis, uint16_t steps); // установить компенсацию люфта на ось axis в количестве шагов steps
void enable(); // включить моторы
void disable(); // выключить моторы
void power(bool v); // переключить питание
// НАСТРОЙКИ
void setMaxSpeed(float nV); // установка максимальной скорости планировщика в шаг/сек
void setAcceleration(uint16_t nA); // установка ускорения планировщика в шаг/сек^2
// ПЛАНИРОВЩИК
uint32_t getPeriod(); // возвращает время в мкс до следующего вызова tick/tickManual
bool ready(); // true - готов принять следующую точку маршрута
void pause(); // пауза (доехать до заданной точки и ждать). ready() не вернёт true, пока ты на паузе
void stop(); // остановить плавно (с заданным ускорением)
void brake(); // резко остановить моторы из любого режима
void resume(); // продолжить после остановки/паузы
void reset(); // сбросить счётчики всех моторов в 0
void home(); // отправить в 0 по всем осям
uint8_t getStatus(); // текущий статус: 0 - стоим, 1 - едем, 2 - едем к точке паузы, 3 -крутимся со скоростью
// СКОРОСТЬ
void setSpeed(uint8_t axis, float speed); // режим постоянного вращения для оси axis со скоростью speed шаг/сек (м.б. отрицателеьной)
// ПОЗИЦИЯ
void setCurrent(int16_t cur[]); // установить текущее положение моторов
void setCurrent(int32_t cur[]); // установить текущее положение моторов
int32_t getCurrent(int axis); // получить текущую позицию по оси axis
// установить цель в шагах и начать движение. type - ABSOLUTE (по умолч.) или RELATIVE
// ABSOLUTE - конкретные координаты точки, куда двигаться
// RELATIVE - смещение относительно текущих положений моторов
// вернёт true, если цель установлена. false, если цель совпадает с текущей
bool setTarget(int32_t target[]);
bool setTarget(int16_t target[]);
bool setTarget(int32_t target[], type);
bool setTarget(int16_t target[], type);
int32_t getTarget(int axis); // получить цель в шагах на оси axis
// ТИКЕР
// тикер, вызывать как можно чаще. Вернёт true, если мотор крутится
// здесь делаются шаги как для движения по точкам, так и для вращения по скорости
bool tick();
// ручной тикер для вызова в прерывании или где то ещё. Выполняется 20..50 us
bool tickManual();
// ======= ДЕФАЙНЫ НАСТРОЕК =======
// объявлять перед подключением библиотеки
#define GS_FAST_PROFILE размер_массива (например 10)
Включает быстрый планировщик скорости. Участок разгона/торможения разбивается
на указанное количество отрезков (+8 байт SRAM на участок), на них скорость будет одинаковая.
Это позволяет быстро вычислять скорость мотора и достигнуть 30000 шаг/с на участке разгона
(в обычном режиме в два раза меньше).
Остальные примеры смотри в examples!
// базовый пример: как создать и запустить планировщик
// при запуске моторы будут отправлены на первую позицию
// при достижении - на вторую. После этого движение прекратится
// открой плоттер и смотри графики
#include "GyverPlanner.h"
// создаём моторы класса Stepper с указанием типа драйвера и пинов
// МОТОРЫ ДОЛЖНЫ БЫТЬ С ОДИНАКОВЫМ ТИПОМ ДРАЙВЕРА
// вот они красавцы
Stepper<STEPPER2WIRE> stepper1(2, 3);
Stepper<STEPPER2WIRE> stepper2(4, 5);
// создаём планировщик, указываем в <> тип драйвера КАК У МОТОРОВ
// и количество осей, равное количеству моторов (любое больше 1)
GPlanner<STEPPER2WIRE, 2> planner;
void setup() {
Serial.begin(115200);
// добавляем шаговики на оси
planner.addStepper(0, stepper1); // ось 0
planner.addStepper(1, stepper2); // ось 1
// устанавливаем ускорение и скорость
planner.setAcceleration(100);
planner.setMaxSpeed(300);
planner.reset(); // сбрасываем все позиции в 0 (они и так в 0 при запуске)
// массив с целевыми позициями осей, размер массива равен количеству осей
int target[] = {300, 200};
// отправляем
planner.setTarget(target);
}
void loop() {
// здесь происходит движение моторов, вызывать как можно чаще
planner.tick();
// вернёт true, если все моторы доехали
if (planner.ready()) {
// загружаем новую точку
int newTarget[] = {10, 50};
planner.setTarget(newTarget);
}
// асинхронно вывожу в порт графики
static uint32_t tmr;
if (millis() - tmr >= 20) {
tmr = millis();
Serial.print(stepper1.pos);
Serial.print(',');
Serial.println(stepper2.pos);
}
}
Многоосевой планировщик траекторий для шаговых моторов и создания станка с ЧПУ
- ПЛАНИРОВАНИЕ СКОРОСТИ НА МАРШРУТЕ. НАСТРАИВАЕМЫЙ БУФЕР
- Макс. скорость:
- Обычный режим: 37000 шаг/с на полной, 14000 шаг/с на разгоне
- Быстрый профиль: 37000 шаг/с на полной, 37000 шаг/с на разгоне
- Трапецеидальный профиль скорости (планировщик 2-го порядка)
- Настройка скорости и ускорения
- Любое количество осей. Будут двигаться синхронно к заданным целям
- Быстрая целочисленная модель планирования траектории и скорости
- Режим постоянного вращения для одной оси (для движения к концевику например)
- Тормоз/плавная остановка/пауза на траектории планировщика
- Оптимизировано для работы по прерыванию таймера
- Быстрый контроль пинов шаговика для Arduino AVR
- Скорость и ускорение можно задать в любое время, но применяются они после остановки мотора!
Планировщик управляет любым количеством моторов, вращая их к указанной позиции. В данной версии реализован буфер траектории, который можно наполнять точками, пока available() возвращает true. addTarget() принимает:
- Массив точек указанного при инициализации размера
- Флаг остановки. Если передать 1 - планировщик остановит мотор в этой точке и будет ждать дальнейшей команды resume()
- Тип точки: ABSOLUTE (абсолютная координата) или RELATIVE (относительно предыдущей точки)
Когда плаанировщик приезжает до точки остановки - он встаёт на паузу (например для включения выключения инструмента), после совершения нужных действий вызываем resume() и он продолжает движение. В отличие от предыдущего GPlanner, в GPlanner2 реализован просчёт траектории в буфере и планирование скорости для всех точек, что позволяет системе двигаться быстрее и не тормозить в каждой точке.
- Смотри симуляцию в Processing: папка Planner Simulation/Planner2
РАЗВЕРНУТЬ
GPlanner2<драйвер, количество осей> planner; // объявяление
GPlanner2<драйвер, количество осей, размер буфера> planner; // + размер буфера (по умолч. 32)
void addStepper(uint8_t axis, Stepper &stp); // подключить мотор класса Stepper на ось axis
// примечание: тип драйвера должен совпадать у планировщика и моторов
void setBacklash(uint8_t axis, uint16_t steps); // установить компенсацию люфта на ось axis в количестве шагов steps
void enable(); // включить моторы
void disable(); // выключить моторы
void power(bool v); // переключить питание
// НАСТРОЙКИ
void setMaxSpeed(float nV); // установка максимальной скорости планировщика в шаг/сек
void setAcceleration(uint16_t nA); // установка ускорения планировщика в шаг/сек^2
void setDtA(float newDta); // установить dt смены скорости в повороте, 0.0.. 1.0 по умолч. 0.3
// ПЛАНИРОВЩИК
uint32_t getPeriod(); // возвращает время в мкс до следующего вызова tick/tickManual
void start(); // начать работу
void stop(); // остановить плавно (с заданным ускорением)
void brake(); // резко остановить моторы из любого режима
void resume(); // продолжить после остановки или конечной точки маршрута
void reset(); // сбросить счётчики всех моторов в 0
bool ready(); // флаг достижения точки остановки. После неё нужно вызывать resume
bool available(); // true - в буфере планировщика есть место под новю точку
uint8_t getStatus(); // текущий статус:
// 0 ожидание команды (остановлен)
// 1 ожидание буфера
// 2 в пути
// 3 на паузу
// 4 на стоп
// 5 крутится setSpeed
// СКОРОСТЬ
void setSpeed(uint8_t axis, float speed); // режим постоянного вращения для оси axis со скоростью speed шаг/сек (м.б. отрицателеьной)
// ПОЗИЦИЯ
// добавить новую точку маршрута. Массив координат, флаг окончания и абсолютный/относительный
void addTarget(int32_t tar[], uint8_t l, GS_posType type = ABSOLUTE);
void addTarget(int16_t tar[], uint8_t l, GS_posType type = ABSOLUTE);
// ABSOLUTE - конкретные координаты точки, куда двигаться
// RELATIVE - смещение относительно текущих положений моторов
void setCurrent(int16_t cur[]); // установить текущее положение моторов
void setCurrent(int32_t cur[]); // установить текущее положение моторов
int32_t getCurrent(int axis); // получить текущую позицию по оси axis
int32_t getTarget(int axis); // получить текущую цель в шагах на оси axis
// ТИКЕР
// тикер, вызывать как можно чаще. Вернёт true, если мотор крутится
// здесь делаются шаги для движения по точкам, для вращения по скорости, а также перестройка буфера
bool tick();
// ручной тикер для вызова в прерывании или где то ещё. Выполняется 20..50 us
bool tickManual();
// обработчик буфера. Сам вызывается в tick. Нужно вызывать вручную при работе с tickManual
// вернёт true, если планировщик отправил моторы на новую позицию (в этот момент можно запускать таймер)
void checkBuffer();
// ======= ДЕФАЙНЫ НАСТРОЕК =======
// объявлять перед подключением библиотеки
#define GS_FAST_PROFILE размер_массива (например 10)
Включает быстрый планировщик скорости. Участок разгона/торможения разбивается
на указанное количество отрезков (+8 байт SRAM на участок), на них скорость будет одинаковая.
Это позволяет быстро вычислять скорость мотора и достигнуть 30000 шаг/с на участке разгона
(в обычном режиме в два раза меньше).
Остальные примеры смотри в examples!
// пример с записанным в памяти маршрутом
// смотри график, а лучше запусти stepperPlot
int path[][2] = {
{100, 250},
{160, 30},
{230, 250},
{60, 100},
{270, 100},
};
// количество точек (пусть компилятор сам считает)
// как вес всего массива / (2+2) байта
int nodeAmount = sizeof(path) / 4;
#include "GyverPlanner2.h"
Stepper<STEPPER2WIRE> stepper1(2, 3);
Stepper<STEPPER2WIRE> stepper2(4, 5);
GPlanner2<STEPPER2WIRE, 2> planner;
void setup() {
Serial.begin(115200);
// добавляем шаговики на оси
planner.addStepper(0, stepper1); // ось 0
planner.addStepper(1, stepper2); // ось 1
// устанавливаем ускорение и скорость
planner.setAcceleration(500);
planner.setMaxSpeed(500);
// начальная точка системы должна совпадать с первой точкой маршрута
planner.setCurrent(path[0]);
planner.start();
}
int count = 0; // счётчик точек маршрута
void loop() {
// здесь происходит движение моторов, вызывать как можно чаще
planner.tick();
// если в буфере планировщика есть место
if (planner.available()) {
// добавляем точку маршрута и является ли она точкой остановки (0 - нет)
planner.addTarget(path[count], 0);
if (++count >= sizeof(path) / 4) count = 0; // закольцевать
}
// асинхронно вывожу в порт графики
static uint32_t tmr;
if (millis() - tmr >= 20) {
tmr = millis();
Serial.print(stepper1.pos);
Serial.print(',');
Serial.println(stepper2.pos);
}
}
- v1.1 - добавлена возможность плавного управления скоростью в KEEP_SPEED (см. пример accelDeccelButton)
- v1.2 - добавлена поддержка ESP8266
- v1.3 - изменена логика работы setTarget(, RELATIVE)
- v1.4 - добавлена задержка для STEP, настроить можно дефайном DRIVER_STEP_TIME
- v1.5 - пофикшен баг для плат есп
- v1.6 - Исправлена остановка для STEPPER4WIRE_HALF, скорость можно задавать во float (для медленных скоростей)
- v1.7 - Исправлен баг в отрицательной скорости (спасибо Евгению Солодову)
- v1.8 - Исправлен режим KEEP_SPEED
- v1.9 - Исправлена ошибка с esp функцией max
- v1.10 - повышена точность
- v1.11 - повышена точность задания скорости
- v1.12 - пофикшена плавная работа в KEEP_SPEED. Добавлена поддержка "внешних" драйверов. Убран аргумент SMOOTH из setSpeed
- v1.13 - исправлены мелкие баги, оптимизация
- v1.14 - исправлены ошибки разгона и торможения в KEEP_SPEED
- v1.15 - оптимизация, исправлены мелкие баги, stop() больше не сбрасывает maxSpeed
- v1.15.2 - добавил включение EN если указан, даже при отключенном autoPower
- v2.0 - оптимизация. Ядро шаговика вынесено в отдельный класс Stepper. Добавлены многоосевые планировщики траекторий
- v2.1 - добавил GyverStepper2, упрощённая и оптимизированная версия GyverStepper
- v2.1.1 - исправлена бага в GyverStepper
- v2.1.2 - совместимость Digispark
- v2.1.3 - починил FOLLOW_POS в GStepper, починил RELATIVE в GPlanner2 и исправил багу с рывками
- v2.1.4 - GPlanner2: исправил рывки, добавил адаптивное перестроение траектории без остановок, чутка оптимизировал вычисления
- v2.1.5 - возможность менять скорость и ускорение во время работы планировщика (GStepper2, GPlanner, GPlanner2)
- v2.1.6 - исправлена ошибка компиляции при вызове disable() в GStepper
- v2.1.7 - добавлен clearBuffer() в GPlanner2
- v2.1.8 - оптимизация, исправлен KEEP_SPEED в GStepper
- v2.2.0 - добавлен скоростной профиль GS_FAST_PROFILE для GStepper2, GPlanner, GPlanner2. Поддержка режима "слежения" для GStepper2
- v2.2.1 - небольшая оптимизация SRAM
- v2.3 - fix compiler warnings, поддержка esp32
- v2.4 - повышена плавность движения шаговиков в Planner и Planner2. Исправлена бага в Stepper2
- v2.5 - исправлено плавное изменение скорости для KEEP_SPEED
- v2.6
- disable() в виртуальном режиме отключает сигнал с мотора (для 4-проводных драйверов)
- улучшена производительность для step-dir драйверов
- добавил autoPower() в GStepper2
- исправлен рывок при смене направления в GStepper
- v2.6.1 - поправлена бага в GStepper2
- v2.6.2 - оптимизированы вычисления в GStepper2, GPlanner и GPlanner2
- v2.6.3 - reverse() в step-dir драйвере теперь применяется сразу
- v2.6.4 - исправлен RELATIVE setTarget() в GPlanner #11
- v2.7
- исправлены различные ошибки компиляции
- исправлены некоторые критические баги
- добавлено управление питанием в планировщики
- добавлена компенсация люфта в планировщики
- исправлены баги при нулевом ускорении во всех библиотеках
- исправлена медленная остановка и удар при большом ускорении
- увеличена производительность для esp8266
При нахождении багов создавайте Issue, а лучше сразу пишите на почту alex@alexgyver.ru Библиотека открыта для доработки и ваших Pull Request'ов!
При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
- Версия библиотеки
- Какой используется МК
- Версия SDK (для ESP)
- Версия Arduino IDE
- Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
- Какой код загружался, какая работа от него ожидалась и как он работает в реальности
- В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код