Низкая скорость с шаговым двигателем

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

Сервопривод питается от Arduino, а шаговый двигатель питается от 12-вольтовой вилки. Я просто не уверен, что в этом коде есть что-то, что замедляет его работу? Спасибо за ваше время! Код, из-за которого он работает медленно, находится здесь:

#include <Servo.h>

Servo myservo;

// Настраиваемые переменные
int MaxServoTurn = 20;

// Жуткие переменные
int pos = 0;
int customDelay;
int customDelayMapped;
const int pin_LED = 10;
const int pin_switch = 8;
const int stepPin = 3;
const int dirPin = 4;
boolean oldSwitchState = LOW;
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;
unsigned long timeNow = 0;
unsigned long timePrev = 0;
unsigned int timeWait = 100;
boolean flashingLEDisON = false;
boolean LEDstatus = LOW;
boolean keyPressed = false;
boolean buttonToggle = false;


// Только настройка, вызов функций здесь
void setup() {
  myservo.attach(9);
  // Устанавливает два вывода в качестве выходов
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  //Позволяет двигателю двигаться в определенном направлении
  digitalWrite(dirPin, HIGH);
  pinMode(pin_LED, OUTPUT);
  digitalWrite(pin_LED, LOW);
  pinMode(pin_switch, INPUT);
}

// Это главный контроллер для приложения
void loop() {
  for (pos = 0; pos <= MaxServoTurn; pos += 1) {
    buttonLoop();
    if (buttonToggle == true) {
      myservo.write(pos);
      setupPotentiometer();
    }
  }
  for (pos = MaxServoTurn; pos >= 0; pos -= 1) {
    buttonLoop();
    if (buttonToggle == true) {
      myservo.write(pos);
      setupPotentiometer();
    }
  }
}

void buttonLoop() {
  newSwitchState1 = digitalRead(pin_switch);
  newSwitchState2 = digitalRead(pin_switch);

  newSwitchState3 = digitalRead(pin_switch);

  if (  (newSwitchState1 == newSwitchState2) && (newSwitchState1 == newSwitchState3) )
  {
    if ( newSwitchState1 != oldSwitchState )
    {
      if ( newSwitchState1 == HIGH ) {
        keyPressed = true;
        buttonToggle = true;
      } else {
        keyPressed =  false;
        buttonToggle = false;
      }
      oldSwitchState = newSwitchState1;
    }
  }


  if ( keyPressed )
  {
    // включить или выключить мигающий светодиод
    if ( flashingLEDisON == false)
    {
      flashingLEDisON = true;
    }
    else
    {
      flashingLEDisON = false;
      // светодиод может быть включен, поэтому на всякий случай мы его выключаем. Если вы хотите, вы можете проверить LEDstatus
      LEDstatus = LOW;  digitalWrite(pin_LED, LEDstatus);
    }
    keyPressed = false;
  }

  // если горит мигающий светодиод. Посмотрите, не пора ли мигнуть
  if ( flashingLEDisON == true )
  {
    timeNow = millis();
    if (timeNow - timePrev >= timeWait )
    {
      timePrev = timeNow;
      if (LEDstatus == LOW) {
        LEDstatus = HIGH;
      } else {
        LEDstatus = LOW;
      }
      digitalWrite(pin_LED, LEDstatus);
    }
  }
}

void setupPotentiometer() {
  customDelayMapped = speedUp(); // Получает пользовательские значения задержки из пользовательской функции speedUp
  // Делает импульсы с пользовательской задержкой, в зависимости от потенциометра, от которого зависит скорость двигателя
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(customDelayMapped);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(customDelayMapped);
}

// Функция для чтения потенциометра
int speedUp() {
  int customDelay = analogRead(A0); // считывает потенциометр
  int newCustom = map(customDelay, 0, 1023, 300, 4000); // Преобразует считанные значения потенциометра от 0 до 1023 в желаемые значения задержки (от 300 до 4000)
  return newCustom;
}

, 👍0


2 ответа


0

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

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

,

Спасибо за ваш ответ, Дункан, мне просто изменить два delayMicroseconds (customDelayMapped); на millis(), как вы упомянули? Я новичок в ардуино, поэтому извините, если я что-то не так понял!, @John

нет, вам нужно реорганизовать свой код, чтобы отслеживать прошедшее время и изменять состояния, когда прошел желаемый интервал времени. Выполните поиск «Arduino Blink Without Delay» и изучите найденные скетчи. Это будет не копирование/вставка изменений, а скорее рефакторинг вашего кода. Возможно, вы сможете найти пример кода для шаговых двигателей и сервоприводов, который не использует задержки, что облегчит вашу работу., @Duncan C


1

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

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

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

Степпер будет перемещать только «количество шагов» за раз для каждого запуска кода. Я столкнулся с аналогичной проблемой, и мне пришлось ввести задержку в 2 мс после команды запуска сервопривода, чтобы двигатели работали более плавно и быстрее, в противном случае это звучало как скрежет и пропуск шестерен. Эти степперы были обращены друг к другу, поэтому они двигались в противоположных направлениях.

if (down==true){
  TLstep.step(-step1);
  TRstep.step(step1);
  delay(2);
}

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

,