Smooth Stepper Response to (x,y) Position Sensor

I have a sensor providing position feedback, which then drives the stepper to a targeted position.

My setup works, but as you can see in the video is very choppy. I believe at least part of the problem here is that my sensor location update and my stepper adjustments are happening in series.

I don't have much experience with coding, but it seems like I need a way for my motor and sensor update to be running in "parallel", or in a way that my stepper's target end-position can be updated while it is still moving to the previous target end position.

Ideas?

I have some other mechanical/accuracy issues to sort out with the setup as you might notice, but my first step is to figure out how to give it a more of an analog (smooth) control.

My setup:
-Nema 17 Stepper Motor.
-Arduino Uno Rev3
-30V Power Supply
-Big EasyDriver

You need to post your program. Without it we are reliant on our crystal balls.

Your description of your requirement is not very clear to me. Are you trying to stay focused on a moving object?

You should be aware that there are hundreds of different Nema 17 stepper motors. Post a link to the datasheet for your motor.

...R

Robin2:
You need to post your program. Without it we are reliant on our crystal balls.

Your description of your requirement is not very clear to me. Are you trying to stay focused on a moving object?

You should be aware that there are hundreds of different Nema 17 stepper motors. Post a link to the datasheet for your motor.

...R

Sorry, code below. It's pretty messy at the moment which is why I didn't dump it in the original post. Hoping my general description might be enough. I've updated my original post with a link to the motor being used...thought I had that on their originally.

Yes, the goal here is to stay focused on a moving object.

Your function MoveMotorForward() moves several steps without re-checking the position.

Try changing that function (and the backward function) so it only moves one step in the correct direction each time. There should be no need to change the code that calls the function.

Also, have a look at how the second example in this Simple Stepper Code does NOT use delay(). The time you are "wasting" with delay(500) could be better used getting another distance reading.

...R
Edit to add ... I just noticed it is delayMicroseconds(500) - apologies.

Robin2:
Your function MoveMotorForward() moves several steps without re-checking the position.

Try changing that function (and the backward function) so it only moves one step in the correct direction each time. There should be no need to change the code that calls the function.

Also, have a look at how the second example in this Simple Stepper Code does NOT use delay(). The time you are "wasting" with delay(500) could be better used getting another distance reading.

...R

The distance readings take ~40ms to process. So I don't see any path to single step the motor with that much delay to the next step. At least with the motor stepping at a reasonable speed.

This is why I was originally hoping to have a program where the motor's end position can be updated while it is already looping through to a previous position.

Maybe I'm asking too much from Arduino in this case? It seems like I need a muti-threading setup where both motor and sensor reads can be running their loops independently? What do you think?

marshallworrall:
The distance readings take ~40ms to process. So I don't see any path to single step the motor with that much delay to the next step. At least with the motor stepping at a reasonable speed.

This is why I was originally hoping to have a program where the motor's end position can be updated while it is already looping through to a previous position.

Sorry - I originally thought the delay was 500 millisecs.

I don't see an easy way to interleave the measurements and the motion unless you can break the process of getting a measurement into smaller parts that each take considerably less than the step interval.

If the step interval is always the same and just the need for a step and the direction change then you could use one of the HardwareTimers to cause an interrupt at the interval spacing. In the Interrupt Service Routine (ISR) you could check the direction and the number of steps still required and cause a step to happen if appropriate. That would make the updating of the distance asynchronous with respect to the motor movement. I'm thinking of an ISR like this

void nextStepISR() {
   if (numStepsRemaining > 0) {
     digitalWrite(directionPin, direction);
     digitalWrite(stepPin, HIGH);
     delayMicroseconds(10);  // this line may not be needed at all because digitalWrite() is quite slow
     digitalWrite(stepPin, LOW);
   }
}

...R

Robin2:
If the step interval is always the same and just the need for a step and the direction change then you could use one of the HardwareTimers to cause an interrupt at the interval spacing. In the Interrupt Service Routine (ISR) you could check the direction and the number of steps still required and cause a step to happen if appropriate. That would make the updating of the distance asynchronous with respect to the motor movement. I'm thinking of an ISR like this

void nextStepISR() {

if (numStepsRemaining > 0) {
    digitalWrite(directionPin, direction);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(10);  // this line may not be needed at all because digitalWrite() is quite slow
    digitalWrite(stepPin, LOW);
  }
}




...R

Awesome! That has helped a lot!! Took some reading up to learn how to work with ISRs, but that really smoothed out the system. Thanks for the advice.