How to make code non blocking?

I'm planning to control multiple stepper motors but my code currently uses delayMicroseconds() to change the delay frequency between each step which blocks the program to be stuck until the stepper has finished the loop so I can't run a second motor until the first one finishes.

}#define dir1 2
#define pul1 3

void setup() {
  pinMode(dir1, OUTPUT);
  pinMode(pul1, OUTPUT);

  moveStepper(true, 6400, 50);
}

void loop() {

}

void moveStepper(bool dir, int steps, int interval) {
  digitalWrite(dir1, dir);
  for (int i = 0; i < steps; i++) {
    digitalWrite(pul1, LOW);
    digitalWrite(pul1, HIGH);
    delayMicroseconds(interval);
  }
}

So essentially in my moveStepper method it gets fed dir the direction, steps the number of steps the stepper will make and interval which is the delay before the for loop goes to the next iteration or "step" basically controlling the speed of the stepper. I have tried using micros() instead of delayMicroseconds() but haven't had much luck getting it work. Any help is highly appreciated.

Hello kugelnova

Welcome to the best Arduino Forum ever :wink:

Take a view to get some ideas:

1 Like

Try not to use "for()" loops... rather, call a single-step function "6400" times using "event timing." That is to say, call the "moveStepper()" function at specific time intervals. The shorter the interval, the faster the function is called again.

Add these variables before "setup()"

int counter, count = 6400; // count the steps
unsigned long timer, timeout = 10; // 1000 / 10 = 100 steps per second

comment-out the call to "moveStepper()" in "setup()"

  // moveStepper(true, 6400, 50);

Add this event timer to your "loop()"

  if ((millis() - timer > timeout) && (counter < count)) { // check event time and step count
    timer = millis(); // reset time
    moveStepper(true, 1, 50); // step CW, 1 step, 50us between LOW and HIGH
    counter++; // count to 6400
  }

Finally, remove the "for()" loop from the function "moveStepper()" so it can be a "one-step" function.

void moveStepper(bool dir, int steps, int interval) {
  digitalWrite(dir1, dir);
  digitalWrite(pul1, LOW);
  delayMicroseconds(interval);
  digitalWrite(pul1, HIGH);
  // this delay is done by waiting for the next event
}
1 Like

HI @kugelnova

welcome to the arduino-forum

Well done to post your code as a code-section in yout first post.

There is a much more comfortable solution. A library with which you can run multiple stepper-motors all at the same time at different speeds and doing various other things in your code in "parallel".

This library creates the stepper-pulses based on a timer-interrupt in the background.
Your main-code is interrupted automatically regardless of what yourt code is doing at the moment. You don't have to care about it. And then the stepper-code creates the step-pulses in the background.

This library is called MobaTools. Hard to find name when searching for stepper-motor-libraries.

You start a movement of any amount of steps (even millions of steps) and the rest is done by the library in the background.

You can install this library with the library-manager of the arduino-IDE

The function-calls have different names than for stepper.h
If you have any questions you can ask here on the forum. Even the author of the library is active in this forum.

The library offers even more functions to slowly drive RC-servos and for buttons and timers.

There is one limitation for this library:
If you want to run multiple stepper-motors in sync to each single step this library can't do this.

You will have to implement the so called bresenham-algorithm for doing this.

So it will be very good if you post a description of your project.

Any kind of CNC-mill, CNC-engraver, CNC-foil-cutter, 3D-printer requires step-synchronisation down to each single step = bresenham-algorithm.

1 Like

i agree with Stefan's suggestion, but if that's too big a step, you could create a block os code that checks a target position for each motor and generates a step pulse for it if the current position is not equal. All the motors that need to step would be clocked at the same time, there would only be one "pair" of delays for all the motors that step

outside of that block would be code that determines the target position for each motor

1 Like

As you try different methods for controlling the stepper motor (and you should), you will see the higher usage of program memory when using libraries, and sometimes restrictions on other devices, versus a handful of lines of code that I presented, that is expandable to controlling many motors without adding more code and without taking more memory. Try as many libraries as you can find. Learn what works for you. Novacula Occami.

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