Помогите разобраться с библиотекой AccelStepper
- Войдите на сайт для отправки комментариев
Здравствуйте!
Никак не могу понять логику работы с этой библиотекой. А именно, как работает .run() В документации сказано, что для продолжения работы двигателя run() должна выполняться непрерывно. С примерами всё ясно и они работают. В них run() находится в loop, кроме него там ничего нет, поэтому условие непрерывного выполнения удовлетворяется.
Но в реальной задаче ситуация другая. Скетч парсит g-code с com-порта:
#include <AccelStepper.h> #define MAX_BUF (64) char buffer[MAX_BUF]; // where we store the message until we get a newline int sofar; // how much is in the buffer AccelStepper Zaxis(1, 4, 7); float parsenumber(char code,float val) { char *ptr=buffer; while(ptr && *ptr && ptr<buffer+sofar) { if(*ptr==code) { return atof(ptr+1); } ptr=strchr(ptr,' ')+1; } return val; } void processCommand() { int cmd = parsenumber('G',-1); switch(cmd) { case 1: Zaxis.setSpeed(1600*parsenumber('F',0)/60); Zaxis.move(1600*parsenumber('Z',0)); Zaxis.runSpeed(); //Serial.print(parsenumber('F',0)); //Serial.print(parsenumber('Z',0)); break; default: break; } } void setup() { Serial.begin(115200); sofar=0; Zaxis.setMaxSpeed(12000); Zaxis.setAcceleration(16000); } void loop() { // listen for serial commands while(Serial.available() > 0) { // if something is available char c=Serial.read(); // get it //Serial.print(c); // repeat it back so I know you got the message if(sofar<MAX_BUF-1) buffer[sofar++]=c; // store it if((c=='\n') || (c == '\r')) { // entire message received buffer[sofar]=0; // end the buffer so string functions work right //Serial.print(F("\r\n")); // echo a return character for humans processCommand(); Serial.print("ok\n"); sofar=0; } } }
В loop мы слушаем порт, если что-то появилось, вызываем функцию processCommand(), которая парсит полученное с помощью parsenumber() и должна выполнить полученную команду g-code.
Например, G1 Z10 F200. Переместиться на 10 мм по +Z со скоростью 200 мм/мин.
Парсится всё правильно, setSpeed() и move() получают нужные значения. Одна проблема: как теперь выполнять комаду run() непрерывно? Получается, что она выполняется однократно. И действительно, рукой можно почувствовать, что на один шаг двигатель всё же срабатывает при получении g-code. Как сделать, чтобы двигатель отработал всё перемещение?
Спасибо!
Я не знаком с данной конкретной бибилиотекой, но общий подход в аналогичных случаях таков :
43 if (Serial.available() >0) { ...
56 };
57 Zaxis.runSpeed(); // добавляем это строчку внутрь основного цикла, но вне условия
Спасибо!
Увы, но теперь появилась новая проблема. При отрицательных значениях перемещения двигатель делает несколько оборотов в противоположную сторону, затем уже отрабатывает перемещение в нужную сторону. При положительных значениях всё работает правильно.
Проблема присутствует даже на простейшем тестовом скече:
Железо Arduino UNO + CNC shild + A4988 + NEMA 17 0.9. Делитель выставлен на 1/16. Связка прекрасно работает с прошивкой grbl.
В чем может быть проблема?
внимательно посмотрите примеры
у вас совсем по другому написано
Переменная или константа используемая как шаговая координата в этой библиотеке должна быть типа long.
Большой недостаток данной библиотеки - работа с быстрыми перемещениями, если мотор должен шагать чаще чем вы обращаетесь к stepper.run, движение мотора будет рывками.
Переменная или константа используемая как шаговая координата в этой библиотеке должна быть типа long.
Большой недостаток данной библиотеки - работа с быстрыми перемещениями, если мотор должен шагать чаще чем вы обращаетесь к stepper.run, движение мотора будет рывками.
Ясно, буду разбираться. А есть какая-нибудь достойная альтернатива этой библиотеке? Для моей задачи Accel избыточна. Мне нужно управлять только одним шаговым двигателем, но максимально точно и плавно.
Поиск ничего не дал.
"Плавно" - это с ускорениями ?
Я брал эту библиотеку, и вешал на прерывание. Из самой библиотеки выьрасывал контроль таймингов.
Вот тут посмотрите : http://arduino.ru/forum/programmirovanie/opyat-shagovik#comment-227068
Правда там я еще подменяю процедуры обработки шагов, но это не обязательно, просто мне так было удобнее.
"Плавно" - это с ускорениями ?
Да
Глюк проявляется, когда setSpeed() находится в loop. Если перенести его в setup, тогда нормально. Как только пользоваться этой библиотекой, если скорость необходимо переопределять? Очень бы хотелось от нее отказаться.
Что значит переопределять скорость?
Скорость очередного перемещения берется из g-code с com-порта. Её нельзя раз и навсегда забить в setup.
Здравствуйте. Я запустил библиотеку AccelStepper все работает все хорошо. Но когда я вставил библиотеку OneWire для измерения температуры у меня моторчик стал некорректно работать. Кто знает как решить эту проблему? Помогите пожалуйста очень нужно. Спасибо заранее!
Здравствуйте. Я запустил библиотеку AccelStepper все работает все хорошо. Но когда я вставил библиотеку OneWire для измерения температуры у меня моторчик стал некорректно работать. Кто знает как решить эту проблему? Помогите пожалуйста очень нужно. Спасибо заранее!
наверно у вас применяются задержки при измерении температуры, вот и тормоза
.run() выполняет перемещение строго на один импульс ( = поворот вала на угол 1,8 градуса, при соотношении в драйвере 1:1). Следовательно, если надо переместить (повернуть) на 180 градусов, надо сделать 100 шагов, т.е. 100 раз запустить этот .run()
Для равномерности движения надо это делать без времязатратных операций, т.е. если во время выполнения этого цикла запустится что-то иное (отрисовка цифры, измерение чего-то), то ШД на это мгновение будет замирать. Выход есть - использовать прерывания, но вначале научитесь использовать основное - выполнение операции перемещения до конца, даже если будут замирания.
Отказался от AccelStepper в пользу форка https://github.com/achest/stepperQ
Работает по прерываниям. Свою задачу уже реализовал. Рекомендую.