External Reference Specification (ERS)

Table of contents

1 Introduction

This document presents a description of how to use PyMini with the rt-stepper dongle. This description is intended to define what the product controls, human interface, and machine interface.

This document is provided "AS IS" without warranties of any kind including warranties of merchantability, fitness for a particular purpose, or non-infringement of intellectual property.

The rt-stepper dongle is a USB-to-Parallel dongle designed specifically for CNC controllers. This dongle provides CNC parallel port support and real time stepper motor control. Precise step/directon pulses are generated by the dongle. You can use this dongle to convert a parallel port CNC controller into a USB CNC controller.

PC software is used to drive the dongle over the USB bus. The rt-stepper software consists of two major compenents - PyMini and the rtstepperemc library. PyMini is the GUI that provides the user interface. The rtstepperemc library provides the gcode interperter, trajectory planner and dongle IO.

Since the dongle provides the real time step pulse generator no real time kernal is required. This allows PyMini to run on Linux, Mac or Windows. All software is available at the rtstepperemc project

1.1 License

The rt-stepper software that runs on the PC is covered by the GNU GPL 2.0 license.

Simply stated the GNU GPL license does allow the following.

What this license does NOT allow you to do is make changes or add features to rt-stepper software and then sell a binary distribution without source code. You must provide source code for any changes, or additions to the software and all code must be provided under the GPL or LGPL as appropriate.

2 Solution

3 Overview

The rt-stepper dongle's USB connector connects to the PC. The dongle's DB25 connector connects to the parallel port of the CNC controller. With the PyMini application a user can operate a CNC machine manually or run a gcode program.

PyMini is a powerful minimalist user interface written in python. A user can write their own gcode program using their favorite text editor or run a CAM generated gcode program on PyMini. You can verify the gcode program with or without the dongle connected and view the xyz paths executed on the backplot panel. All PyMini communication to the dongle takes place through the rtstepperemc library.

The rtstepperemc library is based on the same gcode interpreter and trajectory planner from the EMC/LinuxCNC project at Both projects are separate software applications and the dongle will only run with the PyMini software.

There is only one process that runs on the PC - PyMini. PyMini generates the step pulses, but step timing is maintained by dongle thus eliminating the need for a real time kernel. PyMini coverts the gcode instructions into a series of step buffers. Each step buffer is sent over the USB bus to the dongle. The dongle then clocks each step byte out over the parallel port at precise step intervals. Each step byte drives the step/direction pins on the CNC controller parallel port.

See the "Gcode Overview" section at for gcode syntax. Note, mcodes are handled differently in PyMini. Most mcodes are implemented via python plugin scripts. This means spindle, coolant and homing can be executed via custom python scripts.

4 Jogging

Each axis can be jogged individually. When PyMini is first opened the X axis is selected along with the Incremental Jog option. Pressing the "Jog X -" button will jog the X axis the incremental distance in the negative direction. Pressing the "Jog Y +" button will jog the X axis the incremental distance in the positive direction. You can select a different axis by selecting one of the Y, Z, or A positions in the upper left corner of the screen.

The Speed value is used for jogging. The default Speed value is set in the rtstepper.ini file. You can modify the Speed value on the screen, but it is not saved in the ini file. See the Configuration File section to change the default.

Selecting the Absolute Jog button will switch from incremental jogging to absolute position jogging. The default Absolute Jog value is set in the rtstepper.ini file. You can modify the Absolute Jog value on the screen, but it is not saved in the ini file.

Jogging is not available in Auto/Run mode. When running a gcode file the jogging buttons are disabled.

5 EStop/EReset

Use the EStop button to execute a emergency stop. When in EStop mode the application status LED is red. EStop can be triggered by the user, limit switches or dongle IO error. You must click the EReset button to clear the EStop condition. Once the EStop condition has been cleared the status LED will turn green.

If the EStop occurred during any move command, PyMini will perform an un-synchronized stop. Once stopped the position of the machine is unknown and will require an All Zero command before restarting any move commands.

When PyMini is first started it will try to enumerate the dongle. If the dongle is not found or is unavailable PyMini will automatically come up in EStop mode. Clicking the EReset button will force PyMini to re-enumerate the dongle.

6 MDI Buttons

The Manual Data Input (MDI) buttons can be used for executing gcode commands interactively. There are four MDI buttons. A gcode command can entered on screen then executed by pressing the MDI button. Or you can dedicate any of the buttons to a specific gcode command.

MDI button names and commands can be customized in the rtstepper.ini file. Changes to the MDI commands on screen are not saved to the ini file. See the Configuration File section to change the default.

MDI buttons are not available in Auto/Run mode. When running a gcode file the MDI buttons are disabled.

7 Auto/Run

Running a gcode file is the PyMini workhorse. There are many CAD/CAM software applications, Fusion 360 for example, that generate gcode files. With PyMini you can execute this gcode file to build your part. One can also edit a gcode file manually using a simple text editor such as Microsoft WordPad.

Use the Auto button to open a gcode file. Once the file is open you can use the Run button to execute the program, or use the Verify button to run the program without stepper motor control. As the program is executed each line is displayed on the log panel and the status bar in the lower right corner.

The backplot panel will provide a graphical display of the tool path as the program executes. Use the backplot bottom buttons to manipulate the display. The backplot will only operate in Auto/Run/Verify modes.

Both Run button and Verfiy button have a Cancel button option. When using the Run button cancel the program will execute a synchronized stop. Once the last move has completed you can restart the program without an All Zero command. This different from the EStop button which executes a un-synchronized stop. After an EStop you must issue the All Zero command in order to restart the program.

8 Configuration File

A configuration file will be used to set PyMini runtime options. By default the rtstepper.ini file is used as the configuration file. You can also specify a custom ini file on the PyMini command line.
pymini -i rtstepper.ini

The ini file is a simple ASCII text file that must be customized for each unique CNC controller. Use any text editor to customize the ini file. Multiple ini files can be used for different CNC controllers. The ini file is divided into different sections and key/value pairs. Sections are defined by brackets "[ ]" and key/value pairs are defined by the "=" character. Comment lines start with the "#" character. The rest of this section define some common configuration options and their default values. Generally only these options need to be modified by the user.

8.1 EMC section

MACHINE = PyMini (rtstepper.ini)
Sets the title in the UI application. Useful for identifying what ini file is loaded.

8.2 DISPLAY section

MDI_CMD_1 = G90 G1 X0 Y0 F6
INC_JOG = 0.2
ABS_JOG = 1.0
MDI_LABEL_1 sets MDI button 1 label.

MDI_CMD_1 sets MDI button 1 gcode command.

PyMini has support for 4 MDI command buttons (MDI_LABEL_1 - MDI_LABEL_4, MDI_CMD_1 - MDI_CMD_4).

AUTO_FILE sets the default Auto gcode file.

INC_JOG sets the default incremental jog (mm or inch).

ABS_JOG sets the default absolute jog (mm or inch).

JOG_SPEED sets the default jog speed (mm/minute or inch/minute).

LATHE sets the Tool Offsets screen for lathe or mill (0 = mill, 1 = lathe).

8.3 TRAJ section

LINEAR_UNITS =          inch
MAX_VELOCITY =         400
LINEAR_UNITS sets the engineering units (inch or mm).

The other parameters set the trajectory planner default velocity and acceleration in engineering units. In the above example this would be 0.2 inches/second or 12 inches/minute (12 = 0.2 * 60). This sets the trajectory planner overall acceleration and velocity then each axis can be fine tuned individually in the AXIS section.

8.4 AXIS section

There is a AXIS section for each axis (AXIS_0 - AXIS_3).

MAX_VELOCITY specifies the max velocity for this axis. In the example this would be 0.15 inches/second.

BACKLASH is the amount of backlash or "play" in your XYZ lead screw. Start with zero then after tuning your CNC system, measure your backlash and enter the values here. Note, backlash compensation is a poor substitute for good lead screws. Excessive backlash can "throw" the table, causing inaccurate cuts and or broken tool.

INPUT_SCALE define the stepper motor steps/inch for this axis. This is a function of your motor, lead screw and CNC controller. Metric values can be used here instead of inch.

Here are some notes on how to calculate the INPUT_SCALE for a Sherline mill using the using a Xylotex 3-axis CNC controller and 269 steppers.

1.8 = degrees/step
360 / 1.8 = 200 steps/revolution
.050 = one revolution of the lead screw
200 / .050 = 4000 steps/inch full steps

Since the Xylotex CNC controller board is set to 1/8 stepping.

4000 * 8 = 32000 steps/inch = INPUT_SCALE

STEP_PIN specifies the step pin on the DB25 connector for this axis.

DIRECTION_PIN specifies the direction pin on the DB25 connector for this axis.

STEP_ACTIVE_HIGH specifies the polarity of the step signal (0 = active_low, 1 = active_high).

DIRECTION_ACTIVE_HIGH specifies the polarity of the direction signal (0 = active_low, 1 = active_high).

The default values for step/direction pins will work for many commercial CNC controller boards. Note, the dongle supports 8 digital output signals on DB25 connector pins 2, 3, 4, 5, 6, 7, 8 and 9. Your CNC controller MUST be built to use these pins, most commercial boards are.

8.5 TASK section

Use the "INPUTx_ABORT" option to automatically trigger a un-synchronized estop. Any "INPUTx_ABORT" option can be used to enable a estop. Generally the input signals are used for limit switches. See the Limit Switches section for wiring details.

When "INPUTx_ABORT=0" the un-synchronized estop is disabled. This is the default.

When "INPUTx_ABORT=1" an "active high" transition on the INPUTx pin will cause a un-synchronized estop.

Note the INPUT0 pin can be used as a frequency counter or a limit switch, but NOT both. The frequency counter is only available on INPUT0 and is used for measuring spindle speed (RPM). In order to enable the frequency counter option "INPUT0_ABORT=0" must be set.

9 Tool Offsets

Pressing the Tool Offsets button will display the Tool Offsets screen. Use this screen to set length offset and diameter for Tool number 1-10.

Different tools used for machining operations in a program may vary in length. It is obviously simpler to have a single zero point for all tools, that is what PyMini allows you to do with the All Zero button, but the system can be directed to compensate for offset variations in the program by using the T-word to select one of Tool number 1-10.

When PyMini is started for the first time each tool length offset is set to zero. When the gcode program first starts T1 is the default tool. Using this screen one could set Tool number 2 to -0.1 offset and diameter of 0.125 inch. Nothing is saved until the Ok button is pressed.

Each tool can be selected with a gcode block. The following example selects Tool number 2.

T2 M6 G43
T2 will select Tool number 2 for the next tool change, M6 calls a python script ( to perform a tool change and G43 tells the program to start using the offset. M6 will cause a program pause so the user can manually change the tool, then click the Resume button. The status LED will turn orange when the program is paused. The script can be customized, see the Python Script section.

This tool length offset will be active until the next tool change command. In PyMini clicking the All Zero button will reset the offset back to zero.

By default the Tool Offsets screen will only display mill parameters. If your system is lathe instead of a mill, you can enable the lathe parameter screen. In the *.ini file DISPLAY section set the LATHE option equal to 1.

10 Fixture Offsets

Pressing the Fixture Offsets button will display the Fixture Offsets screen. Use this screen to specify fixture offset locations for each gcode G54-G59. Multiple parts can be cut with a single setup by using a different offset for each part.

The All Zero button will set the Machine Origin, normally this is also the Program Origin. You can change the Program Origin with G54-G59. When the gcode program first starts G54 is the default offset. Using this screen one could set G55 to the location of a second part, G56 to the location of a third part, etc.

This is an interactive screen. One can jog to specific location and use the Teach button to read the current position for that axis. Nothing is saved until the Ok button is pressed.

11 Spindle Speed

Starting with dongle firmware release 1d, PyMini can display the spindle speed in revolutions per minute (RPM). Spindle speed can be measured by connecting a index pulse to the INPUT0 pin. The dongle will accurately measure the frequency or period of the index pulse in counts and PyMini will convert the count to RPM. The index pulse must be a 5vdc open collector "active low" signal. One pulse per revolution is supported.

Here a index pulse was generated with the rt-stepper sensor kit on a Sherline 2000 mill. The period is a little less the 20ms which represents about 3200 RPM.

12 Software Installation

The best way to install PyMini is with a pre-build binary package. Pre-build binary packages are available at Installing from source code is an option, but should only be attempted by an experienced programmer or administrator. See the file for notes about installing from source code.

12.1 Windows Install

For Windows 7, Windows 8 and Window 10 use the following steps to install PyMini. Starting with PyMini 1.16 the python interpreter is now bundled with the PyMini application. This means all PyMini software is contained in a single zip file. This zip file will unzip into a single directory and all software can be run from this directory.
  1. Download the latest file from
  2. Unzip the zip file by right clicking on the zip file and follow the instructions.
  3. After the extraction is complete, goto the unzip directory.
  4. At this point you should be able to run "pymini.exe" by double clicking on it. This should start PyMini application.
  5. With no dongle plugged in, PyMini should display the message "unable to find rtstepper dongle". You can verify your gcode file without the dongle plugged in by pressing the Verify button.
  6. Plug-in a USB cable from the PC to the rt-stepper dongle.
  7. If you have Window 8 or Window 10 there is no driver to install. For Windows 7 you will have to install the driver manually. Goto the Windows Device Manager and look for device entry "rt-stepper 1c", then right click on "rt-stepper 1c" and select Update Driver Software. Then select the downloaded driver.
  8. Disable any power save options that will cause the PC to shutdown during CNC operation.
  9. Now you can run "pymini.exe" and there should be no "unable to fine rtstepper dongle" message.
  10. You are now ready to proceed with the Power Up section.

12.2 Linux Install

For Ubuntu use the following instructions to install PyMini. All PyMini software is contained in a single zip file. Since all major Linux distributions include python by default PyMini will use the default python interpreter. This zip file will unzip into a single directory and all software can be run from this directory.
  1. PyMini requires the python module tkinter (python-tk). By default Ubuntu does not install python-tk. You can install it with the following command.
    apt-get install python-tk
  2. Download the latest file from
  3. Unzip the zip file.
  4. At this point you should be able to run "" or "pymini.pyw" from the unzip directory. This should start the PyMini application.
  5. With no dongle plugged in, PyMini should have displayed the message "unable to find rtstepper dongle". You can verify your gcode file without the dongle plugged in by pressing the Verify button.
  6. In order set the dongle USB device permission, copy the following rules file from the zip directory into "/etc/udev/rules.d".
    cp 55-rt-stepper.rules /etc/udev/rules.d
  7. Plug-in a USB cable from the PC to the rt-stepper dongle.
  8. Disable any power save options that will cause the PC to shutdown during CNC operation.
  9. Now you can run "" and there should be no "unable to find rtstepper dongle" message.
  10. You are now ready to proceed with the Power Up section.

12.3 Mac OSX Install

For Mac OSX use the following instructions to install PyMini. All PyMini software is contained in a single application bundle. Since OSX comes with python installed by default PyMini will use the default python interpreter. The bundle was build on OSX 10.9 and should run on 10.9 and above.
  1. Download the latest pymini-xxx-macosx-xxx-intel.dmg disk image from
  2. Double clicking on the dmg file will automatically mount and popup the file folder screen. You can use the icons from the disk image or you can drag-and-drop them into a folder on your hard drive. In order to modify the rtstepper.ini file you must drag-and-drop all four icons into a folder on your hard drive.
  3. At this point you can run PyMini by clicking on the icon.
  4. With no dongle plugged in, PyMini should have displayed the message "unable to find rtstepper dongle". You can verify your gcode file without the dongle plugged in by pressing the Verify button.
  5. Plug-in a USB cable from the PC to the rt-stepper dongle.
  6. Disable any power save options that will cause the PC to shutdown during CNC operation.
  7. Now you can run PyMini and there should be no "unable to find rtstepper dongle" message.
  8. You are now ready to proceed with the Power Up section.

13 Power Up

The rt-stepper dongle is powered from the USB bus on the PC, no external power supply is required. Since the CNC controller has a separate power supply the following power up sequence must be used.
  1. With all power off plug the dongle into the PC via a USB cable.
  2. Plug the dongle directly into the DB25 connector on the CNC controller.
  3. Power up the PC first then the CNC controller.
  4. After the PC enumerates the USB device check the dongle's green LED.
    The LED should be on solid (no blinking). 
  5. Now run the PyMini application.
Use the reverse order for the power down sequence.

14 Testing

Before we can start CNC stepping the motors we must verify the USB subsystem with the rt-test program. rt-test is part of the PyMini package.

IMPORT!! The rt-test program must be performed with no CNC controller connected to the dongle.

rt-test will verify that your USB subsystem on your PC can drive the rt-stepper dongle. Run "rt-test" from the command line and the following checks will be made.

  1. USB device enumeration.
  2. Device permissions.
  3. Start a 65K byte bulk write transfer.
  4. Wait for transfer complete.
  5. Print pass or fail.
Run rt-test several times, if rt-test passes every time proceed to the Tuning section.

15 Tuning

Note if your CNC system matches a pre-configured rt-stepper *.ini file, then this tuning procedure may not be necessary. See the sample *.ini files at

Before we can cut any real parts we must tune rt-stepper with the CNC system. At this point the INPUT_SCALE values, see the Configuration File section, should be correct for your CNC controller.

Since rt-stepper has it's own real-time clock, tuning is very simple. All we have to determine is the MAX_VELOCITY for each axis on the CNC system. Then update the ini file with the new values.

The MAX_VELOCITY is the max speed the stepper motors can operate at. Stepper motors will go out of sync if they are accelerated or decelerated too suddenly. This is because the magnetic fields are advancing faster than the rotor can keep up. Once a motor is out of synchronization further CNC stepping is useless as the position of that axis has been lost.

For tuning purposes the measured MAX_VELOCITY should be less than the current MAX_VELOCITY values in the ini file. The initial values in the default ini file should be a good starting point for tuning.

The MAX_VELOCITY is a very important control variable and can be used for the following functions.

  1. Set rapid limit in PyMini.
  2. Set the max feed rate in the gcode file.
MAX_VELOCITY must be measured for each axis. Here is the procedure for measuring each axis.
  1. Run PyMini.
  2. Set the Speed parameter to 60 * MAX_VELOCITY in the ini file.
  3. Jog the axis 1 inch.
  4. If the motor chatters or does not move at all reduce the Speed parameter and repeat step 1.
  5. Measure the distance moved, if not 1 inch reduce Speed and repeat step 1.
  6. Done, the resulting Speed is your measured MAX_VELOCITY, set MAX_VELOCITY = (Speed / 60) in the ini file.
Generally the measured MAX_VELOCITY is a function of your CNC controller board and stepper motors not rt-stepper. If your measured MAX_VELOCITY is not acceptable try reducing your steps/inch on your controller board. If you change your steps/inch remember to change the INPUT_SCALE in the ini file.

When tuning is complete you are ready to start cutting parts.

16 Limit Switches

Depending on the CNC system limit switches are optional. If exceeding the XYZ physical limits can cause physical damage to your CNC system then limit switches are NOT optional.

The rt-stepper dongle supports three "active high" input signals called INPUT0, INPUT1 and INPUT2. Although any of the three input signals can be used for limit switches, the following example uses INPUT0. INPUT0 signal is hard wired to the DB25 connector pin 10. Multiple switches are wired in-series as normally closed switches connected to CNC ground.

This configuration frees up INPUT1-2 for other uses and provides simple in-series cable wiring. With "active high" digital input signals a broken wire will be detected immediately.

INPUT0-2 have a internal pull up resistors so no external power or pull up resistor is required. INPUT0-2 use a Schmitt Trigger input buffer for noise immunity, but care should still be taken with the switch wiring. Do NOT route switch wires near power wires.

INPUT0-2 can be used to signal an un-synchronized estop of the current CNC controller move. This functionality can be enabled via the ini file. See the "INPUTx_ABORT" option in the Configuration File section.

The "input0-2_abort" option has a small amount of software overhead so the abort sequence in not immediate. Depending on how fast your PC is, some extra steps may be executed after a switch has been tripped. The number of extra steps will be feed rate dependent. Switches should be chosen that can handle any extra steps without being damaged.

Note if you want to use INPUT0 as a frequency counter or measure spindle speed you must use INPUT1 or INPUT2 for limit switches. INPUT1 uses DB25 connector pin 11 and INPUT2 uses DB25 connector pin 12.

17 Python Scripts

With PyMini most mcodes are supported via python plugin scripts. Standard mcodes such as M3 and M5 are implemented via python scripts. User-defined mcodes are M100-199 and all user-defined mcodes are also implemented via python scripts. PyMini and the python plugin scripts use the same python interpreter Python is a simple programming language that allow users to make their own custom changes without having to recompile the software. All mcode scripts are stored in the "plugin" subdirectory.

What can you do with python a script? Scripts can perform the same functions as PyMini plus additional IO using an Adruino Uno board. By using PyMini's Adruino Uno board support this includes spindle on/off and coolant on/off control.

Arduino board support requires the python module pyserial. Pyserial supports both python 2.7 and python 3.x. You can download pyserial at and install using the following command.

python install (python2.7)
python3 install (python3.x)

Python scripts that execute spindle and coolant mcodes are included with the rtstepperemc software. Here is the python script file for turning the spindle on.

# - m3 mcode script turns spindle on clockwise.
# inputs:
#  p_num = rpm   # S parameter (spindle speed)
#  q_num = n/a
# example:
#  m3 s250.0
import pyemc
import arduino

def run(dongle, p_num, q_num):
   #print dongle.get_version()

   if (not arduino.connected):

   if (not arduino.inited):

   # Init data direction register for output.

   # Set shield pin high.

A similar python script file (plugin/ would turn the spindle off.

17.1 Homing

Homing is a process that moves an axis to a known position. Usually this is done with limit switches or in some cases separate homing switches. Homing is especially useful when your CNC system has no dials on each axis. However, different machines have different requirements and homing can be quite complicated.

The rtstepperemc software supports homing with user-defined mcodes. Included with PyMini is an example python script file that implements the user-defined mcode M190 (plugin/ This is simple script file will home a specified axis. The user will need to customize the script for their CNC application. M190 can be executed as a MDI command or from a gcode file.

M190 P0 Q0 (use INPUT0 for estop, home x-axis)
M190 P0 Q1 (use INPUT0 for estop, home y-axis)
M190 P0 Q2 (use INPUT0 for estop, home z-axis)

17.2 Set Position

Here is another user-defined mcode M191 (plugin/ This script allows you to set the position of the specified axis. For example one can use this script to zero an individual axis.
M191 P0 Q0.0 (zero x-axis)
M191 P1 Q0.0 (zero y-axis)
M191 P2 Q0.0 (zero z-axis) 

18 DB25 Connector

This figure shows the rt-stepper dongle DB25 connector pin out. The 8 digital outputs are reserved for step/direction signals.

19 Specifications

Step resolution: 46,875 hz
Standards: USB V1.1, USB V2.0 Compliant
USB Speed: Full Speed (12 Mb/s)
VID: 0x04d8
PID: 0xff45
Power: Bus Power Only (~5v)
Indicators: Power
Overall Dimensions: 2.6 in.(L) x 2.35 in.(W) x 0.95 in.(H)
Weight: 2.3 oz.
© 2009-2017 Eckler Software

Last updated August 7, 2017