Thursday, May 16, 2013

Stepper Motors and Drivers

PSMD Triple Axis Stepper Controller
A coworker gave me a PSMD Triple Axis Stepper motor controller about a month ago.  This is a device designed to make your life easy when building a 3D printer or something else which requires high level precision of motion in three orthogonal directions.  It provides easy connections between three stepper motors, three stepper drivers ( Polulu A4988), a microprocessor controller, and power.

The gift stimulated me to learn about stepper motors and drivers, as well as ultimately to put together a functional device which makes use of both.  While at the beginning I was shying away from 3D printing, in the end I've migrated in that direction given the wealth of information available on the subject.  This post is not about a 3D printer, but rather about the motion systems used in a 3D printer, or in any CNC machine for that matter (milling machine, laser engraver, etc).

Here's what I've learned about stepper motor drivers.  All stepper drivers activate or deactivate coils in the motors in order to step the rotor around the stator.  There are three types of stepper motors; I used bipolar motors which are common for 3D printers.  They have four wires, two of which connect to each of two sets of coils in the stator.  The rotor has permanent magnets; the number of these magnets, along with the way the coils are arranged in the stator, determines the steps to degrees turning ratio.  The stepper motors I used with the PSMD are 200 steps/turn or 1.8 degrees per step.  Stepper motors can also be microstepped so that each step moves less then 1.8 degrees.  The A4988 allows up to 1/16th of a step to be taken by changing the resistance on three pins.   Stepper motors also hold a position actively; current is constantly applied to the coils in order to stay at the current position while the motors are enabled.  There is a ton more information at this site:  http://openbookproject.net/electricCircuits/AC/AC_13.html#xtocid174388  .

All stepper motor drivers operate in current limiting mode.  This means that they turn off voltage when a maximum current has been reached.  The stepper motors that I am using for the x-axis and y-axis positioning are rated for 4V.  Yet they are being driven by a computer power supply outputting 12V.  If the 12V remains applied for the duration of a step, the motor would get too hot or could have windings burn out.  The A4988 and other similar drivers sense the current through a resistor and limit the duty cycle (amount of time) that the voltage is applied to the motor through an H-bridge, effectively limiting the average current seen by the motor.  The details are a little more complicated:

"Each full-bridge is controlled by a fixed off-time PWM current control circuit that limits the load current to a desired value, ITRIP . Initially, a diagonal pair of source and sink FET outputs are enabled and current flows through the motor winding and the current sense resistor, Rsense. When the voltage across Rsense equals the DAC output voltage, the current sense comparator resets the PWM latch. The latch then turns off the appropriate source driver and initiates a fixed off time decay mode."  See the A4988 datasheet here for more details.  

You can adjust the reference voltage, Vref (which is, I think, the DAC output voltage referenced above) using a potentiometer wired to the REF pin on the A4988 chip.  In my case, I purchased stepper motors rated at 1.2A per coil of current.  (Other important facts about the motors:  44 oz-in holding torque, and 4V rated voltage, see here for motor specs ).  According to the data sheet, Itrip = Vref/(8Rsense).  Looking at the Polulu website for the A4988, Rsense = 0.05 Ohm, so we can solve for the desired Vref = Itrip x 8 x 0.05.   With Itrip =1.2A, we get Vref = 1.2 x 8 x 0.05 = 0.48V. I set the potentiometers for this reference.  There are excellent directions online for setting up the A4988 at this URL: http://aeons.phrenzy.org/~berserk/reprap/PololuPres_V3.pdf .


All the stepper drivers which I have are controlled by three digital TTL level pins.  One controls whether the stepper is enabled or disabled.  The second controls the direction of spin of the stepper.  The third is a step pin, which initiates a step when it is pulsed high (or maybe when it drops low again... I'm not sure).  A simple function to "step" a stepper has the following form:

void takeSingleStep(int stepPin)
{
  digitalWrite(stepPin, LOW);
  delayMicroseconds(2);
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(stepPin, LOW);
}


When called, this function pulses the step pin low, then high, then low again.  I found that the second delay (currently set at 1000 us = 1ms) is important; if that delay is too small then the stepper doesn't have time to execute multiple steps sequentially and it makes weird noises and moves erratically.

A simple function which turns on or off the stepper motors is shown below.

void enableStepperXYZ(int isEnabled, int enablePin)
{
  if(isEnabled)
       digitalWrite(enablePin, LOW); // enable HIGH = stepper driver OFF
   else
      digitalWrite(enablePin, HIGH); // enable HIGH = stepper driver OFF
 
  delayMicroseconds(2);
}


Two simple set of functions which change the direction of rotation are shown below.  I found that one way did not work for the v3.3 driver; they are labelled appropriately.

The following function worked for only the PSMD and is an absolute function:  it sets the direction either clockwise or counterclockwise.

void setCurrentDirection(boolean dir, int dirPin)
{
  if(dir == false)
      digitalWrite(dirPin, LOW);
  else
      digitalWrite(dirPin, HIGH);
  

  delayMicroseconds(1);
}


The following two functions worked for both boards and are relative functions:  they set the direction to be opposite the previous direction.

boolean currentDirectionZ = true;

void setCurrentDirectionZ(boolean dir, int dirPin)
{
  if(dir == false)
      digitalWrite(dirPin, LOW);
  else
      digitalWrite(dirPin, HIGH);
 
  currentDirectionZ = dir;
  delayMicroseconds(1);
}

void changeDirectionZ()
{
  setCurrentDirectionZ(!currentDirectionZ, dirPin);
}


Besides the step, enable, and direction pins, there are other pins on the A4988 which are important, but the PDMS board takes care of most of them for you.  For example, the reset and the sleep pins are both pulled high, effectively making them unusable but so you do not need to worry about them.  The board has three mini-switches attached to MS1, MS2, and MS3, which allow you to easily set the stepping mode (full, 1/2, 1/4, 1/8 or 1/16).

MakerBot v3.3 Stepper Driver
I also worked with the StepperDriver3.3 from Makerbot as there were several of those sitting around from previous work done by others on Makerbot3D printers.  The documentation for these has been largely pulled from the web since they are older products, but they are totally functional.  I've posted the relevant file here.  Most of the information is really similar to the PSMD board, because the v3.3 is based off of a predecessor chip to the A4988, the A3977.  Here's the datasheet for the A3977 chip.  If you compare the two datasheets, you'll see that they are essentially the same at the level of detail that I have been talking about.   One difference is that the A3977 does not have 1/16th stepping possibility, only full, 1/2, 1/4 and 1/8th, set by two pins, MS1, and MS2.  A second difference is that the A3977 supports higher currents and therefore bigger motors, with a rated current of 2.5A compared with 2A for the A4988.


I used the v3.3 board with 42BYGHW-811 Wantan stepper motors, which are rated to a higher current of 2.5A.  The Rsense resistors are 0.25 Ohm for this board, so with a rated current of Itrip = 2.5A, we can calculate the value of Vref to set for the v3.3 board as 5V.  The maximum permissible for the logic of the A3977 circuits is 4V according to the datasheet, so I set Vref = 4.0V.

The PSMD board also has integrated pinouts for limit switches, which are sometimes used to detect the end position in the X, Y, and Z axes (both low and high limits).  The pins provide +5V, and a signal pin.   You can digitally read the signal pin to see when it is shorted to ground with a pullup resistor enabled on the Arduino.


v3.3 Cable Ribbon Pinout
PSMD Cable Ribbon Pinout
Wiring up the stepper motor boards to an Arduino is very easy to do if you have some ribbon cable and the pinout diagrams for each board.  The pinout are shown here... I wired together the enable pins for all the steppers into one pin on my Arduino allowing me to turn on and off all the motors at once.