Run a Nema 23 Stepper Motor Control for Set Amount of Time

Hi!
I am working on a project to create a dosing machine for an industrial application which requires running time and not positioning. In essence the user should be able to set the amount of time a stepper motor must run as well as the speed of the motor. In my project I have attached an Arduino Uno to a TB6600 stepper motor controller. The TB6600 is then connected to a Nema 23 stepper motor.
I have all the components working properly - I can set the speed and I can also set the time the motor must run - but I have one concern about the way I have programmed the stepper motor to run for a certain period of time that I was hoping someone could check and advise.

This is how I control the motor running time:

void loop() {

  if (digitalRead(startDosingButton) == HIGH) {   
 endMillis = millis () + (setTime * 1000);
    nowMillis = millis();

    while (nowMillis < endMillis) {
      nowMillis = millis ();
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(stepperDelay);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(stepperDelay);
    }

where setTime is a variable chosen by the user. The range the user can choose is between 0.1 and 5.
where stepperDelay is a variable also chosen by the user.

My concern relates to the Millis overflow. I’ve read a lot about this and I know when used like in the BlinkWithoutDelay the overflow is not an issue but I can’t seem to find any literature when used in a while function. Can anyone advise when used in this format whether the overflow is an issue? And if so, is there a better way to program an Arduino to run a stepper for a set amount of time using a TB6600 controller?

Thanks!

Your code won’t work at wrap-around:
This is the standard way, without wraparound issues

void loop() {

  if (digitalRead(startDosingButton) == HIGH) {   
    unsigned long duration = setTime * 1000;
    unsigned long startMillis = millis();

    while (millis() - startMillis < duration) {  // the subtraction here is vital.
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(stepperDelay);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(stepperDelay);
    }

The normal way to code this is without a blocking while loop at all:

void loop () 
{
  // state with global extent (lives between calls to loop()).
  static bool active = false ;
  static unsigned long start_time ;
  static unsigned long duration ;

  // handle button
  if (digitalRead(startDosingButton) == HIGH && !active)  // guard against repeated triggering
  {
    active = true ;   // initialize the stepping
    start_time = millis() ;
    duration = setTime * 1000;
  }
  
  // handle stepper
  if (active)
  {
    if (millis() - startMillis < duration)  // the subtraction here is vital.
    {
      digitalWrite(stepPin, HIGH);          // note you could also count steps here, possibly better
      delayMicroseconds(stepperDelay);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(stepperDelay);
    }
    else
      active = false ;  // timed out - so reset the active flag.
  }
}

Using a while loop like you have blocks anything else from progressing,
this way allows other things to happen (for instance a cancel button could
be simply added that set active flag to false).

Hi MarkT,

Thanks so much for the help!

I will implement and test.

Kind regards,

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.