Интернет-лаборатория роботов ZiZiBOT.RU

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

г. Юрга,
ул.Ленинградская 38/83

+7 923-503-6074

Вам не нравятся шаговые моторы, да вы просто не умеете их готовить

  1. Начало изучения
  2. Первая тестовая программа - равномерное вращение
  3. Вторая тестовая программа - разгон
  4. Третья тестовая программа - подбор стартового шага
  5. Четвертая тестовая программа - подбор минимального шага
  6. Пятая тестовая программа - минимальный шаг и торможение
  7. Шестая тестовая программа - равноускоренное движение
  8. Ссылка для скачивания: Программы и схемы для тестов

 

шаговик шаговик шаговик

В рамках проекта "Балансирующий робот" я, с целью изучения возможности использования в качестве ходовых, приобрел пару шаговых двигателей 35HM-0304A4. Планируется использовать их напрямую - без редукторов на колесных осях, что конечно накладывает на двигатели определенные ограничения.

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

Из документации при покупке ясно было только два факта: двигатель имеет активное сопротивление обмотки ~26 Ом; шаг двитателя 0.9 градуса. Все остальное требовалось выяснить.

На вал двигателя уже запрессована зубчатая шестерня, мне достался экземпляр с 15 зубами. С боков имеются очень удобные ушки, для крепления к корпусу балансирующего робота, это  удачная находка, я уже использовал их в 3D модели нового робота. Масса мотора около 100 гр.

Измеренные значения составили: индуктивность ~0.9мГн, активное сопротивление ~25 Ом. Индуктивность двигателя невелика, что возможно позволит довольно значительно его разгонять.

drv8825 drv8825

Управлять шаговиком я буду при помощи хорошо зарекомендовавшего себя драйвера DRV8825 на плате китайского производства. Особенностью данного драйвера является поддержка тока до 2,5A, при этом до 1.5A даже не требуется радиатор (в схеме драйвера используются полевые транзисторы).

 

При использовании платы изображенной ниже, максимальный ток регулируется при помощи подстроечного резистора. Головка вращения резистора металлическая и находится под напряжением (0-1.5V), измерив данное напряжение при помощи мультиметра (Головка резистора - GND) и умножив полученное значение на два, получаем максимальный ток фазы двигателя, т.е. драйвер ограничит ток каждой фазы нашего двигателя именно этим значением.

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

drv8825Повышающий импульсный преобразовательArduino nano

 Я применю китайский клон платы Arduino nANO, но не обычный клон, а довольно качественный и брутальный от robotdyn.com. Его особенность в том, что подключается он по кабелю microUSB, а не mini, как подобные. Других отличий, кроме качества изготовления платы, нет.

 

Для работы драйвера DRV8825 требуеться напряжение от 8.5 до 35 вольт, но два литиевых аккумулятора 18650, подключенные последовательно, не всегда могут обеспечить столь высокое напряжение, поэтому логично с моей стороны было применить повышающий импульсный стабилизатор. Он и повысит напряжение и стабилизирует его на заданном уровне.

Такой стабилизатор стоит недорого, и  поддеживает до 3А ток. Благодаря своей импульсной природе он слабо греется и имеет хороший до 98% коэффициент полезнго действия (КПД).

В данном экземпляре используется микросхема XL6009.

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

Шаговик питание Шаговик питание Шаговик управление Шаговик управление

Схема, которую я собрал, изображена ниже. Так как запитываю всю схему от одного источника питания, соединять земли Arduino и DRV8825 не пришлось, но если источники питания разные, то следует соединить GND Arduino и GND DRV8825 отдельным проводником. На питание моторов установлен дополнительный конденсатор, его я поставил по практическим рекомендациям.

Также стоит отметить наличие диода Шоттки на положительном входе питания Arduino NANO, наличие диода защищает схему от провисания питания контроллера Arduino, когда он запитан от USB, а основная схема обесточена.

Для управления используется три сигнала: ENABLE, STEP и DIR. Они подключены к пинам D4, D3, D2 контроллера Arduino. Далее я приведу несколько программы, которые я использовал при тестировании. Пойдем от простого к сложному.

Пример test_step1 позволяет запустить мотор, он будет делать 4 оборота в одну, затем в другую сторону. Программа состоит из 2-х файлов test_step1.ino и step_motor1.h, оба должны быть расположены в каталоге test_step1.

Движение происходит равномерно, без ускорения как отрицательного так и положительного.

test_step1.ino основной файл, а step_motor1.h содержит функции по работе с шаговым мотором и константы описывающие шаговый двигатель (управление и скорость).

Файл "test_step1.ino"

 

#include "step_motor1.h"
void setup() 
{
  // put your setup code here, to run once:
  setup_step_motor();
}

void loop() 
{
  //Активирую мотор на драйвере
  digitalWrite(EN, 0);
  // Жду окончания активации
  delay(1);
  //Делаю 1600/400 = 4 оборота , у меня мотор с шагом 0.9 гр.
  to_left_steps(1600);
  //  digitalWrite(EN, 1); // Отключение мотора на драйвере
  delay(1000); //Ждем секунду
  //Активирую мотор на драйвере
  //digitalWrite(EN, 0);
  // Жду окончания активации
  delay(1);
  //Делаю 1600/400 = 4 оборота , у меня мотор с шагом 0.9 гр.
  to_right_steps(1600);
  delay(1);
  //digitalWrite(EN, 1);
  delay(1000);
}

Файл "step_motor1.h"

// Задаю пины для управления драйвером
#define EN 4
#define DIR 2
#define STEP 3
//Скоростные характеристики мотора
#define SPEED 1000 // Время на шаг, чем меньше тем быстрее, но возможны пропуски
#define SPEED_OFF 100 // Время МЕЖДУ шагАМИ, чем меньше тем быстрее, но возможны пропуски
//Условоное направление вращения, будет использоваться для сигнала DIR
#define DIR_TO_LEFT false //направление вращения, чтобы не рыться
#define DIR_TO_RIGHT true

//Здесь храниться текущее направление вращения
bool DIR_DATA;

//Инициализация драйвера
void setup_step_motor()
{
  pinMode(EN, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(EN, 1); // Пока отключен
  digitalWrite(STEP, 0);
  digitalWrite(DIR, DIR_TO_LEFT);
}

// Шагаем влево
bool to_left_steps(int steps)
{
  int a;
  a = 0;
  //digitalWrite(EN, 0);
  DIR_DATA = DIR_TO_LEFT;
  digitalWrite(DIR, DIR_DATA); //вправо
  //delay(500);
  a = 0;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    //delay(SPEED);
    delayMicroseconds(SPEED);
    digitalWrite(STEP, 1);
    delayMicroseconds(SPEED_OFF);
    a++;
  }
  //digitalWrite(STEP, 0);
  // delayMicroseconds(SPEED);
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

// Шагаем вправо
bool to_right_steps(int steps)
{
  //digitalWrite(EN, 0);
  DIR_DATA = DIR_TO_RIGHT;
  digitalWrite(DIR, DIR_DATA); //вправо
  //delay(500);
  int a;
  a = 0;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    //delay(SPEED);
    delayMicroseconds(SPEED);
    digitalWrite(STEP, 1);
    delayMicroseconds(SPEED_OFF);

    a++;
  }
  //digitalWrite(STEP, 0);
  // delayMicroseconds(SPEED);
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

Пример test_step2 позволяет запустить мотор, он будет делать 40 оборота в одну, затем в другую сторону. Программа состоит из 2-х файлов test_step2.ino и step_motor2.h, оба должны быть расположены в каталоге test_step2.

В программе реализован разгон двигателя, но ускорение не постоянное. Торможение снижением скорости не реализовано.

Отличие от test_step1 в том, что двигатель разгоняется до определенной максимальной скорости постепенно, при остановке мотор обесточивается, что позволяет свободно вращать вал.

Файл "test_step2.ino"

#include "step_motor2.h"
void setup() {
  // put your setup code here, to run once:
  setup_step_motor();
}
void loop() {
  digitalWrite(EN, 0);
  delay(5);
  to_left_steps(16000);
 delay(5);
  digitalWrite(EN, 1);
  delay(1000);
  digitalWrite(EN, 0);
  delay(5);
  to_right_steps(16000);
  delay(5);
  digitalWrite(EN, 1);
  delay(1000);
}

Файл "step_motor2.h"

#define EN 4 // Пин Arduino На пин драйвера включение - удержание
#define DIR 2 // Пин Arduino На пин драйвера - направление вращения
#define STEP 3 // Пин Arduino На пин драйвера - управления шагами
#define START_STEP_TIME 1500 // Время шага от нуля - толчковый шаг, самый длинный по времени, определяется экспериментально, мотор не должен делать пропуски
#define MIN_STEP_TIME 600 // Время на шаг, для уже разогнааного мотора, чем меньше тем быстрее, но возможны пропуски
#define ACCELERATION_STEP 1 // Уменьшение времени каждого последующего шага, до минимального времени
#define ACCELERATION_ZERRO_STEP 5 // Увеличение времени каждого последующего шага, до остановки
#define STEP_OFF 100 // Время МЕЖДУ шагАМИ, чем меньше тем быстрее, но возможны пропуски, определяется экспериментально
#define DIR_TO_LEFT false //направление вращения - 
#define DIR_TO_RIGHT true //направление вращения - 

bool DIR_DATA;
unsigned int a;

void setup_step_motor()
{
  pinMode(EN, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(EN, 1); // Пока отключен
  digitalWrite(STEP, 0);
  digitalWrite(DIR,DIR_TO_LEFT);
}

//вращается влево на указанное количество шагов
bool to_left_steps(unsigned int steps)
{
  long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_LEFT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
  steplong=START_STEP_TIME;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if(steplong>MIN_STEP_TIME) steplong-=ACCELERATION_STEP;
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

bool to_right_steps(unsigned int steps)
{
    long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_RIGHT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
   steplong=START_STEP_TIME;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if(steplong>MIN_STEP_TIME) steplong-=ACCELERATION_STEP;
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

 

Пример test_step3 позволяет управлять величиной начального шага мотора. Программа состоит из 2-х файлов test_step3.ino и step_motor3.h, оба должны быть расположены в каталоге test_step3.

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

Следует подключить контроллер arduino к компьютеру, загрузить программу, открыть монитор порта, установить в мониторе порта скорость 115200, в верхней строке для ввода данных ввести число и нажать ввод, это число будет воспринято программой как величина начального шага. Программа сделает попытку запустить шаговый двигатель, но если стартовый шаг слишком мал, запук будет неудачным, двигатель загудит и несдвинется. Следует подобрать стартовый шаг, при котором двигатель гарантировано стартует. Далее он может ускоряться.

Плавное торможение в программе не реализовано.

Файл "test_step3.ino"


#include "step_motor3.h"
char chislo[10];
void setup() {
  setup_step_motor(); //Инициализирую шаговый мотор
  Serial.begin(115200);
}
void loop() 
{
  int index;
  char b;
  delay(100);
  for(index= 0;index<7;index++)
  chislo[index] = '�';
  index = 0;
  while(!Serial.available()) delay(100); //Жду появления данных на серийном порту.
while(Serial.available()) //Принимаю число 
{
  b = Serial.read();
  if((b=='1')||(b=='2')||(b=='3')||(b=='4')||(b=='5')||(b=='6')||(b=='7')||(b=='8')||(b=='9')||(b=='0'))
  {
    if(index<6)
    {
      chislo[index] =  b;
      index++;
    }
  }
  delay(10);
}
   START_STEP_TIME = atoi(&chislo[0]); //Из строки в число 
  digitalWrite(EN, 0); //Включаю мотор
  delay(1); // Жду пока произойдет включение
  to_left_steps(1600); //Вращаю четыре оборота //у меня мотор 0.9 градуса на шаг - 400 шагов на оборот.
  delay(1000); //Ротор зафиксирован
  digitalWrite(EN, 1); // Отключаю мотор
}

Файл "step_motor3.h"


#define EN 4 // Пин Arduino На пин драйвера включение - удержание
#define DIR 2 // Пин Arduino На пин драйвера - направление вращения
#define STEP 3 // Пин Arduino На пин драйвера - управления шагами
//#define START_STEP_TIME 1500L // Время шага от нуля - толчковый шаг, самый длинный по времени, определяется экспериментально, мотор не должен делать пропуски
#define MIN_STEP_TIME 600L // Время на шаг, для уже разогнааного мотора, чем меньше тем быстрее, но возможны пропуски
#define ACCELERATION_STEP 1 // Уменьшение времени каждого последующего шага, до минимального времени
#define ACCELERATION_ZERRO_STEP 5 // Увеличение времени каждого последующего шага, до остановки
#define STEP_OFF 100L // Время МЕЖДУ шагАМИ, чем меньше тем быстрее, но возможны пропуски, определяется экспериментально
#define DIR_TO_LEFT false //направление вращения - 
#define DIR_TO_RIGHT true //направление вращения - 

bool DIR_DATA;
unsigned int a;
long START_STEP_TIME; // Время шага от нуля - толчковый шаг, самый длинный по времени, определяется экспериментально, мотор не должен делать пропуски
void setup_step_motor()
{
  pinMode(EN, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(EN, 1); // Пока отключен
  digitalWrite(STEP, 0);
  digitalWrite(DIR,DIR_TO_LEFT);
}

//вращается влево на указанное количество шагов
bool to_left_steps(unsigned int steps)
{
  long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_LEFT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
  steplong=START_STEP_TIME;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if(steplong>MIN_STEP_TIME) steplong-=ACCELERATION_STEP;
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}


bool to_right_steps(unsigned int steps)
{
    long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_RIGHT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
   steplong=START_STEP_TIME;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if(steplong>MIN_STEP_TIME) steplong-=ACCELERATION_STEP;
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

 

Пример test_step4 позволяет управлять величиной минимального шага мотора, т.е. фактически регулировать максимальный разгон. Программа состоит из 2-х файлов test_step4.ino и step_motor4.h, оба должны быть расположены в каталоге test_step4.

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

Следует подключить контроллер arduino к компьютеру, загрузить программу, открыть монитор порта, установить в мониторе порта скорость 115200, в верхней строке для ввода данных ввести число и нажать ввод, это число будет воспринято программой как величина минимального шага. Программа запустит двигатель с величины шага 1500 микросек. (меняется в #define START_STEP_TIME 1500L), а затем начнет пытаться наростить скорость до введенного значения, если двигатель не застопориться, значит исследуемая скорость подходит, в противном случае шаг стоит увеличить и попробовать вновью.

Плавное торможение в программе не реализовано, по этой причине двигатель может делать лишние шаги при торможении.

Файл "test_step4.ino"


#include "step_motor4.h"
char chislo[10];
void setup() {
  setup_step_motor(); //Инициализирую шаговый мотор
  Serial.begin(115200);
}
void loop() 
{
  int index;
  char b;
  delay(100);
  
  for(index= 0;index<7;index++)
  chislo[index] = '�';
  index = 0;
  while(!Serial.available()) delay(100); //Жду появления данных на серийном порту.
while(Serial.available()) //Принимаю число 
{
  b = Serial.read();
  if((b=='1')||(b=='2')||(b=='3')||(b=='4')||(b=='5')||(b=='6')||(b=='7')||(b=='8')||(b=='9')||(b=='0'))
  {
    if(index<6)
    {
      chislo[index] =  b;
      index++;
    }
  }
  delay(10);
}
   MIN_STEP_TIME = atoi(&chislo[0]); //Из строки в число 
  digitalWrite(EN, 0); //Включаю мотор
  delay(1); // Жду пока произойдет включение
  to_left_steps(16000); //Вращаю четыре оборота //у меня мотор 0.9 градуса на шаг - 400 шагов на оборот.
  delay(1000); //Ротор зафиксирован
  digitalWrite(EN, 1); // Отключаю мотор
}

Файл "step_motor4.h"


#define EN 4 // Пин Arduino На пин драйвера включение - удержание
#define DIR 2 // Пин Arduino На пин драйвера - направление вращения
#define STEP 3 // Пин Arduino На пин драйвера - управления шагами
#define START_STEP_TIME 1500L // Время шага от нуля - толчковый шаг, самый длинный по времени, определяется экспериментально, мотор не должен делать пропуски
//#define MIN_STEP_TIME 400L // Время на шаг, для уже разогнанного мотора, чем меньше тем быстрее, но возможны пропуски
#define ACCELERATION_STEP 1 // Уменьшение времени каждого последующего шага, до минимального времени
#define ACCELERATION_ZERRO_STEP 5 // Увеличение времени каждого последующего шага, до остановки
#define STEP_OFF 100L // Время МЕЖДУ шагАМИ, чем меньше тем быстрее, но возможны пропуски, определяется экспериментально
#define DIR_TO_LEFT false //направление вращения - 
#define DIR_TO_RIGHT true //направление вращения - 

bool DIR_DATA;
unsigned int a;
long MIN_STEP_TIME; // Время наибыстрого шага, самый короткий по времени, определяется экспериментально, мотор не должен делать пропуски...

void setup_step_motor()
{
  pinMode(EN, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(EN, 1); // Пока отключен
  digitalWrite(STEP, 0);
  digitalWrite(DIR,DIR_TO_LEFT);
}

//вращается влево на указанное количество шагов
bool to_left_steps(unsigned int steps)
{
  long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_LEFT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
  steplong=START_STEP_TIME;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if(steplong>MIN_STEP_TIME) steplong-=ACCELERATION_STEP;
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

bool to_right_steps(unsigned int steps)
{
    long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_RIGHT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
   steplong=START_STEP_TIME;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if(steplong>MIN_STEP_TIME) steplong-=ACCELERATION_STEP;
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

Пример test_step5 позволяет управлять величиной минимального шага мотора, т.е. фактически регулировать максимальный разгон. Программа состоит из 2-х файлов test_step5.ino и step_motor5.h, оба должны быть расположены в каталоге test_step5.

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

Следует подключить контроллер arduino к компьютеру, загрузить программу, открыть монитор порта, установить в мониторе порта скорость 115200, в верхней строке для ввода данных ввести число и нажать ввод, это число будет воспринято программой как величина минимального шага. Программа запустит двигатель с величины шага 1500 микросек. (меняется в #define START_STEP_TIME 1500L), а затем начнет пытаться наростить скорость до введенного значения, если двигатель не застопориться, значит исследуемая скорость подходит, в противном случае шаг стоит увеличить и попробовать вновью.

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

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

Файл "test_step5.ino"

#include "step_motor5.h"
char chislo[10];
void setup() {
  setup_step_motor(); //Инициализирую шаговый мотор
  Serial.begin(115200);
}
void loop() 
{
  int index;
  char b;
  delay(100);
  
  for(index= 0;index<7;index++)
  chislo[index] = '�';
  index = 0;
  while(!Serial.available()) delay(100); //Жду появления данных на серийном порту.
while(Serial.available()) //Принимаю число 
{
  b = Serial.read();
  if((b=='1')||(b=='2')||(b=='3')||(b=='4')||(b=='5')||(b=='6')||(b=='7')||(b=='8')||(b=='9')||(b=='0'))
  {
    if(index<6)
    {
      chislo[index] =  b;
      index++;
    }
  }
  delay(10);
}
   MIN_STEP_TIME = atoi(&chislo[0]); //Из строки в число 
  digitalWrite(EN, 0); //Включаю мотор
  delay(1); // Жду пока произойдет включение
  to_left_steps(16000); //Вращаю четыре оборота //у меня мотор 0.9 градуса на шаг - 400 шагов на оборот.
  delay(1000); //Ротор зафиксирован
  digitalWrite(EN, 1); // Отключаю мотор
}

Файл "step_motor5.h"

#define EN 4 // Пин Arduino На пин драйвера включение - удержание
#define DIR 2 // Пин Arduino На пин драйвера - направление вращения
#define STEP 3 // Пин Arduino На пин драйвера - управления шагами
#define START_STEP_TIME 1500L // Время шага от нуля - толчковый шаг, самый длинный по времени, определяется экспериментально, мотор не должен делать пропуски
//#define MIN_STEP_TIME 400L // Время на шаг, для уже разогнанного мотора, чем меньше тем быстрее, но возможны пропуски
#define ACCELERATION_STEP 1 // Уменьшение времени каждого последующего шага, до минимального времени
#define ACCELERATION_ZERRO_STEP 1 // Увеличение времени каждого последующего шага, до остановки
#define STEP_OFF 100L // Время МЕЖДУ шагАМИ, чем меньше тем быстрее, но возможны пропуски, определяется экспериментально
#define DIR_TO_LEFT false //направление вращения - 
#define DIR_TO_RIGHT true //направление вращения - 

bool DIR_DATA;
unsigned int a;
long MIN_STEP_TIME; // Время наибыстрого шага, самый короткий по времени, определяется экспериментально, мотор не должен делать пропуски...
bool flag_start;
void setup_step_motor()
{
  pinMode(EN, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(EN, 1); // Пока отключен
  digitalWrite(STEP, 0);
  digitalWrite(DIR, DIR_TO_LEFT);
}

//вращается влево на указанное количество шагов
bool to_left_steps(unsigned int steps)
{
  long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_LEFT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
  steplong = START_STEP_TIME;
  long braking_time; 
  braking_time=steps-(START_STEP_TIME-MIN_STEP_TIME);
  flag_start = true;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if (flag_start)
      if (steplong > MIN_STEP_TIME) steplong -= ACCELERATION_STEP;
      
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    if (a>braking_time)
    {
      steplong += ACCELERATION_ZERRO_STEP;
      flag_start = false;
    }
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}


bool to_right_steps(unsigned int steps)
{
  long steplong;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_RIGHT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
  steplong = START_STEP_TIME;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    if (steplong > MIN_STEP_TIME) steplong -= ACCELERATION_STEP;
    digitalWrite(STEP, 1);
    delayMicroseconds(STEP_OFF);
    a++;
  }
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

Ниже приведена диаграмма разгона торможения шагового двигателя по программе test_step5.

Скоростные характеристики Скоростные характеристики диаграмма

После анализа test_step5, я решил попробовать реализовать программу, которая разгоняет двигатель равноускоренно. Это было реализовано в программе test_step6, а вернее в step_motor6.h. 

Файл test_step6.ino существенных изменений не получил.

Значительных улучшений при равноускоренном вращении я не получил, усложнился алгоритм расчета, пришлось в связи с влиянием времени расчета на шаг, включить расчет внутрь шага, т.е. расчеты производятся во время шага, а не после. Ускорение можно менять изменяя константу #define ACCELERATION_START 6000 // Стартовое ускорение шаг/Сек2.

Файл "test_step6.ino"


#include "step_motor6.h"
char chislo[10];
void setup() {
  setup_step_motor(); //Инициализирую шаговый мотор
  Serial.begin(115200);
   digitalWrite(EN, 1); // Отключаю мотор
}
void loop() 
{
  int index;
  char b;
  delay(100);
  
  for(index= 0;index<7;index++)
  chislo[index] = '�';
  index = 0;
  while(!Serial.available()) delay(100); //Жду появления данных на серийном порту.
while(Serial.available()) //Принимаю число 
{
  b = Serial.read();
  if((b=='1')||(b=='2')||(b=='3')||(b=='4')||(b=='5')||(b=='6')||(b=='7')||(b=='8')||(b=='9')||(b=='0'))
  {
    if(index<6)
    {
      chislo[index] =  b;
      index++;
    }
  }
  delay(10);
}
   MIN_STEP_TIME = atoi(&chislo[0]); //Из строки в число 
  digitalWrite(EN, 0); //Включаю мотор
  delay(1); // Жду пока произойдет включение
  to_left_steps(32000); //Вращаю сорок оборотов //у меня мотор 0.9 градуса на шаг - 400 шагов на оборот.
  delay(1000); //Ротор зафиксирован
  digitalWrite(EN, 1); // Отключаю мотор
}

Файл "step_motor6.h"

#define EN 4 // Пин Arduino На пин драйвера включение - удержание
#define DIR 2 // Пин Arduino На пин драйвера - направление вращения
#define STEP 3 // Пин Arduino На пин драйвера - управления шагами
#define START_STEP_TIME 1500L // Время шага от нуля - толчковый шаг, самый длинный по времени, определяется экспериментально, мотор не должен делать пропуски
//#define MIN_STEP_TIME 400L // Время на шаг, для уже разогнанного мотора, чем меньше тем быстрее, но возможны пропуски
#define ACCELERATION_START 6000 // Стартовое ускорение шаг/Сек2
#define ACCELERATION_STOP 6000 // Ускорение замедления шаг/Сек2
#define STEP_OFF 100L // Время МЕЖДУ шагАМИ, чем меньше тем быстрее, но возможны пропуски, определяется экспериментально
#define DIR_TO_LEFT false //направление вращения - 
#define DIR_TO_RIGHT true //направление вращения - 

bool DIR_DATA;
long a;
long MIN_STEP_TIME; // Время наибыстрого шага, самый короткий по времени, определяется экспериментально, мотор не должен делать пропуски...
bool flag_start;
void setup_step_motor()
{
  pinMode(EN, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(EN, 1); // Пока отключен
  digitalWrite(STEP, 0);
  digitalWrite(DIR, DIR_TO_LEFT);
}

//вращается влево на указанное количество шагов
bool to_left_steps(long steps)
{
  long steplong, v_motor, a_motor, a_motor_ostatok, braking_time, step_off, bubu;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_LEFT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
  steplong = START_STEP_TIME;
  v_motor = 1000000L / steplong;
  a_motor_ostatok = 0;
  a_motor = ACCELERATION_START;
  flag_start = true;
  braking_time = steps;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    digitalWrite(STEP, 1);
    step_off = micros() + STEP_OFF;
    //delayMicroseconds(STEP_OFF);
    if (flag_start)
    {
      if ((steplong > MIN_STEP_TIME) && (a < (steps / 2L)))
      {
        v_motor = v_motor + (a_motor * steplong + a_motor_ostatok) / 1000000L;
        a_motor_ostatok = (a_motor * steplong + a_motor_ostatok) % 1000000L;
        steplong = 1000000L / v_motor;
      }
      else
      {
        flag_start = false;
        braking_time = steps - a;
        a_motor_ostatok = 0;
      }
    }
    if ((flag_start == false) && (a >= braking_time))
    {
      v_motor = v_motor - (a_motor * steplong + a_motor_ostatok) / 1000000L;
      a_motor_ostatok = (a_motor * steplong + a_motor_ostatok) % 1000000L;
      steplong = 1000000L / v_motor;
    }
    a++;
    bubu = micros();
    while (step_off > bubu) bubu = micros();
  }
  Serial.println(steplong);
  Serial.print("V="); Serial.println(v_motor);
  Serial.print("braking_time="); Serial.println(braking_time);
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

bool to_right_steps(unsigned int steps)
{
  long steplong, v_motor, a_motor, a_motor_ostatok, braking_time, step_off, bubu;
  //digitalWrite(EN, 0);
  //delay(500);
  DIR_DATA = DIR_TO_RIGHT;
  digitalWrite(DIR, DIR_DATA); //вправо
  a = 0;
  steplong = START_STEP_TIME;
  v_motor = 1000000L / steplong;
  a_motor_ostatok = 0;
  a_motor = ACCELERATION_START;
  flag_start = true;
  braking_time = steps;
  while (a < steps)
  {
    digitalWrite(STEP, 0);
    delayMicroseconds(steplong);
    digitalWrite(STEP, 1);
    step_off = micros() + STEP_OFF;
    //delayMicroseconds(STEP_OFF);

    if (flag_start)
    {
      if ((steplong > MIN_STEP_TIME) && (a < (steps / 2L)))
      {
        v_motor = v_motor + (a_motor * steplong + a_motor_ostatok) / 1000000L;
        a_motor_ostatok = (a_motor * steplong + a_motor_ostatok) % 1000000L;
        steplong = 1000000L / v_motor;
      }
      else
      {
        flag_start = false;
        braking_time = steps - a;
        a_motor_ostatok = 0;
      }
    }
    if ((flag_start == false) && (a >= braking_time))
    {
      v_motor = v_motor - (a_motor * steplong + a_motor_ostatok) / 1000000L;
      a_motor_ostatok = (a_motor * steplong + a_motor_ostatok) % 1000000L;
      steplong = 1000000L / v_motor;
    }
    a++;
    bubu = micros();
    while (step_off > bubu) bubu = micros();
  }
  Serial.println(steplong);
  Serial.print("V="); Serial.println(v_motor);
  Serial.print("braking_time="); Serial.println(braking_time);
  //digitalWrite(EN, 1); //ОТКЛЮЧЕНИЕ МОТОРА ШАГОВОГО
  return true;
}

 

Ссылка для скачивания: Программы и схемы для тестов

X

Написать сообщение:

Укажите свой номер телефона И e-mail для обратной связи
- e-mail
И
- номер телефона

Текст сообщения: