Запустить два степпера одновременно

Я пытаюсь запустить два шаговых двигателя одновременно с разными оборотами в минуту. Я решил использовать два поворотных энкодера для изменения оборотов в минуту отдельно.

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

Как я могу генерировать отдельные(разные рабочие циклы) шаговые импульсы для шаговых двигателей? Это главная проблема, с которой я столкнулся.

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

void AH_EasyDriver::setSpeedRPM(long RPM)
{
   float DIV = RPM*this->MOTOR_RESOLUTION;  
    this->STEP_DELAY =  60000000.0L/DIV;
 }

Эта функция вычисляет время шага для заданных конкретных оборотов в минуту

void AH_EasyDriver::move(int NUMBER_OF_STEPS)
{  
   while(STEPS > 0) {
    if (micros() - this->LAST_STEP_TIME >= this->STEP_DELAY) {
      this->LAST_STEP_TIME = micros();
      STEPS--;
      stepMotor();
}
}

}

Эта функция вращает двигатель двигатель в STEP_DELAY с помощью функции stepMotor ().

void AH_EasyDriver::stepMotor()
{
  digitalWrite(this->STEP_pin, HIGH);
  delayMicroseconds(100);
  digitalWrite(this->STEP_pin, LOW);
  delayMicroseconds(100);
}

Эта функция производит постоянные шаговые импульсы.

Я удалил некоторые строки в функции. Это ссылка на исходный файл .cpp. Все библиотеки шагового управления имеют эти функции. Я не мог понять, как эти функции могут изменять обороты в минуту. Кто-нибудь может это объяснить?

, 👍1

Обсуждение

Это сложная задача; если вы хотите увидеть пример скоординированного движения с несколькими двигателями, посмотрите на 3D-принтер с открытым исходным кодом на базе Arduino или прошивку станка с ЧПУ., @Chris Stratton


2 ответа


Лучший ответ:

3

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

Ваша функция move() блокирует выполнение другого кода до тех пор, пока движение не будет завершено. Вы делаете это с помощью цикла while( STEPS > 0 ). Вам нужно изменить свой код, чтобы он не был блокирующим. Обычно это делается так, как показано на примере BlinkWithoutDelay IDE Arduino. Вы тоже используете его: вы должны использовать функцию millis() или micros (), чтобы проверить, пришло ли время сделать шаг.

Замените while оператором if:

if( STEPS > 0 )

и сделайте переменную STEPS переменной - членом экземпляра класса. Затем убедитесь, что вы выполняете функцию достаточно часто, чтобы она не упустила время сделать шаг. Проделайте то же самое со вторым мотором. Например, что-то вроде этого:

void setup(){
  ...
  stepper1.doSteps(100);
  stepper2.doSteps(200);
}

void loop(){
  stepper1.move();
  stepper2.move();
}

Здесь, в функции настройки, степперам предлагается сделать 100 и 200 шагов. (Вам придется написать функцию doSteps(int number_of_steps) самостоятельно). Затем движение выполняется функциями move (), когда приходит время это сделать. Поскольку эти две функции зацикливаются очень быстро, они не должны упускать время для шага.

Именно так работает библиотека AccelStepper, которая также является обычной шаговой библиотекой.

,

В то время как ширина шагового импульса может не иметь значения в определенных пределах, время между импульсами чрезвычайно важно и не тривиально для нескольких двигателей. Похоже, вы не объясняете жизнеспособный механизм для достижения этой цели., @Chris Stratton

Я не совсем понимаю, что вы имеете в виду. В моем понимании водитель идет на один шаг, когда считает один импульс. Вы делаете импульсы медленной или более быстрой серией, в зависимости от того, как быстро должен работать степпер. Конечно, это не метод высокой скорости/высокой точности, но способ, которым вы можете пойти, если обстоятельства не слишком сложны. Может быть, я что-то неправильно понял, как работает драйвер. Пожалуйста, поправьте меня. Затем я могу отредактировать или удалить свой ответ, если он неверен, @chrisl

В реальном мире часто необходимо совершать скоординированные движения между двумя двигателями, например, представить себе круг по осям X и Y., @Chris Stratton

Для выполнения такого движения вам придется модулировать скорость двигателей (по существу, делая время между импульсами зависящим от функции). Но ОП использовал его более простым способом. Я думаю, что более сложная функциональность рисования кругов или чего-либо еще выходит за рамки этого вопроса., @chrisl

Хотя это также можно сделать с помощью моего метода, изменяя скорость двигателей во время движения. Но используемые функции этой библиотеки не годятся для этого, я думаю, @chrisl


2

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

  1. Держите одну переменную счетчика на двигатель
  2. Увеличьте каждую переменную счетчика на заданную величину в фиксированном временном цикле
  3. Когда переменная счетчика достигает порогового значения, генерируется очень короткий шаговый импульс
  4. При достижении порогового значения вычтите пороговое значение из соответствующего счетчика

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

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

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

,