AccelStepper stop(). Аварийная остановка шагового двигателя по концевику.

Для управления шаговыми двигателями из Arduino я использую библиотеку AccelStepper.
Она неплоха, позволяет делать плавный контролируемый разгон и торможение. И само движение шаговика мягкое и плавное. Минимум кода.
Через неё можно управлять принципиально разными драйверами шаговых двигателей a4988 и 28byj-48. Причём программный код управления единообразен.

Код для 28BYJ-48 например:

 #define HALFSTEP 7   

// Определение пинов для управления двигателем
#define motorPin1 8 // IN1 на 1-м драйвере ULN2003
#define motorPin2 9 // IN2 на 1-м драйвере ULN2003
#define motorPin3 10 // IN3 на 1-м драйвере ULN2003
#define motorPin4 11 // IN4 на 1-м драйвере ULN2003

// Инициализируемся с последовательностью выводов IN1-IN3-IN2-IN4
// для использования AccelStepper с 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

void setup(){
// Задаём максимальную скорость двигателя
stepper1.setMaxSpeed(1000.0);
// Задаём ускорение двигателя
stepper1.setAcceleration(100.0);
// Установим скорость в шагах за секунду
stepper1.setSpeed(200);
// Перемещаем в абсолютно указанное положение
stepper1.moveTo(360);
}

void loop(){
// Изменяем направление, если шаговик достигает заданного положения
if(stepper1.distanceToGo()==0)
stepper1.moveTo(-stepper1.currentPosition());
stepper1.run();
}

Но была у AccelStepper одна проблема - он не останавливал двигатель по концевику, не позволял сделать аварийное торможение.
Если вызвать функцию stop() но двигатель в общем-то тормозит. Но не сразу и не всегда. В итоге каретка бьётся о концевик, грозя сломать конструкцию.
После долгого поиска и проб я отчаялся найти готовое решение и полез в исходники данной библиотеки.
Смотрим файл AccelStepper.cpp.

 void AccelStepper::stop()
{
if (_speed != 0.0)
{
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
if (_speed > 0)
move(stepsToStop);
else
move(-stepsToStop);
}
}

Что мы видим? Именно то, о чём речь. Двигатель тормозит не сразу, а рассчитывает тормозной путь и как бы переопределяет себе конечную точку.

И первый важный вывод, следующий - обратите внимание на скорость, которую установили. Есть вероятность, что вы её превысили. Двигатель будет при этом перемещаться нормально, но в переменной скорости количество шагов в секунду будет как бы с запасом, превысить её будет не позволять такт работы самой Arduino.

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

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

 void AccelStepper::quickstop()
{
_speed=0;
move(0);
}

В такой реализации торможение происходит сразу, мгновенно. Собственно на этом тему можно закрывать, проблема решена.
Вы можете поправить те исходники которые у вас есть добавив:

в AccelStepper.cpp

void AccelStepper::quickstop()
{
_speed=0;
move(0);
}

В AccelStepper.h

void quickstop();

в keywords.txt

quickstop KEYWORD2

Вот мой коммит на гитхабе

Или можете целиком скачать библиотеку моей версии: https://github.com/synxronica/AccelStepper.git
Директория с исходниками библиотеки должна как вы знаете помещаться в Документы -> Arduino -> Lib, после чего среду разработки нужно перезапустить.

В коде своей программы в нужном месте вместо:

stepper1.stop()

нужно будет вызвать:

stepper1.quickstop()


Уведомлять о статьях
  Автор: administrator
Комментариев к статье пока нет
Яндекс.Метрика admin@synxronica.com