Проблемы с шаговым двигателем dm556 leadshine

guliyev34
Offline
Зарегистрирован: 17.03.2015

Всем доброго времени суток! Прошу помощи, так как уже не понимаю что происходит :) В общем суть в следующем. Имеется 3д принтер, шаговый двигатель, драйвер двигателя. Также ардуино, 3 кнопки и 2 концевика. При нажатии на 1 кнопку - шаговый двигатель начинает вращаться в одном направлении, если дошел до 1 концевика или отпустили кнопку - остановка. При нажатии на 2 кнопку - тоже самое, только другой концевик участвует, и движение в противоположную сторону! Все работает как часы. Но.. Есть 3 кнопка - автоматический режим. При нажатии - первый раз вкл режим, второй раз выкл. При включении автоматического режима, двигатель начинает вращать до момента соприкосновения с первым датчиком. Соприкоснулся? Ок! Движение в обратном направлении на N шагов! Вроде не сложно! Но.. Вывожу в сериал порт все необходимые данные! Все работает как часы. Автоматический режим плавно набирает скорость, доходит до концевика, отводит назад на N шагов! Но это только в сериал порту.. В реальности же двигатель не хочет крутиться.. Хотя все движение двигателя  (функция) она одинакова для всех кнопок.. Уже просто голову сломал. Надеюсь на вашу помощь!

// подключение библиотеки для устранения шума
#include <Bounce2.h>

// пин подключения верхнего концевика
const uint8_t floorUpSwitch = 8;
// пин подключения нижнего концевика
const uint8_t floorDownSwitch = 9;
// пин подключения кнопки ВВЕРХ
const uint8_t  upButton_pin = 7;
// пин подключения кнопки ВНИЗ
const uint8_t  downButton_pin = 6;
// пин подключения кнопки АВТО
const uint8_t  autoButton_pin = 3;
// пин подключения STEP
const uint8_t  motorStep = 13;
// пин подключения DIR
const uint8_t  motorDirection = 12;
// текущая скорость
uint32_t current_speed = 0;
// частота микрошагов
uint32_t f = 15000;
// режим работы (0 - простой, 1 - движение вниз, 2 - движение вверх, 3 - авторежим)
unsigned long state = 0;
// последнее состояние работы
unsigned long state_last = 0;
// количество шагов назад
unsigned long N = 10;
// инициализация кнопок через библиотеку Bounce
Bounce2::Button upButton   = Bounce2::Button();
Bounce2::Button downButton = Bounce2::Button();
Bounce2::Button autoButton = Bounce2::Button();

// функция выполняется один раз - при включении устройства
void setup() {
  Serial.begin(9600);
  // настройка подключенных пинов двигателя (выход , низкий уровень)
  setupPin(motorStep, OUTPUT, LOW);
  setupPin(motorDirection, OUTPUT, LOW);
  // настройка подключенных пинов концевиком (вход с подтяжкой к +5В)
  pinMode(floorUpSwitch, INPUT_PULLUP);
  pinMode(floorDownSwitch, INPUT_PULLUP);
  // настройка подключенного пина кнопки ВВЕРХ (вход с подтяжкой к +5В) с антишумом
  upButton.attach( upButton_pin ,  INPUT_PULLUP );
  upButton.interval(5);
  upButton.setPressedState(LOW);
  // настройка подключенного пина кнопки ВНИЗ (вход с подтяжкой к +5В) с антишумом
  downButton.attach( downButton_pin ,  INPUT_PULLUP );
  downButton.interval(5);
  downButton.setPressedState(LOW);
  // настройка подключенного пина кнопки АВТО (вход с подтяжкой к +5В) с антишумом
  autoButton.attach( autoButton_pin ,  INPUT_PULLUP );
  autoButton.interval(5);
  autoButton.setPressedState(LOW);
  pinMode(autoButton_pin, INPUT_PULLUP);
}

void loop() {
  // обновление состояния кнопки ВВЕРХ
  upButton.update();
  // обновление состояния кнопки ВНИЗ
  downButton.update();
  // обновление состояния кнопки АВТО
  autoButton.update();
  // если нажата кнопка ВВЕРХ
  if (upButton.isPressed()) {
    state = 2;
  } 
  // если нажата кнопка ВНИЗ
  else  if (downButton.isPressed()) {
    state = 1;
  }
  // если нажали кнопку АВТО
  else  if (autoButton.fell()) {
    if (state == 3) {
      state = 0;
      Serial.println("АВТО ВЫКЛ");
    } else {
      state = 3;
      Serial.println("АВТО ВКЛ");
    }
  }
  
  // если прошлое состояние не равно текушему 
  if (state_last != state) {
    // обновление
    state_last = state;
    current_speed = 0;
  }
  
  // обновление режима работы
  switch (state) {
    // режим ожидания
    case 0:
      break;
      // движение ВНИЗ по кнопке
    case 1:
      Serial.println("ВНИЗ, скорость: " + String(current_speed));
      moveDown();
      state = 0;
      break;
      // движение ВВЕРХ по кнопке
    case 2:
      Serial.println("ВЕРХ, скорость: " + String(current_speed));
      moveUp();
      state = 0;
      break;
      // движение вверх в режиме АВТО
    case 3:
      moveAuto();
      break;
    default:
      break;
  }
}

// функция движения в автоматическом режиме ВВЕРХ
void moveAuto() {
  // если достиг концевика - отпускается вниз на N шагов и переход в режим ожидания
  if (digitalRead(floorUpSwitch) == LOW) {
     current_speed = 0;
     for (int i = 0 ; i < N ; i++){takeStepReverse(); Serial.println("АВТО ВНИЗ, скорость: " + String(current_speed));}
     state = 0;
     Serial.println("статус " + String(state));
     return;
  }
  // если не достиг - движение ВВЕРХ
  Serial.println("АВТО ВВЕРХ, скорость: " + String(current_speed));
  takeStepForward();
}

// функция движения ВВЕРХ
void moveUp() {
  // если достиг концевика - переход в режим ожидания
  if (digitalRead(floorUpSwitch) == LOW) {
    state = 0;
    return;
  }
  // если не достиг - движение ВВЕРХ
  takeStepForward();
}

// функция движения ВНИЗ
void moveDown() {
  // если достиг концевика - переход в режим ожидания
  if (digitalRead(floorDownSwitch) == LOW) {
    state = 0;
    return;
  }
  // если не достиг - движение ВНИЗ
  takeStepReverse();
}

// комплексная настройка пина (режим и состояние)
void setupPin(uint8_t pin, uint8_t mode, uint8_t state) {
  pinMode(pin, mode);
  digitalWrite(pin, state);
}

// выполнить шаг вперед
void takeStepForward() {
  // установка направления движения вала
  digitalWrite(motorDirection , LOW);
  // включение двигателя
  digitalWrite(motorStep, HIGH);
  // задержка t3 согласно графику STEP/DIR
  delayMicroseconds(1000000 / current_speed / 2);
  // выключение двигателя
  digitalWrite(motorStep , LOW);
  // задержка t4 согласно графику STEP/DIR
  delayMicroseconds(1000000 / current_speed / 2);
  // постепенное увеличение скорости врщения
  if (current_speed < f)current_speed = current_speed + 50;
}

// выполнить шаг назад
void takeStepReverse() {
  // установка направления движения вала
  digitalWrite(motorDirection , HIGH);
  // включение двигателя
  digitalWrite(motorStep, HIGH);
  // задержка t3 согласно графику STEP/DIR
  delayMicroseconds(1000000 / current_speed / 2);
  // выключение двигателя
  digitalWrite(motorStep , LOW);
  // задержка t4 согласно графику STEP/DIR
  delayMicroseconds(1000000 / current_speed / 2);
  // постепенное увеличение скорости врщения
  if (current_speed < f)current_speed = current_speed + 50;
}

 

guliyev34
Offline
Зарегистрирован: 17.03.2015

Забыл сказать - ардуино УНО оригинал и шаговый двигатель - dm556 leadshine

sadman41
Offline
Зарегистрирован: 19.10.2016

"Не хочет" - это "дымит" или "выдвигает политические требования"?

guliyev34
Offline
Зарегистрирован: 17.03.2015

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

sadman41
Offline
Зарегистрирован: 19.10.2016

Дак питания мож нет? Сделайте скетч попроще, чтобы только CCW делал.

guliyev34
Offline
Зарегистрирован: 17.03.2015

С питанием все нормально. Такое ощущение что ШД не успевает соображать.. Но в ручном то работает

sadman41
Offline
Зарегистрирован: 19.10.2016

Выводите micros() на каждом степе. Так и поймёте - есть ли проблема в расчёте пауз.

guliyev34
Offline
Зарегистрирован: 17.03.2015

В ручном режиме нет их. Отрабатывает все нормально. Так откуда им взяться в автоматическом режиме? Просто ручной режим. Нажали кнопку - сменился статус на движение вверх - зашли в функцию - сделали шаг - вышли с функции - проверка нажатия кнопки - зашли в функцию - сделали шаг -... . А автоматический режим вместо проверки нажатия кнопки - проверка статуса.. А все остальное же тоже самое

sadman41
Offline
Зарегистрирован: 19.10.2016

Определитесь - хотите проблему решить или подискутировать?

guliyev34
Offline
Зарегистрирован: 17.03.2015
// выполнить шаг вперед
void takeStepForward() {
  Serial.println("Time: ");
  time = micros();
  //выводит количество микросекунд с момента начала выполнения программы
  Serial.println(time);
  // установка направления движения вала
  digitalWrite(motorDirection , LOW);
  // включение двигателя
  digitalWrite(motorStep, HIGH);
  // задержка t3 согласно графику STEP/DIR
  delayMicroseconds(1000000 / current_speed / 2);
  // выключение двигателя
  digitalWrite(motorStep , LOW);
  // задержка t4 согласно графику STEP/DIR
  delayMicroseconds(1000000 / current_speed / 2);
  // постепенное увеличение скорости врщения
  if (current_speed < f)current_speed = current_speed + 50;
}

Данные монитора:

АВТО ВКЛ
АВТО ВВЕРХ, скорость: 0
Time: 
3210328
АВТО ВВЕРХ, скорость: 50
Time: 
3272728
АВТО ВВЕРХ, скорость: 100
Time: 
3336168
АВТО ВВЕРХ, скорость: 150
Time: 
3399608
АВТО ВВЕРХ, скорость: 200
Time: 
3463048
АВТО ВВЕРХ, скорость: 250
Time: 
3526488
АВТО ВВЕРХ, скорость: 300
Time: 
3589928
АВТО ВВЕРХ, скорость: 350
Time: 
3653368
АВТО ВВЕРХ, скорость: 400
Time: 
3716808
АВТО ВВЕРХ, скорость: 450
Time: 
3780248
АВТО ВВЕРХ, скорость: 500
Time: 
3843688
АВТО ВВЕРХ, скорость: 550
Time: 
3907128
АВТО ВВЕРХ, скорость: 600
Time: 
3970568
АВТО ВВЕРХ, скорость: 650
Time: 
4034008
АВТО ВВЕРХ, скорость: 700
Time: 
4097448
АВТО ВВЕРХ, скорость: 750
Time: 
4160888
АВТО ВВЕРХ, скорость: 800
Time: 
4224328
АВТО ВВЕРХ, скорость: 850
Time: 
4287768
АВТО ВВЕРХ, скорость: 900
Time: 
4351208
АВТО ВВЕРХ, скорость: 950
Time: 
4414648
АВТО ВВЕРХ, скорость: 1000
Time: 
4479128
АВТО ВВЕРХ, скорость: 1050
Time: 
4543608
АВТО ВВЕРХ, скорость: 1100
Time: 
4608088
АВТО ВВЕРХ, скорость: 1150
Time: 
4672568
АВТО ВВЕРХ, скорость: 1200
Time: 
4737048
АВТО ВВЕРХ, скорость: 1250
Time: 
4801528
АВТО ВВЕРХ, скорость: 1300
Time: 
4866008
АВТО ВВЕРХ, скорость: 1350
Time: 
4930488
АВТО ВВЕРХ, скорость: 1400
Time: 
4994968
АВТО ВВЕРХ, скорость: 1450
Time: 
5059448
АВТО ВВЕРХ, скорость: 1500
Time: 
5123928
АВТО ВВЕРХ, скорость: 1550
Time: 
5188408
АВТО ВЫКЛ
АВТО ВКЛ
АВТО ВВЕРХ, скорость: 0
Time: 
29878360
АВТО ВВЕРХ, скорость: 50
Time: 
29941800
АВТО ВВЕРХ, скорость: 100
Time: 
30006288
АВТО ВВЕРХ, скорость: 150
Time: 
30070760
АВТО ВВЕРХ, скорость: 200
Time: 
30135240
АВТО ВВЕРХ, скорость: 250
Time: 
30199720
АВТО ВВЕРХ, скорость: 300
Time: 
30264200
АВТО ВВЕРХ, скорость: 350
Time: 
30328680
АВТО ВВЕРХ, скорость: 400
Time: 
30393160
АВТО ВВЕРХ, скорость: 450
Time: 
30457640
АВТО ВВЕРХ, скорость: 500
Time: 
30522120
АВТО ВВЕРХ, скорость: 550
Time: 
30586600
АВТО ВВЕРХ, скорость: 600
Time: 
30651080
АВТО ВВЕРХ, скорость: 650
Time: 
30715560
АВТО ВВЕРХ, скорость: 700
Time: 
30780040
АВТО ВВЕРХ, скорость: 750
Time: 
30844520
АВТО ВВЕРХ, скорость: 800
Time: 
30909000
АВТО ВВЕРХ, скорость: 850
Time: 
30973480
АВТО ВВЕРХ, скорость: 900
Time: 
31037960
АВТО ВВЕРХ, скорость: 950
Time: 
31102440
АВТО ВВЕРХ, скорость: 1000
Time: 
31167960
АВТО ВВЕРХ, скорость: 1050
Time: 
31233480
АВТО ВВЕРХ, скорость: 1100
Time: 
31299000
АВТО ВВЕРХ, скорость: 1150
Time: 
31364520
АВТО ВВЕРХ, скорость: 1200
Time: 
31430040
АВТО ВВЕРХ, скорость: 1250
Time: 
31495560
АВТО ВВЕРХ, скорость: 1300
Time: 
31561080
АВТО ВВЕРХ, скорость: 1350
Time: 
31626600
АВТО ВВЕРХ, скорость: 1400
Time: 
31692120
АВТО ВВЕРХ, скорость: 1450
Time: 
31757640
АВТО ВВЕРХ, скорость: 1500
Time: 
31823160
АВТО ВВЕРХ, скорость: 1550
Time: 
31888680
АВТО ВВЕРХ, скорость: 1600
Time: 
31954200
АВТО ВВЕРХ, скорость: 1650
Time: 
32019720
АВТО ВВЕРХ, скорость: 1700
Time: 
32085240
АВТО ВВЕРХ, скорость: 1750
Time: 
32150760
Time: 
32169480
АВТО ВНИЗ, скорость: 50
Time: 
32230840
АВТО ВНИЗ, скорость: 100
Time: 
32293240
АВТО ВНИЗ, скорость: 150
Time: 
32355640
АВТО ВНИЗ, скорость: 200
Time: 
32418040
АВТО ВНИЗ, скорость: 250
Time: 
32480440
АВТО ВНИЗ, скорость: 300
Time: 
32542840
АВТО ВНИЗ, скорость: 350
Time: 
32605240
АВТО ВНИЗ, скорость: 400
Time: 
32667640
АВТО ВНИЗ, скорость: 450
Time: 
32730040
АВТО ВНИЗ, скорость: 500
статус 0

Вот такие показания выдает программа (разница между соседними показаниями):

ручной режим - ВНИЗ: 52000
ручной режим - ВВЕРХ: 52000
режим АВТОМАТ: 
движение вверх - 64480
движение вниз  - 62400
sadman41
Offline
Зарегистрирован: 19.10.2016
 
 
Currently, the largest value that will produce an accurate delay is 16383; larger values can produce an extremely short delay.
 
guliyev34
Offline
Зарегистрирован: 17.03.2015

Получается надо изменить этот диапазон? delayMicroseconds(1000000 / current_speed / 2); чтобы диапазон был от 3 до 16383? но если подставить у меня получается должен быть диапазон :

максимальный 1000000 / 50 / 2 = 10000 микросекунд

минимальный 1000000 / 15000/ 2 = 33 микросекунды

Вроде как попадаю в диапазон.. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Не факт, что все вычисляется, как вы представляете. Я бы туда константу поставил и посмотрел - будет ли он ездить по алгоритму, но без разгона. Потому что вроде как иных мест, где можно было бы словить баг, я пока не вижу.

guliyev34
Offline
Зарегистрирован: 17.03.2015

Понял. Спасибо. Сейчас проверю

guliyev34
Offline
Зарегистрирован: 17.03.2015

Добрый день. Разобрались наконец-то.. концевик на восьмой ноге из за своей длинны(и может еще каких то внешних факторов) давал наводку, срабатывал конец команды авто. Повесили через резистор на плюс и через конденсатор на минус и все заработало. Спасибо за помощь!