Accelstepper: отсутствует синхронизация в простой тестовой программе

У меня есть следующий тестовый код, который я запускаю на Arduino Yùn. К Arduino подключены только PulCyan и DirCyan, все остальные контакты не подключены (кроме заземления).

Если я запущу эту программу, я ожидаю остановки на 500 мс, когда положение единственного подключенного двигателя (stepperCyan) достигнет 0.

Однако я вижу, что когда он достигает позиции 0, он останавливается, затем делает 1 шаг и снова останавливается, а затем переходит на -200 и так далее...

Как это возможно? Я совершенно запутался. (код обновлён благодаря ответам ниже, но всё ещё не работает так, как описано ранее)

#include <AccelStepper.h>
 
// Define a stepper and the pins it will use
//Stepper motors

int pulYellow = 30;     //N/A on Yùn
int dirYellow = 31;     //N/A on Yùn
//int enaYellow = 32;   //N/A on Yùn
int pulMagenta = 33;    //N/A on Yùn
int dirMagenta = 34;    //N/A on Yùn
//int enaMagenta = 35;  //N/A on Yùn
int pulCyan = 4;   //36 MEGA
int dirCyan = 8;   //37 MEGA
//int enaCyan = 38;   //N/A on Yùn
AccelStepper stepperMagenta(AccelStepper::DRIVER, pulMagenta, dirMagenta);
AccelStepper stepperYellow(AccelStepper::DRIVER, pulYellow, dirYellow);
AccelStepper stepperCyan(AccelStepper::DRIVER, pulCyan, dirCyan);

unsigned long previousMillis = 0;  // will store last time LED was updated
const long interval =500;
void setup()
{  
  // Change these to suit your stepper if you want
  stepperMagenta.setPinsInverted(true, true, true);
  stepperYellow.setPinsInverted(false, false, false);
  stepperCyan.setPinsInverted(true, true, true);
  stepperMagenta.setMinPulseWidth(20);
  stepperYellow.setMinPulseWidth(20);
  stepperCyan.setMinPulseWidth(20);
  stepperMagenta.setMaxSpeed(400);
  stepperMagenta.setAcceleration(200);
  stepperMagenta.moveTo(200);
  stepperYellow.setMaxSpeed(400);
  stepperYellow.setAcceleration(200);
  stepperYellow.moveTo(200);
  stepperCyan.setMaxSpeed(400);
  stepperCyan.setAcceleration(200);
  stepperCyan.moveTo(200);
}
 
void loop()
{
    if (stepperMagenta.currentPosition() == 200 && stepperMagenta.distanceToGo() == 0)
      stepperMagenta.moveTo(0);
    if (stepperMagenta.currentPosition() == 0  && stepperMagenta.distanceToGo() == 0){
      delay(500);
      stepperMagenta.moveTo(-200); 
    } 
    if (stepperMagenta.currentPosition() == -200  && stepperMagenta.distanceToGo() == 0)
      stepperMagenta.moveTo(200);
//-------
    if (stepperYellow.currentPosition() == 200  && stepperYellow.distanceToGo() == 0)
      stepperYellow.moveTo(0);
    if (stepperYellow.currentPosition() == 0  && stepperYellow.distanceToGo() == 0){
      delay(500);
      stepperYellow.moveTo(-200); 
    } 
    if (stepperYellow.currentPosition() == -200   && stepperYellow.distanceToGo() == 0)
      stepperYellow.moveTo(200);
//-------
    if (stepperCyan.currentPosition() == 200 && stepperCyan.distanceToGo() == 0)
      stepperCyan.moveTo(0);
    if (stepperCyan.currentPosition() == 0 && stepperCyan.distanceToGo() == 0){
      delay(500);
      stepperCyan.moveTo(-200); 
    } 
    if (stepperCyan.currentPosition() == -200 && stepperCyan.distanceToGo() == 0)
      stepperCyan.moveTo(200);
//-------      
    stepperMagenta.run();
    stepperYellow.run();
    stepperCyan.run();  
}

, 👍1

Обсуждение

Задержка (500) приостанавливает выполнение цикла loop(). В это время состояние шагового двигателя не обновляется, поскольку метод stepperCyan.run() не вызывается., @liaifat85


1 ответ


Лучший ответ:

1

Не так следует использовать AccelStepper. Метод run() не всегда выполняет шаг. И он не ждёт, когда шаг будет выполнен. Вместо этого он проверяет, настало ли время выполнить шаг. Если да, то он это делает, если нет, то быстро завершает работу. Поэтому вам нужно вызывать run() как минимум с частотой ваших шагов (определяемой скоростью). Функция delay() мешает библиотеке AccelStepper выполнять шаги, что приводит к сбоям.

Если вы хотите остановиться в позиции 0, вы должны позволить шаговому механизму дойти до этой позиции (через moveTo(0)), затем подождать 500 мс, а затем перейти в следующую позицию (через moveTo(-200), например).

Еще лучше: вместо использования delay(500) используйте функцию millis(), как в примере BlinkWithoutDelay (поставляется с Arduino IDE), чтобы засекать время следующего изменения положения, не блокируя при этом выполнение другого кода.

,

Я пытался следовать вашим подсказкам, но всё равно делает двойную остановку. (Я не знаю, как использовать millis(), извините). Новый код, который я написал для каждого шагового двигателя в вопросе, @Luigi

@Luigi В обновлённом коде в операторах if используются одинарные символы &. Это опечатка? Для логического «И» нужно && (то есть двойной &)., @chrisl

Спасибо, это была опечатка. Изменил, но задержка всё равно 500 мс, небольшой шаг и снова задержка 500 мс., @Luigi