stepper motor stutters

I am driving a set of four stepper motors with four Arduinos. Each stepper needs to run run at a different speed but should start and finish its motion at the same times. I am calculating the delay needed between each step as a sum of a millisecond delay and a microsecond delay. My problem is that sometimes the stepper motor "stutters", that is, misses a step. Seems like the code is non-deterministic and the Arduino gets busy doing something else. I am reading an encoder using interrupts at the same time, but the problem happens even if I omit the encoder. The problem is difficult to pin down. Sometimes the motion is perfectly smooth.

for(int i=0;i<numberSteps;i++){
digitalWrite(stepPin, HIGH);
delay(milliDelay); // millisecond delay (a long delay), for example 28 ms
delayMicroseconds(MSDelay); // microsecond delay (a short delay), for example, 320 us
digitalWrite(stepPin, LOW);
delay(stepDelay); // a quick delay between LOW and the next HIGH, 5 us
}

Thoughts?

stepper_and_encoder_example_UDP_messaging.ino (13.4 KB)

My thoughts:

  1. When I am dealing with stepper motors I always try to avoid:
    Delay(), Serial.print() and While() as these commands stop all other actions while they are being executed.

  2. I prefer the accelstepper library which also handles multiple steppers at the same time and is easy to set up.

trgentry:
I am reading an encoder using interrupts at the same time, but the problem happens even if I omit the encoder.

Thoughts?

Don't use delay() or delayMicroseconds(). Have a look at the second example in this Simple Stepper Code.

You really need to post a complete program.
Also tell us what stepper driver you are using; post a link to the datasheet for your stepper motor and give the details (volts and amps) of the motor power supply.

...R
Stepper Motor Basics

Thanks to you both. Complete code is attached to first message in the thread but is quite long. I am using the big easy stepper driver, no microstepping, and NEMA 17 gear-reduction stepper:

I think the libraries you are pointing me to will be helpful. Thanks again.

Sorry. I missed the attachment to your Original Post.

Now I have had a look at it it looks horribly complicated for what is probably a simple task.

I am not familiar with the UDP stuff so I don't know if any part of it might block for more than a few microseconds.

As I said earlier delay() is anathema to any program that needs to be responsive or that needs to keep time while other activities happen.

So is WHILE unless it is for some small thing that just takes a number of microseconds.

I can understand the attraction of lots of Serial.print() statements - but they are also relatively slow and may impede the necessary repeat frequency for loop().

You are using several libraries. Do not be surprised to find that there are incompatibilites among them. An Arduino has very few resources so it can be difficult or impossible to allocate them without conflicts. And many library authors don't even try.

Can you give an example of the sort of message that is sent by the PC?

I don't think you gave details of the motor power supply. That motor will need 20v or more to perform well.

...R

Now I have had a look at it it looks horribly complicated for what is probably a simple task.

Unfortunately it's not going to be simple. The motor part might be simple but there is a lot of other stuff going on (timing, encoder, strain sensor, ethernet).

I am not familiar with the UDP stuff so I don't know if any part of it might block for more than a few microseconds.

The code is written now so that the Arduino is not looking at the Ethernet board while the stepper is moving. But there might be some background traffic on the network that is slowing the stepper routine down. I will delete this code and see if that helps.

As I said earlier delay() is anathema to any program that needs to be responsive or that needs to keep time while other activities happen.

OK. I will try to re-write with the millisecond timer instead of delay.

I can understand the attraction of lots of Serial.print() statements - but they are also relatively slow and may impede the necessary repeat frequency for loop().

All that serial printing is debugging and I will take it out and see if that helps.

You are using several libraries. Do not be surprised to find that there are incompatibilites among them. An Arduino has very few resources so it can be difficult or impossible to allocate them without conflicts. And many library authors don't even try.

Libraries seem unavoidable but I will scour them for conflicts.

Can you give an example of the sort of message that is sent by the PC?

// An example string delivered to the Arduino over UDP looks like this:
// 99,0,1463159904,620,1,600,1,8

I don't think you gave details of the motor power supply. That motor will need 20v or more to perform well.

Good call. Specs say 12 to 24 volt supply. Currently using 12 volt supply but have others that I can try. No load on the stepper right now other than the encoder.

Here is a handy bit of code when your using Serial only for debugging.
Add these 2 lines at the top of your code.
Setting the first line to false completely removes Serial(and all those strings) from the compiled program.

#define DEBUG true                         // Set to true to enable Serial Debug
#define Serial if (DEBUG)Serial            // WARNING: Use only when Serial is used for Debugging only (THIS REMOVES Serial COMPLETLY!!!)

trgentry:
Unfortunately it's not going to be simple. The motor part might be simple but there is a lot of other stuff going on (timing, encoder, strain sensor, ethernet).

I still suspect the code could be simplified by organizing each part into its own function so that each piece can be tested separately. I reckon the code in loop() can be reduced to something like

void loop() {
    readUDP();
    readSensor();
    updatePositionFromEncoder();
    calculateMotorMove();
    moveMotor();
}

...R

Thank you Hutkilz, that's pretty cool. Robin, I agree. I will change out the power supply and strip some stuff out to see if I get the motor fixed. I am away from my lab for two weeks, but will report back. Thanks for your help.