Stepper Acceleration (More theory based)

So I am working on a research project and one of my responsibilities is to produce a stepper driver that can do any acceleration based off a given function. So desirably to any order. I have been looking over a lot of material and am stuck on a certain idea. So we use pulses to send movement into the motor, and these pulses always have the same width and you vary the distances between pulses? So my main question is in confusion if the last statement was true. I am not sure if the motion, acceleration is caused by:

1) Vary pulse distance and keep pulse width the same 2) Vary pulse width and keep pulse distance the same 3) Vary both?

The code that I am reffering to is:

  digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9)/2);
      digitalWrite(STEP_PIN, LOW); 
      delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9)/2);

In this code we set the same delay for both the high and low section of pulse and you change the delay for each pulse to have it change velocities. Is there a difference in just setting this to the minimum value and setting an additional delay after this? As you can see I am more confused on just how the pulsing method works. Any help would greatly be appreciated.

Cheers

-Tyler Scofield

tyscof: So we use pulses to send movement into the motor, and these pulses always have the same width and you vary the distances between pulses?

Correct

So my main question is in confusion if the last statement was true. I am not sure if the motion, acceleration is caused by:

1) Vary pulse distance and keep pulse width the same 2) Vary pulse width and keep pulse distance the same 3) Vary both?

Number 1

The code that I am reffering to is:

  digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9)/2);
      digitalWrite(STEP_PIN, LOW); 
      delayMicroseconds((MICROSECONDS_PER_MICROSTEP * 0.9)/2);

While it is not what you asked this code is mixing up integer and floating point maths and probably does not work as you expect. In an Arduino floating point maths is slow and shoudl be avoided. And delayMicroseconds() need an unsigned long value, not a float

In this code we set the same delay for both the high and low section of pulse and you change the delay for each pulse to have it change velocities. Is there a difference in just setting this to the minimum value and setting an additional delay after this? As you can see I am more confused on just how the pulsing method works. Any help would greatly be appreciated.

Life is much simpler with a constant short pulse of (say) 10 microsecs and all the timing concentrated in the interval between pulses. Look at the examples in this Simple Stepper Code

...R Stepper Motor Basics

So something like this?

digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(STEP_PIN, LOW); 
      delay(100);

Is this going to be accurate for accelerations? (assume the pulse as instantaneous) Also what is the best way of running a stepper motor very slow without getting too hot?

Also in your example code you set the writes directly after one another with no delay?

void singleStep() {
 if (curMillis - prevStepMillis >= millisBetweenSteps) {
 prevStepMillis += millisBetweenSteps;
 digitalWrite(stepPin, HIGH);
 digitalWrite(stepPin, LOW);

-Tyler S

The trick to doing acceleration with steppers is doing it within the calculation limits of a cheap MCU. Acceleration algorithms are plentiful and extensively documented. Acceleration algorithms that are computationally practical for anything other than simple linear acceleration, or limited to very low maximum speeds, or full-step mode only, are very few. Thoughts of doing second- or third-order, or S-curve accelerations on an AVR-based Arduino should be abandoned right off the bat, unless you are happy being limited to a few hundred RPM. With micro-stepping, which should be considered a must-have for any real-world application, things get much more difficult, due to the MUCH higher step rates required. And using software timing of step pulses will yield a sub-optimal result, as the best results can be achieved only with a very low-jitter pulse train. Jitter is a very common cause of "lost steps" and even motor stalling.

From the questions being asked, I'd suggest the OP needs to study this until he understands every word:

http://homepage.divms.uiowa.edu/~jones/step/

Regards, Ray L.

Also is it the total delay that matters or just the delay between high points? Say if I were to set the first delay to very small then variable the second delay in microseconds.

If I wanted to increase my delay before moving from microseconds() to delay() - milliseconds. Could I increase my first delay instead?

In other words...

If I wanted x Delay say 1000 to achieve a speed

With delay1 = 50 microseconds delay2 = 100 microseconds

Can I do both:

1) Increase delay2 to ~950 and keep delay1 the same

AND/OR

2) Increase delay 1 but some amount say delay1 = 500, delay2 = 500 OR delay1 = 200 delay2 = 800.

RayLivingston: The trick to doing acceleration with steppers is doing it within the calculation limits of a cheap MCU.

Haha yea I agree, I am using a teensy 3.5

I am also looking to rotate at very low speeds.

At "very slow speeds", you don't even need to do acceleration, other than perhaps something very rudimentary.

Several of your questions depend on the specific motor driver you use, so cannot be answered definitively. In particular, step pulse polarity and minimum/maximum step pulse width. Most will only care about the one edge, and some minimum "active" level, but requirements vary greatly from one driver to another. Without a thorough understanding of HOW stepper motors work, the effects of voltage and current, the myriad driver options (PWM, micro-stepping, step "morphing", current limiting, idle current reduction, etc., etc.), and the specific detailed system requirements (not least of which being ultimate performance requirements), you can't hope to develop a decent drive system.

Regards, Ray L.

I am using a: SainSmart TB6560 Stepper Stepping Motor Driver Board

tyscof: So something like this?

digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(STEP_PIN, LOW); 
      delay(100);

Is this going to be accurate for accelerations? (assume the pulse as instantaneous)

No. It's not accurate for anything. Adding up the delays gives you 100.01 milliseconds, or 100010 microseconds. But the other parts of the code take some time. digitalWrite() is not too bad but your imaginary acceleration algorithm needs to do a variable amount of calculation in between each step, so that will add a variable delay which this code isn't measuring.

You need to use a timer such as millis() which gives you exact times that don't depend on the time that your code takes to do calculations. Here's a simple example:

void loop() {
  static unsigned long LastStepTaken;
  static unsigned long CurrentStepDuration;
  if(millis()-LastStepTaken >= CurrentStepDuration) {
    //take the step, recording the time when we stepped
    LastStepTaken = millis();
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(STEP_PIN, LOW); 
    //work out how long we need to wait for the next step
    CurrentStepDuration = calculateStepDurationForNextStep();
  }
  //other tasks go here - make sure that no task will take longer than the minimum step time
}

This example is relatively simple. Usually there would be more controls around this to start, stop, reverse or whatever. And the digitalWrite()s would be encapsulated in a function so that you can control many steppers.

Also what is the best way of running a stepper motor very slow without getting too hot?

The heating of the stepper is not dependent on speed. The stepper gets hot at all speeds. You should set the current limit on your stepper driver to an appropriate value for your motor. If the motor is too hot to touch for more than a second then it's about right. (Steppers are very rarely used for battery-operated devices because of the high power consumption.)

The chips we use in our Arduinos have a lot of hardware resources specifically intended for running motors. Most of the time we don't use those resources because the software is fast enough. A Teensy 3.5 can do lots of calculations in between the steps. But the hardware timers allow you to do longer and more complex tasks and the hardware will ensure that the steps still go out at the required intervals.

This is running away and theory and practice are mixed up and it is hard to know what is the important question and whether it has been answered.

I agree with the code concept in @MorganS's Reply #8. It is similar to the second example in my link in Reply #1. But it may be that in this snippet

So something like this?

digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(STEP_PIN, LOW);
      delay(100);

the OP was just using delay as a general indication of the concept rather than the specific way he intends to implement the project.

In general terms acceleration is simply the variation of the interval between steps.

...R