Arduino UNO + шаговый двигатель
- Войдите на сайт для отправки комментариев
Здравствуйте!
Подскажите, пожалуйста. Есть задача: нужно крутить шаговым мотором, посылая команды (сколько сделать шагов), через COM порт. Потом, как только мы нажали на концевик - мотор остановился. Как только отпустили концевик мотор прошёл еще сколько-то заданных шагов через COM порт.
Получилось закрутить мотор, но он проезжает 2,5 оборота максимум. Посылаю через COM порт 12800 шагов (один оборот) - делает. Посылаю 38400(3 оборота) - делает только 2,5. Больше не делает.
1)Это первая проблема.
2)Вторая - как останвить мотор?
Я подсоеденил концевик и провери работу на светодиоде - всё работает. Нажимаешь - горит. Отпускаешь - тухнет.
А с мотором не получается. Может есть команда которая останавливает мотор?
Через полчаса группа ЭКСТРАСЕНСОВ займется вашей проблемой...
Может и есть такая команда, да никто пока не знает, как (программно) Вы управляете мотором. Есть еще вариант: послали команду сделать 1/5/10/100 шагов - проверили состояние концевика - опять послали - опять проверили - опять послали, или не послали - мотор остановился.
#include <Stepper.h> #define STEPS 12800 //800 шагов на оборот (но установили микрошаг получилось 12800) int steps; int btnPin = 7; // pin кнопки int dirPin = 8; // pin вкл мотора int btnval=0; Stepper stepper(STEPS, 2, 5); //pin которые через плату работают void setup(){ stepper.setSpeed(10); // установили скорость pinMode(dirPin, OUTPUT); pinMode(btnPin, INPUT); // а это вход - кнопка Serial.begin(9600); } void loop() { stepper.step(34000); // шагов должен сделать // delay(1000); // if (Serial.available()){ // steps = Serial.parseInt(); // stepper.step(steps); //через монитор com порта задаем сколько шагов должен сделать // } btnval = digitalRead(btnPin); // узнаём состояние кнопки if(btnval == HIGH) // кнопка нажата { stepper.setSpeed(0); // мотор остановился, и вот проблема что же делать когда отпустили кнопку, скорость в 0 } // else // кнопка не нажата // { // if (Serial.available()){ // steps = Serial.parseInt(); // stepper.step(steps); // } }Если хотите управлять шаговым двигателем в реальном времени - забудьте про библиотеки. Особенно stepper.
И каким образом управлять? Писать на C? Я новичок в этом деле.
Первое что насторожило: "12800 шагов один оборот".
32767 шагов - 2,559921875 оборота, что очень близко к указанным Вами 2.5.
Так что при таких запросах вместо int нужно пользоваться long.
Но, в принципе, правильно подсказываю: нужно крутить маленикими порциями и проверять, не пора ли останавливать. Возможно, так и int будет достаточно.
12800 шагов (один оборот) - а что это за дробление шага?
800 шагов на оборот- это без дробления. Поставил дробление 16, поэтому и 12800.
Но, в принципе, правильно подсказываю: нужно крутить маленикими порциями и проверять, не пора ли останавливать. Возможно, так и int будет достаточно.
А как опрашивать не подскажите?
Смотря какой драйвер шаговый используется. Бывают импульсами управляются. Если не секрет зачем такая точность? Управление оптикой?
Алгоритм такой:
1. сделал шаг
2. проверил сигнал стоп
3. Если сигнала стоп нет, вернуться к пункту 1
Команду на вращение вы тоже на С пишете. Здесь будет на пару команд больше.
То есть можно в sketch писать на С или С++ и ардуиновскими библиотеками? И всё в перемешку?
Да для оптики. Вот такая штуковина http://ru.aliexpress.com/item/New-UNO-R3-Board-CNC-Shield-Expansion-Board-4-x-A4988-Stepper-Motor-Driver-with-Heat/32467589482.html?spm=2114.031020208.3.1.87379Q&ws_ab_test=searchweb201556_2_79_78_77_91_80,searchweb201644_5,searchweb201560_9
Мне просто нужно остановить шаговый мотор при нажатии на концевик. Не понятно почему в стандартной библиотеке нет остановки мотора.
(Получилось закрутить мотор, но он проезжает 2,5 оборота максимум. Посылаю через COM порт 12800 шагов (один оборот) - делает. Посылаю 38400(3 оборота) - делает только 2,5. Больше не делает.)
Может проблема в - int steps; Данная переменная больше 32767 не примет а у Вас на один оборот 12800, отсюда имеем 2,5 оборота
Попробовал поставить long steps вместо int. Не помогло.
800 шагов на оборот- это без дробления. Поставил дробление 16, поэтому и 12800.
а что за двигатель с таким разрешением - 800 на оборот
Мне сложно сказать. Это китайский. http://kapanadze.zipkatalog.ru/bedini-iz-shagovogo-dvigatelya.html В разрезе типа такого.
(Потом, как только мы нажали на концевик - мотор остановился. Как только отпустили концевик мотор прошёл еще сколько-то заданных шагов через COM порт.)
Можно попробовать сделать "обманку", алгоритм такой:
1) Достигли концевика и он тупо отрубил питание от шаговика подав сигнал на контролер
2) В порт Вы ввели нужное количество шагов нажали ЕНТЕР сработало реле, заблокировало концевик и шаговик отработал, реле-of
А вообще шаговики нужны для позиционирования по количеству шагов, а концевики ему нужны для калибровки и чтобы в случае сбоя не выехать из рабочго поля. Если работать по концевикам то можно использовать простой двигатель: задал скорость направление и ждешь сработки концевика
http://roboforum.ru/forum86/topic14992.html
Первая же ссылка в яндексе. Там пример прямого управления этим драйвером напрямую.
Мне и нужен концевик для "0" пункта(калибровка). Т.е. мотор едет, например, 500 шагов, потом касается концевика и останавливается. Для мотора это и будет "0" пункт. А потом от него сколько нужно уже столько и движемся.
Програмно нужно делать через прерывание. Ваш код на правильность я не проверял но в нево вставил алгоритм прерывания, как я его вижу. Посмотрите може Вам подойдет. Переключите с 2 на 3 Stepper stepper(STEPS, 3, 5); //pin которые через плату работают
#include <Stepper.h> #define STEPS 12800 //800 шагов на оборот (но установили микрошаг получилось 12800) uint16_t steps; int btnPin = 2; // pin кнопки int dirPin = 8; // pin вкл мотора int btnval = 0; bool stop = 0; //Флаг что достигли концевика Stepper stepper(STEPS, 3, 5); //pin которые через плату работают void setup() { stepper.setSpeed(10); // установили скорость pinMode(dirPin, OUTPUT); pinMode(btnPin, INPUT); // а это вход - кнопка attachInterrupt (0, pinChange, CHANGE); // подключаем обработчик прерывания Serial.begin(9600); } // Функция обработки прерывания (ISR) void pinChange () { stop = 1; //Достигли концевика сработало прерывание } void loop() { if (Serial.available()) { //через монитор com порта задаем сколько шагов должен сделать steps = Serial.parseInt(); stop = 0; for (uint16_t i; i < steps ; ++i)// Переменой задаем cчитаное из com количество шагов для движения { stepper.step(1);// Делаем один шаг if (stop) //Проверяем есть ли прерывание если да выходим из цыкла { stop = 0; break; } } } }Спасибо! Буду пробовать! У меня получилось без библиотеки stepper, посмотрев на драйвера A4988 Stepper Motor Driver Carrier Board
Нашел такой скетч.
#include <AccelStepper.h> #define HALFSTEP 8 #define motorPin1 8 // IN1 on ULN2003 ==> Blue on 28BYJ-48 #define motorPin2 9 // IN2 on ULN2004 ==> Pink on 28BYJ-48 #define motorPin3 10 // IN3 on ULN2003 ==> Yellow on 28BYJ-48 #define motorPin4 11 // IN4 on ULN2003 ==> Orange on 28BYJ-48 int endPoint = 1024; // Move this many steps; 1024 = approx 1/4 turn // NOTE: The sequence 1-3-2-4 is required for proper sequencing of 28BYJ-48 AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4); volatile boolean stopNow = false; // flag for Interrupt Service routine int cycleCount = 0; // counter for endpoint cycles boolean homed = false; // flag to indicate when motor is homed void setup() { attachInterrupt(0, intService, LOW); // Enable interrupt 0, switch pulled low Serial.begin(9600); Serial.println(stepper1.currentPosition()); delay(5000); stepper1.setMaxSpeed(1000.0); stepper1.setAcceleration(100.0); stepper1.setSpeed(200); stepper1.moveTo(endPoint); } void loop() { if (stopNow) { detachInterrupt(0); // Interrupt not needed again (for the moment) Serial.print("Interrupted at "); Serial.println(stepper1.currentPosition()); stepper1.stop(); stepper1.setCurrentPosition(0); Serial.print("position established at home..."); Serial.println(stepper1.currentPosition()); stopNow = false; // Prevents repeated execution of the above code homed = true; } else if (stepper1.distanceToGo() == 0 && !homed) //executed repeatedly until we hit the limitswitch { Serial.println(stepper1.currentPosition()); stepper1.setCurrentPosition(0); stepper1.moveTo(endPoint); cycleCount ++; Serial.print("cycle count = "); Serial.println(cycleCount); Serial.println(stepper1.currentPosition()); } stepper1.run(); if(homed) { Serial.println("I am homed"); //Prints continually once homed } } // // Interrupt service routine for INT 0 // void intService() { stopNow = true; // Set flag to show Interrupt recognised and then stop the motor }Набор: Уно, драйвер L298n, двиг 28BYJ-48 в биполярном режиме (перезанная дорожка) включен по схеме из скетча.
То есть - При включении питания пришел к концевику... стоп. Ок. А что дальше?
Теперь "сынок, иди работать..." А мне всего то нужно:
Если на пин12 - 0 то стоять никуда не ходить! Если там вдруг объявится -1 то шагать 2000 и там стоять пока пин12 не станет в 0. Продолжать.
Помогите разобраться?
И еще бы заставить с любого положения пройти половину...