Шаговый двигатель.

inlag
Offline
Зарегистрирован: 12.02.2016

Всем привет, я новичок еще учусь программировать, возникла проблема с написанием скетча под шаговый двигатель, вроде с функциями разобрался, а как правильно написать не понимаю, буду очень благодарен если кто нибудь напишет пример скетча на один шаговый двигатель через STEP/DIR/ENABLE.

vvadim
Offline
Зарегистрирован: 23.05.2012

устанавливаете библиотеку AccelStepper и в ней куча примеров

satelit
Offline
Зарегистрирован: 12.12.2015

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

MacSim
Offline
Зарегистрирован: 28.11.2012

inlag пишет:

Всем привет, я новичок еще учусь программировать, возникла проблема с написанием скетча под шаговый двигатель, вроде с функциями разобрался, а как правильно написать не понимаю, буду очень благодарен если кто нибудь напишет пример скетча на один шаговый двигатель через STEP/DIR/ENABLE.

выставляете на нагу направление

дергаете степом с двумя паузами. 1 пауза после включения, 2 после выключения.

длительность паузы меняете, меняется скорость вращения. с 2 паузой в 1,4* первой получается лучше.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
#define ENA_PIN       10    // пин для подключения к контакту ENABLE у драйвера
#define DIR_PIN       4     // пин для подключения к контакту DIR у драйвера
#define STEP_PIN      6     // пин для подключения к контакту STEP у драйвера
#define STOP_BUTTON   8     // пин для кнопки аварийной остановки (кнопку на пин и на GND)
#define SPEED_1       16    // пауза между шагами, мкс (меньше = выше скорость, но слабее тяга)

// определем синонимы для большей наглядности
#define ENABLE        LOW
#define DISABLE       HIGH
#define CLOCKWISE     HIGH
#define ANTICLOCKWISE LOW

unsigned long steps = 0;    // переменная для хранения количества шагов


void setup() 
{
  pinMode(ENA_PIN, OUTPUT);           // инициализируем пины как выход
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(STOP_BUTTON, INPUT_PULLUP); // инициализируем пин как вход с внутренней подтяжкой
  motor(DISABLE);                     // запрещаем драйверу управление ШД
}


void loop () 
{ 
  motor(ENABLE);                      // разрешаем драйверу управление ШД

  // делаем 1 шаг по часовой
  motorOneStep(CLOCKWISE);       
  delay(3000);

  // делаем 1 шаг против часовой  
  motorOneStep(ANTICLOCKWISE); 
  delay(3000);

  // делаем 1 оборот (200 шагов) по часовой
  motorMove(200);   
  delay(3000);

  // делаем 1 оборот (200 шагов) против часовой
  motorMove(-200);
  delay(3000);

  // крутим 500 шагов по часовой, параллельно делая что-то еще
  steps = 0;
  while (steps < 500)
  {
    motorOneStep(ANTICLOCKWISE);
    if(!digitalRead(STOP_BUTTON))      // если нажали кнопку остановки
    {
      motor(DISABLE);                  // запрещаем драйверу управление ШД
      digitalWrite(LED_BUILTIN, HIGH); // врубаем аварийный LED
      break;                           // вылетаем преждевременно
    }
    steps++;
  }
  motor(DISABLE);                      // запрещаем драйверу управление ШД

  delay(30000);
} //void loop


void motorMove(long stepsLimit)        // делаем N шагов в заданном направлении
{
  boolean dir = stepsLimit > 0 ? CLOCKWISE : ANTICLOCKWISE;
  for (unsigned long n = 0; n < stepsLimit; n++) motorOneStep(dir);
}


void motorOneStep(boolean dir)         // делаем один шаг в заданном направлении
{ 
  digitalWrite(DIR_PIN, dir);          // задаем направление вращения
  digitalWrite(STEP_PIN, HIGH);        // даем импульс на один шаг
  delayMicroseconds(SPEED_1);          // пауза
  digitalWrite(STEP_PIN, LOW);
}


void motor(boolean state)              // разрешаем/запрещаем драйверу управление ШД  
{
  digitalWrite(ENA_PIN, state);
}

 

paf
Offline
Зарегистрирован: 25.01.2013

Tomasina, я правильно понял, скетч должен работать, собственно комментарии в Loop и описывают работу.

Однако у меня это происходит иначе.

По шагу туда-сюда.

По часовой 200

И безостановочно против часовой... на кнопку не реагирует.

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

у меня все работает. Кнопка как подключена?

paf
Offline
Зарегистрирован: 25.01.2013

Кнопка на землю?   И у меня двиг28BYJ-48 в биполярном включении SPEED1 пришлось выставить 4096, но это лишь на скорость вращения влияет.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Выкидываем все лишее. Если этот код не работает, значит проблемы с подключением кнопки.

#define STOP_BUTTON   8     // пин для кнопки аварийной остановки (кнопку на пин и на GND)
void setup() 
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(STOP_BUTTON, INPUT_PULLUP); // инициализируем пин как вход с внутренней подтяжкой
}

void loop () 
{ 
  if(!digitalRead(STOP_BUTTON))      // если нажали кнопку остановки
  {
    Serial.println("Button pressed!");
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else digitalWrite(LED_BUILTIN, LOW);
  
  delay(100);
} //void loop

 

paf
Offline
Зарегистрирован: 25.01.2013

Пока кнопку держу повторяется "баттон прессед"...

И горит лед... В том скетче  тоже лед должен гореть? 

....Чудеса .... может IDE виновата?  1.0.2

Да вообще, чудеса! 

Убрал минус. Два раза по часовой. И откуда-то взялось еще против... Дальше по кругу через длинную паузу. Кнопка не работает...

Так, это на цикле третий поворот... против часовой.

Понял. Кнопку жать вовремя третьего поворота. Но что же с минусом?

Минус вызывает бесконечный поворот. Вот.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

ага, ошибочка с отрицательным числом вылезла ;)

В строке 69 надо так:

for (unsigned long n = 0; n < abs(stepsLimit); n++) motorOneStep(dir);

Вот правильный вариант:

#define ENA_PIN       10    // пин для подключения к контакту ENABLE у драйвера
#define DIR_PIN       4     // пин для подключения к контакту DIR у драйвера
#define STEP_PIN      6     // пин для подключения к контакту STEP у драйвера
#define STOP_BUTTON   8     // пин для кнопки аварийной остановки (одним контактом на пин, другим на GND)
#define SPEED_1       16    // пауза между шагами, мкс (чем меньше, тем выше скорость, но слабее тяга)

// определем синонимы для большей наглядности
#define ENABLE        LOW
#define DISABLE       HIGH
#define CLOCKWISE     HIGH
#define ANTICLOCKWISE LOW

unsigned long steps = 0;    // переменная для хранения количества шагов


void setup() 
{
  pinMode(ENA_PIN, OUTPUT);           // инициализируем пины как выход
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(STOP_BUTTON, INPUT_PULLUP); // инициализируем пин как вход с внутренней подтяжкой
  motor(DISABLE);                     // запрещаем драйверу управление ШД
}


void loop () 
{ 
  motor(ENABLE);                      // разрешаем драйверу управление ШД

  // делаем 1 шаг по часовой
  Serial.print("One step CLOCKWISE... ");
  motorOneStep(CLOCKWISE);      
  Serial.println("Done."); 
  motor(DISABLE);                     // отключаем мотор, чтобы не грелся
  delay(3000);

  // делаем 1 шаг против часовой  
  Serial.print("One step ANTICLOCKWISE... ");
  motorOneStep(ANTICLOCKWISE); 
  Serial.println("Done.");
  motor(DISABLE);
  delay(3000);

  // делаем 1 оборот (200 шагов) по часовой
  Serial.print("200 steps CLOCKWISE... ");
  motorMove(200);  
  Serial.println("Done."); 
  motor(DISABLE);
  delay(3000);

  // делаем 1 оборот (200 шагов) против часовой
  Serial.print("200 steps ANTICLOCKWISE... ");
  motorMove(-200);
  Serial.println("Done.");
  motor(DISABLE);
  delay(3000);

  // крутим 500 шагов по часовой, параллельно делая что-то еще
  Serial.print("500 steps ANTICLOCKWISE or press button... ");
  steps = 0;
  Serial.println(steps);
  while (steps < 500)
  {
    motorOneStep(ANTICLOCKWISE);
  Serial.println(steps);
    if(!digitalRead(STOP_BUTTON))      // если нажали кнопку остановки
    {
      motor(DISABLE);                  // запрещаем драйверу управление ШД
      digitalWrite(LED_BUILTIN, HIGH); // врубаем аварийный LED
      Serial.print("STOP button pressed!");
      break;                           // вылетаем преждевременно
    }
    steps++;
  }
  Serial.println("Done.");
  motor(DISABLE);                      // запрещаем драйверу управление ШД
  delay(30000);
} //void loop


void motorMove(long stepsLimit)        // делаем N шагов в заданном направлении
{
  boolean dir = stepsLimit > 0 ? CLOCKWISE : ANTICLOCKWISE;
  for (unsigned long n = 0; n < stepsLimit; n++) motorOneStep(dir);
}


void motorOneStep(boolean dir)         // делаем один шаг в заданном направлении
{ 
  digitalWrite(DIR_PIN, dir);          // задаем направление вращения
  digitalWrite(STEP_PIN, HIGH);        // даем импульс на один шаг
  delayMicroseconds(SPEED_1);          // пауза
  digitalWrite(STEP_PIN, LOW);
}


void motor(boolean state)              // разрешаем/запрещаем драйверу управление ШД  
{
  digitalWrite(ENA_PIN, state);
}

 

tw911
Offline
Зарегистрирован: 22.10.2013

satelit пишет:

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

Там обычно не шаговые двигатели. Или только те, которые лазер двигают.

paf
Offline
Зарегистрирован: 25.01.2013

Ок! Спасибо... Будем изучать, мыслить... Прорабатывать.

Кх-хм... Шудеса!!! 

Tomasina, это точно должно работать?! 

Serial.begin(9600); // бы в секцию сетап добавить... все ж как-то лучшее былоб, но я не настаиваю! 

ukr109
Offline
Зарегистрирован: 25.02.2016

Добрый вечер. У меня вопрос.

Есть большой шаговый двигатель ,(вродеSY110STH99-5504A) драйвер к нему CW-5045, Arduino UNO. Задача чтобы от одной кнопки вращался в одну сторону от второй в другую.

Когда я ставлю "i" больше 30000 у меня цикл становиться бесконечным(проезжает мимо). Это ардуине памяти не хватает? Попробовал скопировать внутри цикла ещё пару раз не меняя "i" - работает. Ардуина МЕГА решит мою проблему? Нужно, чтоб цикл повторялся не 30К, а ~600К до 1M раз

int switchL = 2; 
int switchR = 3;
int pull = 4;
int dir = 5;

void setup() 
{
  pinMode(switchR, INPUT);
  pinMode(switchL, INPUT);
  pinMode(pull, OUTPUT);
  pinMode(dir, OUTPUT);
  digitalWrite(pull, LOW);
  digitalWrite(dir,LOW);
}

void loop()
{
    if (digitalRead(switchR) == HIGH)
  {
    digitalWrite(dir, HIGH);
   for (int i=0; i<=30000; i++)
    {
     digitalWrite(pull, HIGH);
     delayMicroseconds(60);
     digitalWrite(pull, LOW);
     delayMicroseconds(60); 
         
    }
   }
   else if (digitalRead(switchL) == HIGH)
{
    digitalWrite(dir, LOW);
    for (int i=0; i<=30000; i++)
    {
     digitalWrite(pull, HIGH);
     delayMicroseconds(60);
     digitalWrite(pull, LOW);
     delayMicroseconds(60); 
       
    }
    
}
else
{
   
}
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

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

При i > 30000 работать будет корректно, при i > 32767 будет зацикливаться. Вот причина.