This documentation is no longer maintained. For documentation of the current version of emc2, please see

Basic configurations for a stepper based system


This chapter describes some of the more common settings that users want to change when setting up EMC2. Because of the various possibilities of configuring EMC2, it is very hard to document them all, and keep this document relatively short.

The most common EMC2 usage (as reported by our users) is for stepper based systems. These systems are using stepper motors with drives that accept step & direction signals.

It is one of the simpler setups, because the motors run open-loop (no feedback comes back from the motors), yet the system needs to be configured properly so the motors don't stall or lose steps.

Most of this chapter is based on the sample config released along with EMC2. The config is called stepper, and usually it is found in /etc/emc2/sample-configs/stepper.

Maximum step rate

With software step generation, the maximum step rate is one step per two BASE_PERIODs for step-and-direction output. The maximum requested step rate is the product of an axis's MAX_VELOCITY and its INPUT_SCALE. If the requested step rate is not attainable, following errors will occur, particularly during fast jogs and G0 moves.

If your stepper driver can accept quadrature input, use this mode. With a quadrature signal, one step is possible for each BASE_PERIOD, doubling the maximum step rate.

The other remedies are to decrease one or more of: the BASE_PERIOD (setting this too low will cause the machine to become unresponsive or even lock up), the INPUT_SCALE (if you can select different step sizes on your stepper driver, change pulley ratios, or leadscrew pitch), or the MAX_VELOCITY and STEPGEN_MAXVEL.

If no valid combination of BASE_PERIOD, INPUT_SCALE, and MAX_VELOCITY is acceptable, then hardware step generation (such as with the emc2-supported Universal Stepper Controller)


One of the majour flaws in EMC was that you couldn't specify the pinout without recompiling the source code. EMC2 is far more flexible, and now (thanks to the Hardware Abstraction Layer) you can easily specify which signal goes where. (read the [*] section for more information about the HAL).

As it is described in the HAL Introduction and tutorial, we have signals, pins and parameters inside the HAL.

The ones relevant for our pinout are1.1:

signals: Xstep, Xdir & Xen 
pins: & 1.2
Depending on what you have chosen in your ini file you are using either standard_pinout.hal or xylotex_pinout.hal. These are two files that instruct the HAL how to link the various signals & pins. Furtheron we'll investigate the standard_pinout.hal.


This file contains several HAL commands, and usually looks like this:

# standard pinout config file for 3-axis steppers
# using a parport for I/O
# first load the parport driver
loadrt hal_parport cfg="0x0378"
# next connect the parport functions to threads
# read inputs first
addf base-thread 1
# write outputs last
addf parport.0.write base-thread -1
# finally connect physical pins to the signals
linksp Xstep =>
linksp Xdir  =>
linksp Ystep =>
linksp Ydir  =>
linksp Zstep =>
linksp Zdir  =>

# create a signal for the estop loopback
linkpp iocontrol.0.user-enable-out iocontrol.0.emc-enable-in

# create signals for tool loading loopback
linkpp iocontrol.0.tool-prepare iocontrol.0.tool-prepared
linkpp iocontrol.0.tool-change iocontrol.0.tool-changed

# create a signal for "spindle on"
newsig spindle-on bit
# connect the controller to it
linkps motion.spindle-on => spindle-on
# connect it to a physical pin
linksp spindle-on =>

### You might use something like this to enable chopper drives when machine ON
### the Xen signal is defined in core_stepper.hal

# linksp Xen =>

### If you want active low for this pin, invert it like this:

# setp 1

### A sample home switch on the X axis (axis 0).  make a signal,
### link the incoming parport pin to the signal, then link the signal
### to EMC's axis 0 home switch input pin

# newsig Xhome bit
# linkps => Xhome
# linksp Xhome => axis.0.home-sw-in

### Shared home switches all on one parallel port pin?
### that's ok, hook the same signal to all the axes, but be sure to 
### set HOME_IS_SHARED and HOME_SEQUENCE in the ini file.  See the
### user manual!

# newsig homeswitches bit
# linkps => homeswitches
# linksp homeswitches => axis.0.home-sw-in
# linksp homeswitches => axis.1.home-sw-in
# linksp homeswitches => axis.2.home-sw-in

### Sample separate limit switches on the X axis (axis 0)

# newsig X-neg-limit bit
# linkps => X-neg-limit
# linksp X-neg-limit => axis.0.neg-lim-sw-in

# newsig X-pos-limit bit
# linkps => X-pos-limit
# linksp X-pos-limit => axis.0.pos-lim-sw-in

### Just like the shared home switches example, you can wire together
### limit switches.  Beware if you hit one, EMC will stop but can't tell
### you which switch/axis has faulted.  Use caution when recovering from this.

# newsig Xlimits bit
# linkps => Xlimits
# linksp Xlimits => axis.0.neg-lim-sw-in
# linksp Xlimits => axis.0.pos-lim-sw-in

### you can also use the "net" syntax to accomplish the "newsig" and "link"
### operations all at once.  This command does the same thing as the above
### block.

# net Xlimits => axis.0.neg-lim-sw-in axis.0.pos-lim-sw-in
The files starting with '#' are comments, and their only purpose is to guide the reader through the file.

Overview of the standard_pinout.hal

There are a couple of operations that get executed when the standard_pinout.hal gets executed / interpreted:

  1. The Parport driver gets loaded (see [*] for details)
  2. The read & write functions of the parport driver get assigned to the Base thread 1.3
  3. The step & direction signals for axes X,Y,Z get linked to pins on the parport
  4. Further IO signals get connected (estop loopback, toolchanger loopback)
  5. A spindle On signal gets defined and linked to a parport pin

Changing the standard_pinout.hal

If you want to change the standard_pinout.hal file, all you need is a text editor. Open the file and locate the parts you want to change.

If you want for example to change the pin for the X-axis Step & Directions signals, all you need to do is to change the number in the '' name:

linksp Xstep  
linksp Xdir
can be changed to:

linksp Xstep  
linksp Xdir
or basicly any other numbers you like.

Hint: make sure you don't have more than one signal connected to the same pin.

Changing the polarity of a signal

If external hardware expects an ``active low'' signal, set the corresponding -invert parameter. For instance, to invert the spindle control signal:

setp TRUE

Adding PWM Spindle Speed Control

If your spindle can be controlled by a PWM signal, use the pwmgen component to create the signal:

loadrt pwmgen output_type=0 
addf pwmgen.update servo-thread 
addf pwmgen.make-pulses base-thread 
net spindle-speed-cmd motion.spindle-speed-out => pwmgen.0.value 
net spindle-on motion.spindle-on => pwmgen.0.enable 
net spindle-pwm pwmgen.0.pwm => 
setp pwmgen.0.scale 1800 # Change to your spindle's top speed in RPM
This assumes that the spindle controller's response to PWM is simple: 0% PWM gives 0RPM, 10% PWM gives 180 RPM, etc. If there is a minimum PWM required to get the spindle to turn, follow the example in the nist-lathe sample configuration to use a scale component.

Adding an enable signal

Some amplifiers (drives) require an enable signal before they accept and command movement of the motors. For this reason there are already defined signals called 'Xen', 'Yen', 'Zen'.

To connect them use the following example:

linksp Xen
You can either have one single pin that enables all drives, or several, depending on the setup you have. Note however that usually when one axis faults, all the other ones will be disabled aswell, so having only one signal / pin is perfectly safe.

Adding an external ESTOP button

As you can see in [*] by default the stepper configuration assumes no external ESTOP button. 1.4

To add a simple external button you need to replace the line:

linkpp iocontrol.0.user-enable-out iocontrol.0.emc-enable-in

linkpp iocontrol.0.emc-enable-in
This assumes an ESTOP switch connected to pin 01 on the parport. As long as the switch will stay pushed1.5, EMC2 will be in the ESTOP state. When the external button gets released EMC2 will imediately switch to the ESTOP-RESET state, and all you need to do is switch to Machine On and you'll be able to continue your work with EMC2.


... are1.1
Note: we are only presenting one axis to keep it short, all others are similar.
Refer to section [*] for additional information
the fastest thread in the EMC2 setup, usually the code gets executed every few microseconds
An extensive explanation of hooking up ESTOP circuitry is explained in the and in the Integrator Manual
... pushed1.5
make sure you use a maintained switch for ESTOP.