Как управлять шаговым двигателем, и одновременно выполнять другие задачи?
Плата драйвера Polulo A4988
ожидает сигнала LOW -> ВЫСОКИЙ
импульс на цифровом выводе для включения шагового двигателя.
Простой способ создать импульс с задержкой, скажем, 100 мкс
, — использовать функцию delayMicroсекунды
:
#define STEP_PIN 3
#define DELAY 100
void setup(){
pinMode(STEP_PIN, OUTPUT);
}
void loop(){
//тяжелые вычисления, требующие времени
digitalWrite(STEP_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(DELAY);
}
Хотя это работает, проблема в том, что все время, которое процессор тратит на функцию delayMicroсекунды
, тратится впустую. Это значит, что если бы я захотел, например, обрабатывать входы с последовательной линии, у меня не было бы на это времени. Кроме того, время выполнения этих вычислений приведет к увеличению времени импульса, что не идеально, поскольку скорость шагового двигателя больше не будет одинаковой.
Как я могу эффективно подавать импульсы степперу в нужное время, оставляя при этом себе место для выполнения других задач между импульсами?
Ps Это для этого проекта: https://github.com/joeiddon/chess_robot.
@Joe Iddon, 👍0
Обсуждение1 ответ
Вместо того, чтобы делать задержку между импульсами, выполните цикл основной функции loop()
как можно быстрее, постоянно проверяя время, чтобы увидеть, стоит ли нам подавать импульс на двигатель. р>
Это означает, что вычисления могут выполняться в цикле (при условии, что они достаточно быстрые).
Для реализации этого можно использовать функцию micros()
для получения беззнакового значения long, представляющего микросекунды, прошедшие с момента запуска программы.
Затем в каждом цикле цикла нам нужно проверять, составляет ли разница между текущим временем и последним временем, когда мы подали импульс, >=
задержку импульса. В этом случае мы посылаем импульс на двигатель
Однако вместо установки переменной времени последнего импульса на текущее время мы увеличиваем переменную последнего импульса на время задержки. Это приводит к тому, что даже если мы немного опоздали с пульсацией , мы притворяемся, что действительно пульсировали в нужное время, чтобы они не смещались со временем.
Это будет выглядеть примерно так:
#define STEP_PIN 3
#define DELAY 100
uint32_t last_pulse;
void setup(){
pinMode(STEP_PIN, OUTPUT);
last_pulse = micros();
}
void loop(){
//тяжелые вычисления, требующие времени
if (micros() - last_pulse >= DELAY){
last_pulse += DELAY;
digitalWrite(STEP_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
}
}
Обратите внимание, что здесь есть небольшая тонкость: результат micros()
и, следовательно, значение last_pulse
переполнится после ~70
минут. Однако, поскольку мы берем разницу двух беззнаковых чисел, этот метод все равно будет работать, если micros()
никогда не опережает на целый цикл last_pulse
, который в практика никогда не будет иметь место.
- Шаговый двигатель не работает с платой A4988
- Шаговый двигатель работает медленно при чтении с датчика MPU 6050
- AccelStepper.h — Как быстро увеличить скорость двигателя NEMA 17?
- CD rom stepper нагревается
- Перегорают ли мои шаговые двигатели? В чем здесь проблема?
- Почему мой шаговый двигатель работает, когда я открываю последовательный порт?
- Использование драйвера шагового двигателя A4988 для малоточного (15 мА) шагового двигателя.
- Нужна помощь с независимым регулированием скорости на нескольких ступенях
Используйте библиотеку, которая генерирует импульсы за вас: https://www.airspayce.com/mikem/arduino/AccelStepper/ Какую плату Arduino вы используете?, @Jot
@Jot Я использую Arduino Nano. Что касается библиотеки, то меня больше интересует понимание того, как работает шаговое управление, а не конечный результат. :), @Joe Iddon
В этом случае вы могли бы взглянуть на исходный код [AccelStepper](https://github.com/adafruit/AccelStepper/blob/master/AccelStepper.cpp). При беглом взгляде кажется, что они используют тот же метод, который Джо Иддон описывает ниже, с некоторыми дополнениями, позволяющими увеличивать и уменьшать скорость двигателя. Совершенно другое решение — использовать таймер и таймер-прерывание для запуска кода через заданный интервал., @Gerben
@Gerben Спасибо за ссылку, я посмотрю на источник. Кроме того, система, управляемая прерываниями, звучит интересно, я об этом не подумал. Однако сейчас он работает хорошо, поэтому я сомневаюсь, что потрачу слишком много времени на его совершенствование. Хотя спасибо за вклад :), @Joe Iddon