Управление биполярным шаговым двигателем при помощи инкрементального энкодера

Управление биполярным шаговым двигателем при помощи инкрементального (инкрементного) энкодера EC11, Arduino Nano и DRW8825

Для проекта используется:

Плата Arduino Nano, инкрементальный (инкрементный) энкодер EC11, драйвер для шагового двигателя DRV8825, макетная плата, соединительные провода, и биполярный шаговый двигатель Mitsumi.

плата Arduino Nano, драйвер шагового двигателя DRV8825, макетная плата, соединительные провода, биполярный шаговый двигатель Mitsumi, инкрементальный (инкрементный) энкодер EC11.

Для сканирования контактов энкодера можно использовать этот скетч! Загрузите его на плату до подключения энкодера к плате!


//Начало скетча для теста контактов энкодера


void setup()
{
  Serial.begin(9600);
  pinMode( 2, OUTPUT); digitalWrite( 2, HIGH);
  pinMode( 3, INPUT);
  pinMode( 4, INPUT);
  pinMode( 5, INPUT);
}

void loop()
{
  int sw = digitalRead(3);
  int clk = digitalRead(5);
  int dt = digitalRead(4);
  Serial.print("SW="); Serial.print(sw);
  delay(10);
  Serial.print(" CLK="); Serial.print(clk);
  delay(10);
  Serial.print(" DT="); Serial.println(dt);
  delay(100);
}


//Конец скетча для теста контактов энкодера




После загрузки скетча для теста контактов энкодера, можно подключать энкодер к плате Arduino Nano, как показано на этой схеме.

Схема подключения инкрементального (инкрементного) энкодера EC11 к Arduino Nano

Первый вариант кода, который был представлен в видео.

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

Внимание! Если при удержании вала шаговый двигатель нагревается более чем на 50 градусов, то следует уменьшить подачу тока, немного повернув регулятор на драйвере шагового двигателя, по часовой стрелке (для DRW8825)!

При использовании драйвера шагового двигателя A4988, уменьшение тока происходит при вращении регулятора против часовой стрелки!


//Начало первого варианта кода


const int stepPin = 11;
const int enablePin = 12;
const int dirPin = 13;

const int plus = 2;
const int sw = 3;
const int dt = 4;
const int clk = 5;

int state_SW = 0;
int state_DT = 0;
int state_CLK = 0;
int i = 0, j = 0, steps = 0;
int limit, limit_1 = 1, limit_2 = 5;

void setup()
{
  Serial.begin(9600);
  pinMode( plus, OUTPUT); digitalWrite( 2, HIGH);
  pinMode( sw, INPUT);
  pinMode( dt, INPUT);
  pinMode( clk, INPUT);
  pinMode( stepPin, OUTPUT); digitalWrite( stepPin, LOW);
  pinMode( enablePin, OUTPUT); digitalWrite( enablePin, LOW);
  pinMode( dirPin, OUTPUT); digitalWrite( dirPin, LOW);
}

void loop()
{
  state_SW = digitalRead(sw);
  state_DT = digitalRead(dt);
  state_CLK = digitalRead(clk);
  if (state_SW == LOW) {
    limit = limit_2;
  } else {
    limit = limit_1;
  }
  if ((state_DT == HIGH) && (state_CLK == LOW) && (i == 0) && (j == 0)) {
    i = 1;
  }
  if ((state_DT == LOW) && (state_CLK == LOW) && (i == 1) && (j == 0)) {
    i = 2;
  }
  if ((state_DT == LOW) && (state_CLK == HIGH) && (i == 2) && (j == 0)) {
    i = 3;
  }
  if ((state_DT == HIGH) && (state_CLK == HIGH) && (i == 3) && (j == 0)) {
    i = 0;
    Serial.println("Step +");
    steps = limit; digitalWrite( dirPin, HIGH);
  }
  if ((state_DT == LOW) && (state_CLK == HIGH) && (j == 0) && (i == 0)) {
    j = 1;
  }
  if ((state_DT == LOW) && (state_CLK == LOW) && (j == 1) && (i == 0)) {
    j = 2;
  }
  if ((state_DT == HIGH) && (state_CLK == LOW) && (j == 2) && (i == 0)) {
    j = 3;
  }
  if ((state_DT == HIGH) && (state_CLK == HIGH) && (j == 3) && (i == 0)) {
    j = 0;
    Serial.println("Step -");
    steps = limit; digitalWrite( dirPin, LOW);
  }
  if (steps > 0) {
    steps--;
    digitalWrite( stepPin, HIGH); delay(5);
    digitalWrite( stepPin, LOW);
  }
}


//Конец первого варианта кода




Второй вариант кода.

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


//Начало второго варианта кода


const int stepPin = 11;     //Контакт для подключения к Step
const int enablePin = 12;   //Контакт для подключения к Enable
const int dirPin = 13;      //Контакт для подключения к Dir

const int plus = 2;   //Контакт для подачи питания на энкодер
const int sw = 3;     //Контакт для подключения кнопки энкодера
const int dt = 4;     //Контакт для подключения линии энкодера DT
const int clk = 5;    //Контакт для подключения линии энкодера CLK

int state_SW = 0;     //Переменная для хранения состояния кнопки энкодера
int state_DT = 0;     //Переменная для хранения состояния линии энкодера DT
int state_CLK = 0;    //Переменная для хранения состояния линии энкодера CLK
int steps = 0;        //Переменная для хранения количества шагов, которые надо выполнить
int limit, limit_1 = 1, limit_2 = 5;  //Переменные задающие количество шагов
unsigned long saveMillis = 0;         //Переменная для хранения значения времени 

void setup()
{
  //Подключение к шине UART (Может пригодиться для отладки кода)
  //Serial.begin(9600);
  
  pinMode( plus, OUTPUT);       //Назначить контакт plus как выход
  digitalWrite( plus, HIGH);    //Задать высокий уровень контакту plus
  pinMode( sw, INPUT);          //Назначить контакт sw как вход
  pinMode( dt, INPUT);          //Назначить контакт dt как вход
  pinMode( clk, INPUT);         //Назначить контакт clk как вход
  pinMode( stepPin, OUTPUT);    //Назначить контакт stepPin как выход
  digitalWrite( stepPin, LOW);  //Задать низкий уровень контакту stepPin
  pinMode( enablePin, OUTPUT);  //Назначить контакт enablePin как выход
  pinMode( dirPin, OUTPUT);     //Назначить контакт dirPin как выход
  digitalWrite( dirPin, LOW);   //Задать низкий уровень контакту dirPin
  state_CLK = digitalRead(clk); //Считывает начальное состояние входа clk
}

void loop()
{
  state_SW = digitalRead(sw);   //Считывает текущее состояние выхода sw
  state_DT = digitalRead(dt);   //Считывает текущее состояние выхода dt
  if (state_SW == LOW) {
    limit = limit_2;  //Если кнопка энкодера нажата, то добавлять по 5 шагов
  } else {
    limit = limit_1;  //Если кнопка энкодера не нажата, то прибавлять по 1 шагу
  }
  
  //Если прошло более чем пол секунды после того как вращался шаговый двигатель
  //то задать высокий уровень контакту enablePin, то есть выключить драйвер шагового двигателя
  if (millis() - saveMillis > 500) {  digitalWrite( enablePin, HIGH);}
  
  // Если предыдущее и текущее состояние входа dt различаются, это означает, что произошел импульс
  if (state_DT != state_CLK){     
    // Если состояние входа clk отличается от состояния выхода dt, это означает, что энкодер вращается по часовой
    if (digitalRead(clk) != state_DT) { 
      //Serial.println("Step +");   //Сообшить в порт UART о свершившемся событии
      steps = limit;                //К переменной steps прибавить количество шагов
      digitalWrite( dirPin, HIGH);  //Задать высокий уровень контакту dirPin
      digitalWrite( enablePin, LOW);//Задать низкий уровень контакту enablePin (включить драйвер ШД)
      saveMillis = millis();        //Запомнить текущее время
    } else {
      //Serial.println("Step -");   //Сообшить в порт UART о свершившемся событии
      steps = limit;                //К переменной steps прибавить количество шагов
      digitalWrite( dirPin, LOW);   //Задать низкий уровень контакту dirPin
      digitalWrite( enablePin, LOW);//Задать низкий уровень контакту enablePin (включить драйвер ШД)
      saveMillis = millis();        //Запомнить текущее время
    }
  } 
  state_CLK = state_DT; // Обновляет предыдущее состояние входа clk текущим состоянием
  
  if (steps > 0) {      //Если имеются шаги, то выполнить 1 шаг
    steps--;            //Отнять 1 шаг их общего количества
    digitalWrite( stepPin, HIGH); //Задать высокий уровень контакту stepPin
    delay(5);                     //Выполнить паузу 5 миллисекунд
    digitalWrite( stepPin, LOW);  //Задать низкий уровень контакту stepPin
  }
}


//Конец второго варианта кода




После загрузки скетча можно собрать все, как показано на этой схеме.

Схема управления биполярным шаговым двигателем с использованием инкрементального (инкрементного) энкодера EC11, Arduino Nano и драйвера для шаговых двигателей DRW8825

Видео проекта “Управление биполярным шаговым двигателем при помощи инкрементального энкодера”


Управления биполярным шаговым двигателем с использованием инкрементального (инкрементного) энкодера EC11, Arduino Nano и драйвера для шаговых двигателей DRW8825.