Управление скоростью в шаговом двигателе постоянного тока (двигатель: NEMA 17; драйвер: drv8825) [регулирование частоты]

Я делаю школьный проект, используя несколько шаговых двигателей с драйверами drv8825 (на самом деле это будет мостовой кран) с Arduino UNO. Во-первых, у нас нет огромных денег, которые можно было бы тратить. Теперь проблема заключается в следующем: мы собираемся использовать ПИД-регулятор через гироскоп MPU6050 acc +, который будет контролировать скорость двигателей (нагрузка должна быть как можно более жесткой во время движений), и единственный два способа изменить скорость шагового двигателя:

1) Через метод задержки, например:

for (i = 0; i<400; i++)
{
    digitalWrite(StepPinB, LOW);
    delayMicroseconds(500);
    digitalWrite(StepPinB, HIGH);
    delayMicroseconds(500); 

}

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

2) За счет внешнего регулирования тактовой частоты drv8825, например, с помощью «преобразователя напряжения в частоту» (переменное напряжение может быть задано с помощью «Arduino PWM» + «фильтр нижних частот») или с помощью «нестабильного мультивибратора». («нестабильный генератор») с «цифровым потенциометром» для изменения частоты. Я уже пробовал метод «преобразователя напряжения в частоту», но он не сработал из-за шумов в цепи.

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


person Jacopo    schedule 06.04.2017    source источник


Ответы (2)


вы используете то же время (500 мкс), поэтому приведенный ниже код может вам подойти (с использованием функции arduino millis()):

   unsigned long timerBefore = 0; //global variable
   int inc=0;
   void Temporize(){
      unsigned long timerNow=millis();
      if((unsigned long)(timerNow-timerBefore)>=(500){
         timerBefore=millis();
         inc++;
         if(inc==1)
           digitalWrite(StepPinB, LOW);
         if(inc==2){
           digitalWrite(StepPinB, HIGH);
           inc=0;
         }
     }
 }

тогда вы можете вызвать эту функцию внутри этого for без подчинения вашего микроконтроллера, как ваш код.

person Fabio Henrique Fudoli    schedule 06.04.2017
comment
Спасибо за ваш ответ, теперь я собираюсь предпринять несколько попыток с вашим кодом, чтобы проверить, могу ли я проверить свой датчик, не останавливая двигатель. - person Jacopo; 07.04.2017

Это не конкретный ответ, потому что моя репутация не позволяет мне комментировать. Но у меня есть другое предложение: вы думали о прерывании по таймеру вместо задержек.

#include "TimerOne.h"

long X{1000000};
int volatile altVar{1};

void clockSignal();

void setup(){
  timer.initialize(X);
  timer.attachInterrupt(clockSignal());
}

void loop(){
  readSensor();
}

// Gets called every X cycles;
void clockSignal(){
  if(altVar == 1){
    digitalWrite(stepPinB, LOW);
  }else{
    digitalWrite(stepPinB, HIGH);
  }
  altVar *= -1;
}

Вы получите совершенно бесплатную функцию Loop. Для всего, что вы хотите сделать, есть место и время, и оно прерывается лишь на короткое время, чтобы задать цикл часов.

person H. Puc    schedule 06.04.2017
comment
Это не то, как вы присоединяетесь к прерыванию. Вы просто звоните clockSignal() и прикрепляете void. - person gre_gor; 06.04.2017
comment
@gre_gor Это происходит, когда я пытаюсь внести предложение (опять же, должен быть комментарий под вопросом) и использую первый пример, который я смог найти (немецкий: plays.arduino.cc/Deutsch/). Не стесняйтесь редактировать правильную реализацию. Но в любом случае идея, лежащая в основе этого, может быть полезной. - person H. Puc; 06.04.2017
comment
Спасибо за ваш ответ, теперь я собираюсь предпринять несколько попыток с вашим кодом, чтобы проверить, могу ли я проверить свой датчик, не останавливая двигатель. - person Jacopo; 07.04.2017