Motion Control


To control a cartesian robot built from Contraptor, several steps are needed.

  1. Define motion paths. In case of digital fabrication, this is typically done by Computer Aided Manufacturing (CAM) software.
  2. Create G-code from the motion paths. Many CAM apps will generate G-code. It's very simple and can be written by hand or generated by a script.
  3. Send G-code to the controller where it's interpreted by the firmware.
  4. Controller sends the digital step pulses to stepper driver boards and the boards drive the stepper motors

G-code Controller Firmware

Arduino GCode Interpreter is used at the moment, specifically Chris Meighan's rewrite. It implements several features including hardware timer, acceleration, true arcs (G2,G3) and G-Code lookahead. Several Reprap-oriented forks are available at github and should also work, although they don't (yet) support arcs and G-Code lookahead. There are also grbl and rsteppercontroller although they don't support acceleration (as of this writing).

Sending G-code to the Controller

You can single commands to interpreter via:

  • Arduino IDE
  • serial terminal utility such as Hyperterminal or RealTerm on Windows or cutecom on Linux

When sending G-code files, the host should get the "ok" confirmation after every command sent to the interpreter and prior to sending the next command. The following Python script does just that. The individual commands should be on separate lines, i.e. "G20 G91" will not work.

# To send a gcode file to Arduino Gcode interpreter:  python <
# This script reads the lines from stdin and writes them to port_id using pySerial module
# After each line it waits until it gets one of the predefined responses from the port
# port_id examlpes: "COM1" on Windows, "/dev/ttyUSB0" on Linux
import serial,sys
port_id = "/dev/ttyUSB0"
baud = 38400
print "FLUSHING..."
ser = serial.Serial(port=port_id, baudrate=baud, timeout=2)
while True:
    response = ''
    response = ser.readline()
    print response.strip('\n')
    if response is '':
ser = serial.Serial(port=port_id, baudrate=baud, timeout=30)
for line in sys.stdin.readlines():
    print line.strip('\n')
    while True:
        response = ser.readline()
        print response
        if response.strip() in ['ok','start']:

Other ways to talk to the interpreter (untested)

Generating G-code

G-code is a text format that can be written by hand or generated by a script. CAM applications are generally used to generate G-code for subtractive fabrication from 3D or 2D design files, usually DXF.

  • CamBam is a beginner-friendly CAM application with a free version available.
  • Skeinforge is a tool that generates G-code for FDM additive fabrication from STL file.
  • GCAM is the free GNU Computer Aided Manufacturing package.
  • At you can find an optimized version of for creating gcode. There is also a link to, where the complete process of making pcbs with a milling machine is very well explained, including how to fix the boards, which bits to use etc.
  • A list with tons of CAM tools

Cartesian Movement

First of all you have to get an understanding about the Cartesian coordinate system. This system is used by G-code. For an introduction to G-code have a look at wikipedia G-code. (If you want to execute the following examples always initialize you mill with "G20" (programming in inches) followed by a LF/CR, than "G91" (incremental programming) also followed by a CR/LF.)


If you are looking from the front side at your Mini CNC the Y axis goes across the table from the front to the rear , the X axis is parallel to the gantry and the Z axis is the vertical axis, which moves the whole gantry up and down. Because the table of the Mini CNC is able to move a longer distance than the gantry, you want to change these both axis. In that case, imagine that you look from the left side at your Mini CNC. To control it in that way, just change the connections of the X axis stepper controller with that of the y axis. But the Z axis always points to the vertical direction.

Another important fact is, that when defining directions of movement, you always consider that only the tool is moving, not the workpiece. In the beginning this can be confusing for the table movement. For example (Y axis is parallel to the table) if you say something like "G1 Y1" (that is a positive value) you might expect, that the table is moving depart from you. But because you have to look in which direction the tool is moving relative to the workpiece, the table moves towards you.

All other movements work as you expect them intuitively. For example "G1 X1" will move the gantry one inch to the right and "G1 X-1" will move it one inch to the left, "G1 Z1" moves the whole gantry one inch up and "G1 Z-1" moves it one inch down. This is because the tool is moved directly and not the workpiece.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License