Управление шаговыми двигателями. Библиотека AccelStepper.
- Войдите на сайт для отправки комментариев
Вс, 29/01/2017 - 21:45
Доброго времени суток! Уважаемые Форумчане, помогите начинающему, пожалуйста. Уже месяц колупаюсь над проектом ( возникла такая необходимость ), начал с нуля... с полного нуля, а уже с неделю не получается вращать двигатели как хотелось бы.
Должно быть так - выбирается управление автомат или ручное. На автомате начинают в паре вращаться myStepper1 и myStepper4 (это работает) потом 2-й (работает) и затем 3-й в паре с 4-м (начались проблемы, вращается только 3-й). Этот цикл должен повторится, ну скажем 5 раз и остановиться. При повторном выборе режима авто должно
все повториться. ВООБЩЕ не получается повторить вращение, только через полное отключение. При вращении двигателей, когда срабатывает кнопка переключения режимов они должны остановиться, пока вращаются 2-й и 4-й это получается а дальше управление теряется. Помогите кто чем может, у меня уже ума не хватает.
Вот код:
#include <AccelStepper.h> #include <Wire.h> #include <LiquidCrystal.h> LiquidCrystal lcd1(31, 32, 33, 34, 35, 36); LiquidCrystal lcd2(A8, A9, A10, A11, A12, A13); // Define some steppers and the pins the will use AccelStepper myStepper1; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5 AccelStepper myStepper2(AccelStepper::FULL4WIRE, 6, 7, 8, 9); AccelStepper myStepper3(AccelStepper::FULL4WIRE, 10, 11, 12, 13); AccelStepper myStepper4(AccelStepper::FULL4WIRE, 14, 15, 16, 17); const int buttonPinA_M = A4; const int buttonPinB_1 = A7; const int buttonPinB_2 = A2; const int buttonPinB_3 = A3; const int ledPin5V = 40; const int ledPinSTOP = 41; const int ledPinAUTO = 18; const int ledPinMANUAL = 19; const int ledPinD_1 = 44; const int ledPinD_2 = 43; const int ledPinD_3 = 42; const int ledPinD_4 = 2; int A_M = 1; int flag = 0; int regim = 0; int flag_1 = 0; int regim_1= 0; volatile int state = LOW; void setup() { myStepper1.setMaxSpeed(300.0); myStepper1.setAcceleration(200.0); myStepper1.moveTo(500); myStepper2.setMaxSpeed(300.0); myStepper2.setAcceleration(200.0); myStepper2.moveTo(100); myStepper3.setMaxSpeed(300.0); myStepper3.setAcceleration(200.0); myStepper3.moveTo(100); myStepper4.setMaxSpeed(300.0); myStepper4.setAcceleration(200.0); myStepper4.moveTo(100); pinMode(buttonPinA_M, INPUT); pinMode(buttonPinB_1, INPUT); pinMode(buttonPinB_2, INPUT); pinMode(buttonPinB_3, INPUT); pinMode(ledPin5V, OUTPUT); pinMode(ledPinAUTO, OUTPUT); pinMode(ledPinMANUAL, OUTPUT); pinMode(ledPinSTOP, OUTPUT); pinMode(ledPinD_1, OUTPUT); pinMode(ledPinD_2, OUTPUT); pinMode(ledPinD_3, OUTPUT); Serial.begin(9600); } void loop() { digitalWrite(ledPin5V, HIGH); if(digitalRead(buttonPinA_M) == !state && flag == 0) { regim ++; flag = 1; if(regim > 2) // Если номер режима превышает требуемого { // то отсчет начинается с нуля regim = 0; } } if(digitalRead(buttonPinA_M) == state && flag == 1) { flag = 0; } // ======= Вполняем задачу при выборе режима ======= // РЕЖИМ 0: OFF if(regim == 0) { Stop(); } // РЕЖИМ 1: AVTO if(regim == 1) { avto(); } // РЕЖИМ 2: MANUAL if(regim == 2) { digitalWrite(ledPinMANUAL,HIGH); manual(); } } void motor_x3() { digitalWrite(ledPinD_3,HIGH); myStepper4.run(); myStepper3.runToNewPosition(100); myStepper3.runToNewPosition(0); } void motor_x2() { digitalWrite(ledPinD_2,HIGH); myStepper2.runToNewPosition(100); myStepper2.runToNewPosition(0); if (myStepper2.distanceToGo() == 0) motor_x3(); } void motor_x1() { myStepper1.run(); myStepper4.run(); if (myStepper1.distanceToGo() == 0) motor_x2(); } void manual() { } void Stop() { digitalWrite(ledPinD_1,LOW); digitalWrite(ledPinD_2,LOW); digitalWrite(ledPinD_3,LOW); digitalWrite(ledPinMANUAL, LOW); digitalWrite(ledPinAUTO, LOW); digitalWrite(ledPinSTOP, LOW); } void avto() { digitalWrite(ledPinD_1,HIGH); digitalWrite(ledPinMANUAL, LOW); digitalWrite(ledPinAUTO, HIGH); motor_x1(); if (myStepper3.distanceToGo() == 0) digitalWrite(ledPinSTOP, HIGH); }
когда в функцию manual добавляю
if(digitalRead(buttonPinB_1) == state && flag_1 == 0) { regim_1 ++; flag_1 = 1; if(regim_1 > 1) // Если номер режима превышает требуемого { // то отсчет начинается с нуля regim_1 = 0; } } if(digitalRead(buttonPinB_1) == !state && flag_1 == 1) { flag_1 = 0; } // ======= ======= // РЕЖИМ 0: OFF if(regim_1 == 0) { motor_x1(); } // РЕЖИМ 1: R if(regim_1 == 1) { digitalWrite(ledPinD_1,HIGH); digitalWrite(ledPinSTOP, HIGH); }
для ручногоуправления тоже не продолжить движение,
не в паузу перейти.
Заранне благодарю за помощь.
Да и еще, запчасти еще в пути, моделирую в протеусе.
С нетерпением жду ответа.
вы не изучили библиотеку
сначала перепробуйте примеры и разбиритесь в них
надо помнить что в библиотеке некоторые функции блокирующие (в описании на сайте автора указано) и во время их выполнения нифига больше не работает
Все примеры перепробовал. В описании библиотеке сказано для продолжения движения
Stepper.run(); вызвать и здесь вообще непонятно
сколько не добавляй
myStepper1.run();
myStepper1.run();
myStepper1.run(); движения нет и цикл пробовал применять, толку нет, или чтото не так делаю
сначала научитесь кнопкой управлять одним шаговиком
потом пробуйте наращивать количество двигателей
ну и неполохо бы решить вопрос с дребезгом контактов кнопки
светодиоды потом уже подключайте когда всё будет работать как вам нужно
Защиту от дребезга убрал временно, она никак не влияла. С помощью Stepper.h проблем особых нет и одним управлял и шестью, а вот с акулой никак не разберусь. Одним управлял с помощбю примеров - тупик во всех примерах или один раз крутится или без остановок, не пойму в чем загвоздка, гдето явного не вижу
это хождение покругу уже достало
Защиту от дребезга убрал временно, она никак не влияла. С помощью Stepper.h проблем особых нет и одним управлял и шестью, а вот с акулой никак не разберусь. Одним управлял с помощбю примеров - тупик во всех примерах или один раз крутится или без остановок, не пойму в чем загвоздка, гдето явного не вижу
это хождение покругу уже достало
ну что ещё вам посоветовать - подключать мотор, кнопку и пробовать
блокирующие функции на двух моторах работать не будут
Как успехи? Не разобрались как можно повторять несколько раз одно вращение? Разбираюсь с этой же библиотекой, никак не могу понять логику этой функции (stepper.distanceToGo() == 0)
Как успехи? Не разобрались как можно повторять несколько раз одно вращение? Разбираюсь с этой же библиотекой, никак не могу понять логику этой функции (stepper.distanceToGo() == 0)
Подразобрался немного, как то так
Ура! Спасибо, заработало))
Ура! Спасибо, заработало))
Пожалуйста, с этой библиотекой еще разбираться и разбираться, эх, знаний не хватает.
Пока рулит метод научного ТЫКА.
AnLaz - это не то что работать, это даже компилироваться не должно
Уважаемый AnLaz - почитайте про библиотеку stepper. и сделайте несколько простеньких примеров (на 1 двигатель), а потом, если не получится задавайте конкретные вопросы, а не "что-то не учтено". Пока Вы в стадии теоретических рассуждений Вам здесь не помогут.
Прошу помощи. По задумке есть три режима у шагового двигателя. На каждом режиме он должен прокрутиться определенное количество шагов. Но при таком составлении скетча он вообще не вращается. Если без дополнительных функций, просто добавить в void loop
{
if (Stepper1.distanceToGo() == 0) //проверка, отработал ли двигатель предыдущее движение
}
то всё работает.
Не пойму почему не запускается мотор.
Нумбер_оф_регим меняется?
В строках #60 и #66 слова void лишние.
Да меняется, у меня светодиоды загораются по очереди.
Согласен void лишний . Но и на первом режиме не работает шаговик.
Надо смотреть через Serial, как distanceToGo() меняется.
distanceToGo() меняется от 10000 до 0 после того как начал вращаться.
maxSpeed > 1000 шаг/сек вообще-то к неадекватному поведению должен в аксельстеппере приводить.
Прошу помощи. По задумке есть три режима у шагового двигателя. На каждом режиме он должен прокрутиться определенное количество шагов. Но при таком составлении скетча он вообще не вращается. Если без дополнительных функций, просто добавить в void loop
{
if (Stepper1.distanceToGo() == 0) //проверка, отработал ли двигатель предыдущее движение
}
то всё работает.
Не пойму почему не запускается мотор.
нажали кнопку , запустили мотор и взвели флаг.
после окончания движения
if (Stepper1.distanceToGo() == 0)
флаг опускаем.
при поднятом флаге кнопка не фурычит.
и уменьшите скорость и увеличите ускорение.
когда отработаете - выставите как нужно
Не сильно понимаю как использовать флаги, но буду разбираться. Я ещё в самом начале своего пути программиста. Спасибо за помощь!
Тоже разбираюсь с управлением шаговиков. Хотел бы узнать какие у вас драйверы и схемы подключения к ним?
Что-то типа DRV8825 (у меня такие) и подобных ? Которым нужно подать только один сигнал с импульсами. Один импульс - один шаг и т.д.
Или какие-то другие?
Драйвер у меня из Китая такой TB6600. Ну подключил я как рекомендовал продавец драйвера. Скину фотку , если не понятно напишите я подскажу.
я тоже с аксельстеппером вожусь, документация у него не простая, примеры самые простые, кручу двумя моторами через А4988, в самом простом случае (один мотор крутится постоянно, подстроечником регулируем скорость)
но не могу понять как правильно выставить stepper1.setMaxSpeed , ставлю 1000, мотору явно мало импульсов в режиме 1\16, приходится 1\8 втыкать, а это вибрации сразу.
ставлю 2500, теряется линейность.
runSpeed() отказывается принимать аргументы, видимо я его не умею готовить.
жаль нет примеров применения :( не понимаю в каком контексте те или иные функции и классы используются :(
runSpeed() отказывается принимать аргументы, видимо я его не умею готовить.
жаль нет примеров применения :(
ConstantSpeed.ino
я кажется понял что не так, я использовал stepper1.run(); хотя я не указывал число шагов а указывал скорость движения, и для этого нужно установить stepper1.runSpeed(); , не увидел этого отличия в примерах, спасибо!
Есть подробное описание библиотеки AccelStepper на Русском?