Accelstepper.runToPosition() работает нормально. Accelstepper.run() ничего не делает

У меня есть сложный скетч с Arduino Uno, последовательный Com Bluetooth с использованием AltSoftSerial, последовательный com с использованием SoftwareSerial и последовательной связи с ПК.

Я хочу переместить один шаговый двигатель и остановить его при получении сигнала. Я использую драйвер A4988 Pololu и биполярный шаговый двигатель NEMA 17.

Этот код работает нормально. MyStepper.moveTo(позиция); MyStepper.runToPosition();

Если я изменю код на MyStepper.moveTo(позиция); MyStepper.run(); чтобы запуск не блокировал мой код, двигатель ничего не делает Абсолютно никакого движения.

Заземление источника питания двигателя соединено с заземлением Arduino. Двигатель отлично работает при блокировке движений.

, 👍0

Обсуждение

прочитайте документацию библиотеки для функции run (), @jsotola


2 ответа


-1

Проблема заключается в блокировке задержек. Функция запуска прерывается любым другим действием программы. Так что вам приходится звонить ему все время. В цикле требуется вызов run, и я написал простую функцию mydelay, которая решает проблему, если вам нужно использовать задержку для связи по Bluetooth или других целей.

int mydelay(int j) { 
  long endmillis;
  endmillis = millis() + j;
  while (millis() < endmillis) {
  MyStepper.run();
  }

Я надеюсь, что помогу кому-нибудь, потому что мне, новичку в Arduino, потребовалось некоторое время, чтобы разобраться в этом.

,

я отклонил ваш ответ, потому что вы написали блокирующую функцию для решения проблемы, вызванной другой блокирующей функцией ..... это может сработать для вас, и это здорово, но следует избегать блокирующих функций .... я поддержал ваш вопрос, потому что вы решили его самостоятельно ...... также, ваше решение страдает от "ошибки опрокидывания", и оно может испортиться после 49-дневного запуска ..... читать https://arduinoprosto.ru/q/12587/how-can-i-handle-the-millis-rollover, @jsotola

В моем случае мне нужно дождаться, пока Bluetooth отправит целую строку. Если я отправлю строку "12345", if bluetoothserial.available() перехватит 1, возможно, 2, потеряет 3 4 5, которые прибудут через несколько мс. Мне нужна небольшая задержка около 10 мс. Мое устройство никогда не будет работать в течение 50 дней, пока таймер часов не будет сброшен. В любом случае, это было решением моей проблемы, и мне удалось переместить степпер, управляемый мобильным устройством, он движется плавно, и пока он движется, я могу изменить положение цели, и он изменит свое направление с соответствующими ускорениями. Я действительно не мог найти лучшего способа и много искал., @Dimitris

вот почему я сказал, что это здорово, что это работает для вас .... причина снижения в том, что другие люди проведут исследование проблемы, которая у них может возникнуть, и найдут ваш ответ ..... важно, чтобы они подумали о возможных проблемах, если они примут ваш решение, @jsotola

о связи по Bluetooth ..... если вы отправляете "12345", есть ли в конце строки символ конца строки, например, CR или NL?, @jsotola

Да, есть 12345 #. Иногда я отправляю большие строки GOTO#1500 #. @jsotola Ваш вопрос заставил меня задуматься, и я попытался убрать задержку и читать до тех пор, пока не будет получен #. Сначала это не сработало, затем я добавил while incoming!="#", если Bluetooth доступен, считайте входящие, и это работает. Я пытаюсь добавить код в комментарий, но Ctrl + K не работает, поэтому я пока не буду добавлять код., @Dimitris


2

Вы не включили никакого кода, чтобы мы могли увидеть, в чем собственно проблема, но я готов предположить, что вы не приняли во внимание, что команда run требует повторного запуска.

Если ваша программа доходит до точки, где есть экземпляр runToPosition , функция блокировки останавливает программу до тех пор, пока шаговый движок не достигнет указанной позиции.

Когда ваша программа переходит к экземпляру run(), она запускает импульс и продолжает чтение. Таким образом, вы должны использовать цикл.

stepperMotor.moveTo(3000);
stepperMotor.runToPosition();
// достигает пункта назначения

stepperMotor.moveTo(3000);
stepperMotor.run();
// перемещается на один шаг

stepperMotor.moveTo(3000);
while (stepperMotor.distanceToGo > 0) {
stepperMotor.run();
}
// достигает пункта назначения

Причина, по которой вы бы использовали run поверх runToPosition, заключается в том, чтобы разрешить выполнение непрерывных операций / параметров. Например, два шаговых двигателя, работающих одновременно:

stepperMotor1.moveTo(5000);
stepperMotor2.moveTo(3000);
while ((stepperMotor1.distanceToGo > 0) && (stepperMotor2.distanceToGo > 0)) {
stepperMotor1.run();
stepperMotor2.run();
}
// Оба двигателя будут работать, но оба остановятся, когда любой из них достигнет места назначения.

В зависимости от скорости вашего микропроцессора вы можете создать несколько сложных наборов команд для вашего двигателя (двигателей).

,