# How do Arduino-based 3D-printers control several stepper motors at the same time?

I have been using an Arduino to control a stepper motor using an A4988 stepper driver.

The driver requires the direction and step signal to move the motor. The most straightforward method is to use a digitalWrite and delay to indicate the stepping. During this delay the Arduino is frozen and is not able to process other commands. I later realized that my 3D-printer also uses an Arduino and analogous stepper drivers to move all the motors at the same time.

How can Arduino-based 3D-printers with a minimum of 4 motors (x, y, z, extruder) control all motors at the same time?

It seems to me the Arduino is just not fast enough to use a delay()-based method to control 3D-printers, and I was under the impression common stepper libraries are based on the delay command.

• FYI, There are ways to "delay" without actually using delay(). Have you seen the "Blink Without Delay" examples?
– Bort
Apr 21 at 12:38
• You can look at the source for grbl and see exactly how its done. Apr 21 at 12:55
• There are ways to program Arduino hardware in much more efficient way than using the kindergarten Arduino IDE and libraries, utilizing its full power (which is much more than Arduino IDE is offering). There is Atmel Studio which one can use to write a "normal" FW for Arduino. Specifically one can directly control timers and write true real-time interrupt driven firmware. Apr 21 at 13:30

The delay() function is bad programming practice and it's unfortunate that it is taught to beginners.

  if(condition1) {                    // trigger
t1 = millis()                     // start time
}
if((millis() - t1) > timeDelay1) {  // elapsed time
// do something
}


The above code can be expanded to as many timers as you need. The rest of the program can continue to be scanned no matter how long the time delay is.

• That is simple and clean. Regarding millis(), "This number will overflow (go back to zero), after approximately 50 days" will the arduino run slightly slower on day 49 than on day 1 due to the large size of the function value, and any operations on that larger number? Apr 21 at 14:36
• You are correct about the 50 days. It's $2^{32} \ \text{ms}$. It doesn't take any longer to subtract any particular pair of 32-bit numbers. They're all the same size, 32-bits. If you think you can keep an Arduino going for 50 days without stop then you'll need to address the overflow in your code. See if baldengineer.com/arduino-how-do-you-reset-millis.html helps. Apr 21 at 14:49

During this delay the Arduino is frozen

The solution is don't delay if you need to do something.

Only call delay() when you have done all the things that need doing. and only delay the shortest amount you want to wait for the next thing you need to do.