Nonlinear stepper acceleration

In my project I need to have a stepper motor that will run through a non linear acceleration profile.

I know that this must be possible due to the driving of a stepper is as simple as the pulse rate but am not sure on the best method of doing this.

I believe this could be accomplished by either of two methods:

1) AccelStepper or some other prebuilt library with acceleration preset.

In order to do this I had hoped to break my acceleration curve into multiple discrete lines (linear profiles) and as each line completes (# of steps/ distance moved) the acceleration would change.

I would prefer this method due to the simplicity of the code as I can put in distances and acceleration values instead of setting delays and pulses. And it somehow relates directly to acceleration so I wouldn't have to worry about length of my program messing with pulse delay.

2) Send a pulse with delays

This method I would just find pulse rates required and compile into an array or some loop structure. This method is a bit more straight forward but I believe will be much more mathematically intensive and incur more missed steps/ errors.

I have a unipolar stepper motor which I will probably end up converting over to bipolar so I can run off a big easy driver or derivative.

If everything works out i'll move to a teensy 3.2 or 3.6 for the increased processing power required to run the code.

Lastly for this project I would like to create a vb.net GUI OR labview panel to run and select the profiles required. Is there a "simple" way to do this? Will it transfer information fast enough? Ideally I would create a GUI that has profile type (equation) with a button for beginning the experiment. This would either reprogram the board or change parameters preset in the code, I am not sure what is even possible honestly. It should be easy to make a stand alone program to write the code needed for the arduino and reupload constantly but would rather have communication as discussed above.

Thanks for any help
-Tyler Scofield

It's probably best to drive the pulses yourself. That way you control the acceleration directly.

I did a lot of work with a Teensy 3.2 last year when I needed a specific sinusoidal drive that changed frequency and amplitude on the fly. The Teensy was chosen for its physical size but the speed was also helpful: I could do several floating-point calculations in between each step being taken. Using the Flex Timer Module, I found I had to calculate the time required for the step after next and pre-load that into the buffer. An interrupt at each step drove the calculations. It ended up using 52% of the Teensy capacity (no overclocking) when running at the fastest step frequency I needed, which was 5kHz.

The stepper library has a setSpeed() function, but I've not used it for any kind of fast accelerations so I don't know how much overhead it has.

How you handle data transfer from the PC to the Arduino mostly depends on how fast you need to change the speed setting. You can run a serial port up to 115,200 bits per second or even faster if the connection is short and properly bypassed and shielded. Assuming 2 or 3 bytes per message you can send more than a thousand updates per second, provided your code can process everything fast enough. If you need faster updates then downloading the profile to the Arduino ahead of time is the way to go, but I suspect you will need a Teensy or an ARM based Arduino. The AVR micros don't have that much memory.

It might not be exactly what you're looking for.
But I recently wrote a library for running stepper motors using a timing callback.
This handles acceleration (i.e. don't just use fixed velocity for movement)

It uses the Timer 2 (via FlexiTimer2 library which is included)

MorganS:
It's probably best to drive the pulses yourself. That way you control the acceleration directly.

How would you suggest I overcome unintended pulse delay errors due to the increasing size of the code? IE: If I had a code that was much shorter it would drive the pulses much more quickly but I am unsure of how to overcome this if I wanted to change code in any substantial way without re calibrating every time. Or is the teensy clock rate quick enough for this to not be a problem?

MorganS:
I could do several floating-point calculations in between each step being taken. Using the Flex Timer Module, I found I had to calculate the time required for the step after next and pre-load that into the buffer. An interrupt at each step drove the calculations. It ended up using 52% of the Teensy capacity (no overclocking) when running at the fastest step frequency I needed, which was 5kHz.

So you used a timer to create the interrupt(physical timer?) in which whenever the timer pulsed the calculations for pulsing on the next step was calculated? Could you not use a counter or something in the code to determine the steps?

sdturner:
The stepper library has a setSpeed() function, but I've not used it for any kind of fast accelerations so I don't know how much overhead it has.

I will look into this.

sdturner:
How you handle data transfer from the PC to the Arduino mostly depends on how fast you need to change the speed setting. You can run a serial port up to 115,200 bits per second or even faster if the connection is short and properly bypassed and shielded. Assuming 2 or 3 bytes per message you can send more than a thousand updates per second, provided your code can process everything fast enough. If you need faster updates then downloading the profile to the Arduino ahead of time is the way to go, but I suspect you will need a Teensy or an ARM based Arduino. The AVR micros don't have that much memory.

I suppose I don't need a live connection to feed the data just to change up a present number of variables for slope of acceleration, steps, ect.. but if the connection if this fast maybe I can do the calculations on the computer and send the data through? It will probably be easier to just do it all on board though.

elliotwoods:
It might not be exactly what you're looking for.
But I recently wrote a library for running stepper motors using a timing callback.
This handles acceleration (i.e. don't just use fixed velocity for movement)

It uses the Timer 2 (via FlexiTimer2 library which is included)

GitHub - elliotwoods/GrubStep: An Arduino library for stepper motor control using timer interrupts.

I'll have a look thanks.

Thank you all for your help

If you use the timer interrupt method, then it doesn't matter how slow the rest of your code is. It gets interrupted when it's time to calculate the next step.

What does matter is how long it takes to calculate the period of the next step. If that takes longer than the shortest step, then it will fail. You actually want this to take some small fraction of the step time, so that there's some processor time left over for the rest of the code to run between the interrupts.

Here's the core of my interrupt function which clears the interrupt bits, updates the current position and sets the time for the step-after-next:

void ftm1_isr (void) {
  //called by interrupt when timer matches = the end of a step pulse

  FTM1_C1SC &=  ~FTMx_CnSC_CHF; // clear channel 1 interrupt - necesssary when CHIE is set
  if(FTM1_SC & 0b10000000) {
    FTM1_SC &= 0b0111111; //clear the Timer Overflow interrupt - this is necessary if TOIE is set
  }


  if(Paused) {
    return; //don't update position or next-step time when paused
  } else {
    if(Direction) {
      Position ++;
    } else {
      Position --;
    }

    FTM1_MOD = calcTimerInterval(Position, Direction);   
  }
  return;
}

Everything prefixed "FTM" is part of the flex timer module and is defined for you by the framework.

Configuring the flex timer for the initial start is a longer function - there's hundreds of lines of comments describing what each FTM register does.