Go Down

Topic: S-Curve for EasyDriver v3 Stepper Motor Driver (Read 18 times) previous topic - next topic

Chris E.

I have an Arduino project where I'd like to control a stepper motor.  Unfortunately, the Arduino library for stepper motors is very limited.  I'd like to define parameters for the acceleration, deceleration, and total displacement and have the Arduino take care of the rest.  Poking around on this forum, I surprised that no one seems to have posted anything relating to this - so I figured it was incumbent on me to get something started.  I've attached my first iteration.  Seems to be working well in my tests.  Comments and suggestions will be greatly appreciated.

In my current setup, I'm using the EasyDriver stepper driver from sparkfun Electronics - though any driver that used pulse and direction should work fine.

Quote


/*
=============================================================
=       Project: S curve
=      Language: Arduiino r12
=          Date: January 2008
=        Author: C. Eckert
=============================================================
*/

// Givens
long ta = 3e6;     // acceleration time (microsec)
long td = 3e6;     // decelleration time (microsec)
long Vm = 3200;    // steady state velocity (pulse/sec)
long Pt = 12800;    // total number of pulses for move (1600 steps per rev)

// Other variables
long dly;           // stepper pulse delay (microsec)
long t = td/9;      // current time (microsec)  -  You need to seed the initial time with something > 0
                   //                             so you don't calculate to long of a delay
long t12;           // time during constant velocity (microsec)

int count = 0;      // count the number of pulses
int Perr = 0;       // error in position

// Arduino pins
#define dirPin 3
#define stepPin 12

void setup() {
 Serial.begin(9600);
 pinMode(dirPin, OUTPUT);
 pinMode(stepPin, OUTPUT);
 
 // Calculate the time at constant velocity
 t12 = (Pt/(Vm/1e6))-0.5*(ta+td);
 Serial.println(); Serial.println();

 Serial.println("Setup Done");
}
void loop()
{
 digitalWrite(dirPin, LOW);  // Set the stepper direction

 // Decide which part of the velocity curve your at
 if (t<ta) {                                       // Acceleration
   //Serial.println ("Acceleration Curve");
   dly = (ta)/(2*(Vm/1e6)*t);
 }
 else if (t>=ta && t<(ta+t12)){                    // Constant velocity
   //Serial.println ("Constant Velocity");
   dly = 1/(2*(Vm/1e6));
 }
 else if (t>=(ta+t12) && t<(ta+t12+td)){          // Deceleration
   //Serial.println ("Deceleration Curve");
   dly = 1/(2*((Vm/1e6)-(Vm/(1e6*td))*(t-ta-t12)));
 }
 
 t = t+2*dly; // update the current time
 //Serial.print("dly: "); Serial.print (dly); Serial.println(" microsec");
 //Serial.print ("Current time: "); Serial.print(t); Serial.println(" microsec");
 
 // Move stepper one pulse using delay just calculated
 digitalWrite(stepPin, HIGH);
 delayMicroseconds(dly);
 digitalWrite(stepPin, LOW);
 delayMicroseconds(dly);
 count ++;
   
 // The move is finished
 if (t>(ta+t12+td)){
   Serial.println ("Move Complete");
   Serial.print ("Total steps indexed: "); Serial.println (count);
   
   // Correct for any position error due to rounding
   Perr = Pt-count;
   if (Perr < 0) {
     digitalWrite(dirPin, 1^digitalRead(dirPin));  // reverse the stepper direction
     delay(50);
     Perr = -1*Perr;
   }
   for (;Perr>0;){
     digitalWrite(stepPin, HIGH);
     delayMicroseconds(dly);
     digitalWrite(stepPin, LOW);
     delayMicroseconds(dly);
     Perr--;
   }
   
   count=0;
   t=td/9;
   
   delay (1000);
 }
 
}




Mike Mc

#1
Jan 14, 2009, 10:17 am Last Edit: Jan 14, 2009, 10:20 am by zooto68 Reason: 1
Thanks for this. I also have the Easydriver v3. Though I have so far only played around with the sample code in the playground.

What is the reason for you needing finer control over the acceleration and deceleration? Making a telescope mount?

Grumpy_Mike

Hi Mike,
The point about acceleration is that you can get the motor to run at a faster top speed if you accelerate up to it than you can if you try and drive it from a standing start. The latter is sometimes called the stall speed. It is due to the mechanical inertia you have.

However, if you get it accelerating too fast then you start skipping steps and so you loose accuracy. I used to use a liner ramp to get up to speed but you really should use a bit of control theory to work out the acceleration profile.
Same goes for slowing down, if you just do a dead stop it can over run if going too fast.

Chris thanks for posting this it should be useful.

Mike Mc

Thanks. That will explain why my telescope mount starts slowly, speeds up, runs at its full slew speed, then decelerates to a stop gradually.

michaelh

Did this project go anywhere?  I'm thinking about replacing my old telescope controller and motors and I'd have more fun replacing it with an arduino setup.

Go Up