High Resolution Stepper Motor Speed Control

Hey guys,

I don't have any experience with Arduino and only very limited experience with microcontroller. I have to fix a device that is run by two stepper motors. The key to my problem is speed control of the steppers. My max speed is 1.25 rev/s. Someone coded up the Arduino before but what I have noticed is that there is no actual speed control in the code. I only have 1.25, (1/2)*1.25, (1/4)*1.25, (1/8)*1.25, (1/16)*1.25, and (1/32)*1.25. The gap between these speeds is just so huge, specially at higher speeds and I need to reduce these gaps as much as possible. I also noticed that the setSpeed function does almost the same thing! What can I do about this? The board is mega 2560 and the motors each have 200 steps per revolution. Any comment would be helpful. Thank you all in advance!

Do you have the source code?

Yes I have the code but it’s a very long one and I can’t figure out which parts of the code actually control the stepper speed.
Here is the part of the code that does step modification:

void setDelay() {
if(stepperSpeed == 0) {
step_delay = 1000000000;
}
else {
double tempDelay = double(1.25) / double(stepperSpeed);
step_delay = tempDelay;
}
return;
}

// Returns stepperSpeed using a given value for delay
double setSpeedFromDelay(double delayVal) const {
return double(1.25) / delayVal;
}

// Returns step_delay value
double getDelay() const {
return step_delay;
}

// Move the motor forward or backward
void step1(unsigned long &stepperTimeNew, unsigned long &stepperTimeOld) {
stepperTimeNew = millis();
if(step_number == 30000) {
step_number = 0;
}

// move only if the appropriate delay has passed:
if (double(stepperTimeNew - stepperTimeOld) >= step_delay && stepperSpeed != 0 && !checkOn()) {
// depending on direction:
if (neg == 1) {
stepMotor(step_number % 4);
}
else {
stepMotor(3 - (step_number % 4));
}
stepperTimeOld = stepperTimeNew;
step_number++;
}
return;
}

// Selects appropriate number of fraction steps to take based upon maximum speed
void selectStepMode() {
if(step_delay <= 1) {
// No step modification
digitalWrite(mode_pin1, LOW);
digitalWrite(mode_pin2, LOW);
digitalWrite(mode_pin3, LOW);
}
else if(step_delay <= 2) {
// Half step
digitalWrite(mode_pin1, HIGH);
digitalWrite(mode_pin2, LOW);
digitalWrite(mode_pin3, LOW);
step_delay = step_delay / 2;
}
else if(step_delay <= 4) {
// Quarter step
digitalWrite(mode_pin1, LOW);
digitalWrite(mode_pin2, HIGH);
digitalWrite(mode_pin3, LOW);
step_delay = step_delay / 4;
}
else if(step_delay <= 8) {
// Eigth step
digitalWrite(mode_pin1, HIGH);
digitalWrite(mode_pin2, HIGH);
digitalWrite(mode_pin3, LOW);
step_delay = step_delay / 8;
}
else if(step_delay <= 16) {
// Sixteenth step
digitalWrite(mode_pin1, LOW);
digitalWrite(mode_pin2, LOW);
digitalWrite(mode_pin3, HIGH);
step_delay = step_delay / 16;
}
else {
// 1/32 step
digitalWrite(mode_pin1, HIGH);
digitalWrite(mode_pin2, LOW);
digitalWrite(mode_pin3, HIGH);
step_delay = step_delay / 32;
}
}

I think the problem is that no timers are used in the code. It only uses step modification to change the speed. My max speed is 1.25 rev/sec. When I run at max speed everything’s fine. When I turn the speed to 1.249 rev/sec the speed turns down to 0.625. Basically the motor runs with full-step at max speed and as soon as I try to run it at a slightly slower speed, the code starts running the motor at half-step and so on.

I thought this should work with the arduino’s setspeed function. So I tried to compile the arduino example for stepper speed and I had the exact same problem. I suppose that aside from the code, something should also be wrong with motor drivers. Is that right? Isn’t the setspeed function in stepper library supposed to give me a somewhat better resolution?

Thank you so much for the help. I’m not sure which parts of the code could actually help. Please let me know if you need any specific part of the code or else if you need the whole code.

Please use the code tags. If you click "Preview", it is the button with a # symbol on it.

I'd very much like to see -all- the code to tell what is going on.

Which stepper driver board(s) is it using? Pictures? Links, if you know where they came from?

Sorry about that. It seems that I can’t post the full code because it exceed number of allowed characters so I just attached it to this post.

Here’s the link for the stepper: http://www.pololu.com/product/1200
Here’s the link for the driver: http://www.pololu.com/product/2977

Thank you so much.

FullCode.ino (26.5 KB)

I have a look at the code attached to the previous Post. What is it supposed to do? What is the “machine” that it is controlling? How is the machine supposed to work?

There seems to be an enormous amount of code for very little output?

I have great difficulty understanding why people create classes for things when there will only be one instance of the class. I could understand the value of a class for “bees” if one wanted to model the goings on in a beehive.

…R

Basically we have two stepper motors one of which gives us rotational movement and the other which is connected to a screw makes the linear motion possible. The device has 2 operating modes. One in which you can just select the speed of each motor and another one in which you give diameter of a rod and a desired angle as inputs and the device calculates the optimum rotational and linear speed to achieve those inputs. There are 4 multimeter on the device which altogether are used for providing inputs. The inputs are in the form of XXXX with a multimeter provided for any of those X. There is a mode change switch, a return switch, a start/stop switch and another switch for changing between 2 variables. A lot of effort has been put into this but it has a very fundamental problem which I described before.

Any ideas?

Thanks.

That is very confusing. You might be better off starting over.

arg110: The device has 2 operating modes.

Can we make life simple. WHAT IS THE DEVICE? Have you a photo of it? or perhaps a short video?

If I had some notion of what you are talking about I might be able to make sense of what you are saying..

...R

arg110, when you said "multimeter", I think you meant "potentiometer".

And using a stepper library such as Stepper or AccelStepper might be a good (re)starting point.

You’re right polymorph! I should have said potentiometer.
The device is used to wrap fibers around a rod. The rod rotates while moving in forward direction. This way a fiber is wrapped around the rod. You can find a cad representation of the device attached to this post.
Thanks again.

Dev1.pdf (119 KB)

Reminds me of the X-winder.

    if (neg == 1) {
          stepMotor(step_number % 4);
        } 
        else {
          stepMotor(3 - (step_number % 4));
        }

You are using a proper step-and-dir driver board but you are using code designed for the 'motor shield'.

Keep the proper driver, get rid of the wrong code.

Also, you are going to have to coordinate motion between the two motors. If you can't figure out how to do this on your own, you could try adapting the GRBL code.