Step-S (Yet another S-Profile Accerlation/Deceleration)

Hi,

I wrote a small and simple S-shaped envelop stepper movement sketch. It’s still early, but it seems to work fine.
I wanted something simple that could protect stepper and gearbox mechanisms from wear and tear.

It’s not that sophisticated, but instead it’s made so that user-can tune it.
You only need the last functions; the first two are for testing.
Make sure you don’t have heavy, fast and dangerous equipment hooked up for testing.
(In other words, use at your own risk.)

Edit: Had older version with int’s for Acceleration/Deceleration; these were changed to Floats.
It had been failing over 90 steps on Acceleration/Deceleration.

// For testing
const int pin_step = 13;

void setup ()
{
  pinMode (pin_step, OUTPUT);
}
void loop()
{
  step_s (pin_step, 8000, 8000, 30000, 30, 10, 10);
}

void step_s (int pin_step, int pulsewidth, int pulsewait_min, float pulsewait_max, int steps_total, float steps_attack, float steps_decay)
{
  // Sends Timed Pulses for Stepper S-Curved Accelleration / Deceleration
  // Version 1.004
  // By Brenda Make
  //
  // pin_step = Pin to send pulses to.
  // pulsewidth = Duration of pulse to sent.
  // pulsewait_min = Shortest Pulse to use for fastest speed, in microseconds.
  // pulsewait_max = Longest Pulse to use for slowest speed, in microseconds.
  // steps_total = Total length of movement in steps or pulses.
  // steps_attack = Attack portion of movement.
  // steps_decay  = Decay portion of movement.
  // Steps_attack and steps_decay should be even numbers over 6.
  // The sustain length must be at least 1.

  int count, wait, scale;
  float steps, angle, rad;

  // For a Quarter Wave
  steps = 90 / steps_attack;
  scale = (pulsewait_max - pulsewait_min) / 2;

  // Attack First Quadrant
  for ( angle = 270 ; angle < 360 ; angle = angle + steps )
  {
    rad = angle / 360 * 6.283185307;
    wait = abs (int ( sin (rad) * (scale) ) );
    wait = wait + scale + pulsewait_min;
    pulse (pin_step, pulsewidth, wait);
  }

  // Attack Second Quadrant
  for ( angle = 0 ; angle < 90 ; angle = angle + steps )
  {
    rad = angle / 360 * 6.283185307;
    wait = abs (int ( sin (rad) * (scale) ) );
    wait = scale - wait;
    wait = wait + pulsewait_min;
    pulse (pin_step, pulsewidth, wait);
  }

  // Sustain
  steps = steps_total - (steps_attack, steps_decay);
  for ( count = 0 ; count < steps ; count++ )
  {
    pulse (pin_step, pulsewidth, pulsewait_min);
  }

  // For a Quarter Wave
  steps = 90 / steps_decay;

  // Decay First Quadrant
  for ( angle = 90 ; angle < 180 ; angle = angle + steps )
  {
    rad = angle / 360 * 6.283185307;
    wait = abs (int ( sin (rad) * (scale) ) );
    wait = scale - wait;
    wait = wait + pulsewait_min;
    pulse (pin_step, pulsewidth, wait);
  }

  // Decay Second Quadrant
  for ( angle = 180 ; angle < 270 ; angle = angle + steps )
  {
    rad = angle / 360 * 6.283185307;
    wait = abs (int ( sin (rad) * (scale) ) );
    wait = wait + scale + pulsewait_min;
    pulse (pin_step, pulsewidth, wait);
  }
}
void pulse (int pin_step, int pulsewidth, int wait)
{
  // Pulse
  digitalWrite (pin_step, HIGH);
  delayMicroseconds (pulsewidth);
  digitalWrite (pin_step, LOW);

  // Wait
  delayMicroseconds (wait);
}