Проблемы с шаговым двигателем dm556 leadshine
- Войдите на сайт для отправки комментариев
Всем доброго времени суток! Прошу помощи, так как уже не понимаю что происходит :) В общем суть в следующем. Имеется 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;
}
Забыл сказать - ардуино УНО оригинал и шаговый двигатель - dm556 leadshine
"Не хочет" - это "дымит" или "выдвигает политические требования"?
И это забыл упомянуть - молчит.. не подает признаков жизни
Дак питания мож нет? Сделайте скетч попроще, чтобы только CCW делал.
С питанием все нормально. Такое ощущение что ШД не успевает соображать.. Но в ручном то работает
Выводите micros() на каждом степе. Так и поймёте - есть ли проблема в расчёте пауз.
В ручном режиме нет их. Отрабатывает все нормально. Так откуда им взяться в автоматическом режиме? Просто ручной режим. Нажали кнопку - сменился статус на движение вверх - зашли в функцию - сделали шаг - вышли с функции - проверка нажатия кнопки - зашли в функцию - сделали шаг -... . А автоматический режим вместо проверки нажатия кнопки - проверка статуса.. А все остальное же тоже самое
Определитесь - хотите проблему решить или подискутировать?
// выполнить шаг вперед 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; }Данные монитора:
Вот такие показания выдает программа (разница между соседними показаниями):
Получается надо изменить этот диапазон? delayMicroseconds(1000000 / current_speed / 2); чтобы диапазон был от 3 до 16383? но если подставить у меня получается должен быть диапазон :
максимальный 1000000 / 50 / 2 = 10000 микросекунд
минимальный 1000000 / 15000/ 2 = 33 микросекунды
Вроде как попадаю в диапазон..
Не факт, что все вычисляется, как вы представляете. Я бы туда константу поставил и посмотрел - будет ли он ездить по алгоритму, но без разгона. Потому что вроде как иных мест, где можно было бы словить баг, я пока не вижу.
Понял. Спасибо. Сейчас проверю
Добрый день. Разобрались наконец-то.. концевик на восьмой ноге из за своей длинны(и может еще каких то внешних факторов) давал наводку, срабатывал конец команды авто. Повесили через резистор на плюс и через конденсатор на минус и все заработало. Спасибо за помощь!