This is just one of several manufacturing projects that I am working on.

Steps CNC to Stepper Converter

Table of Contents

  1. Introduction
  2. Input File Format
  3. Output File Format
  4. Protocol
  5. Command Line
  6. Interactive
  7. Source Code
  8. Download

1 Introduction

Steps is a program that converts from a limited subset of RS-274 (i.e. CNC "G-codes") to much simpler timed step and direction file. In other words, the output is basically a sequence of commands that specify that at time T, please increment or decrement the following stepper motors by one position. All of the issues with accelleration, maximum velocity, backlash, etc. are taken care of by the software. What this means is that the controller that uses these codes can be quite inexpensive and simple.

Below is a small screenshot of the jog program used to move the mill table around to set things up.

Small jog screenshot
I won't try and explain everything, since it was thrown together in a real hurry and will undoubtly change as I get more experience using it.

2 Input File Format

The input file format is a restricted subset of RS-274. The following codes are accepted:

The letters in parenthesis specify what arguments can be supplied to the command. The G02 and G03 commands only accept I, J, and K -- not R. The G04 command only accepts P -- not X.

As usual for RS-274 comments are enclosed in parentheses (...). The machine and controller configuration information is encoded in comments of the form:

(steps: configuration information)

The following configuration options are available:

(steps:Baud_Rate: baud_rate )
cycles specifies the desired baud rate for machine controller.
(steps:Cycles: cycles )
cycles specifies the number of cycles per second that the controller is operating at. Fundamentally, this specifies the maximum stepping rate that the controller can (theoretically) achieve. In practice, the actual machine may not be able to come any where close to this performance level.
(steps:Path: path )
path specifies the path to I/O port to use to talk to the controller.
(steps:axis_Backlash backlash )
backlash is a floating point number that specifies the the amount of backlash on the axis. axis must be one of A, X, Y, or Z.
(steps:axis_Acceleration acceleration )
acceleration is a floating point number that specifies the maximum acceleration for the axis and it is measured in units/sec2. axis must be one of A, X, Y, or Z.
(steps:axis_Length length )
length is a floating point number that specifies the length of the axis in units of length. axis must be one of A, X, Y, or Z.
(steps:axis_Rapid_Feedrate feedrate )
feedrate is a floating point number that specifies the maximum velocity for the axis measured in units/min. axis must be one of A, X, Y, or Z.
(steps:axis_Steps steps )
steps is an integer that specifies the number of steps per unit for the axis. axis must be one of A, X, Y, or Z.

Below is an example of configuration for a small table top milling machine:

(Sherline Mill)
(steps:Cycles: 100000)
(steps:Baud_Rate: 115200)
(steps:Path: /dev/ttyUSB0)
(X Axis)
(steps:X_Acceleration: 1)
(steps:X_Backlash: 0)
(steps:X_Length: 12)
(steps:X_Rapid_Feedrate: 15)
(steps:X_Steps: 8000)
(Y Axis)
(steps:Y_Acceleration: 1)
(steps:Y_Backlash: 0)
(steps:Y_Length: 8)
(steps:Y_Rapid_Feedrate: 15)
(steps:Y_Steps: 8000)
(Z Axis)
(steps:Z_Acceleration: 1)
(steps:Z_Backlash: 0)
(steps:Z_Length: 8)
(steps:Z_Rapid_Feedrate: 15)
(steps:Z_Steps: 8000)

								

3 Output File Format

The basic concept behind the steps file format is that a dedicated microcontroller generates interrupts at regular intervals. At each interrupt interval, the microcontroller can increment, decrement, or leave alone each axis -- X, Y, Z, or A. The steps software reads in RS-274 code and figures out how what the correct sequence and time of pulses should be for eaxh axis. All of the heavy math is done on the host computer and the CNC controller can be quite simple.

The controller has two delay registers called D and P. The D register is the current delay register and the P register is the previous delay register. For the purposes of writing into these registers, they are partioned into A, B, C, and D as shown below:

D and P Registers
13:10 9:6 5:2 1:0
0 0 a a a a b b b b c c c c d d
13:12 11:8 7:4 3:0
where the 4-bit quantity aaaa corresponds to the high order 4 bits, bbbb corresponds to the next 4 bits, cccc corresponds to the next 4 bits, and dd corresponds to the low order 2 bits. The SetA command is used to set aaaa of D, the SetB command is used to set bbbb of D, the SetC command is used to set cccc of D, and the Step command is used to set dd of D.

The output is a sequence of commands of the following format:

Command
Name
Bit Cycles Description
7 6 5 4 3 2 1 0
Step 0 d d c a x y z D + 1 Set D<1:0> to dd. If c is 1, clear D<13:2>. After delaying by D cycles step the axes marked with a 1 in axyz.
SetA 1 0 0 0 a a a a 0 Set D<10:13> to aaaa.
SetB 1 0 0 1 b b b b 0 Set D<9:6> to bbbb.
SetC 1 0 1 0 c c c c 0 Set D<5:2> to cccc.
SetDirection 1 0 1 1 a x y z 0 Set the direction for the A, X, Y, and Z axes to axyz where 1 is increment and 0 is decrement.
Reserved 1 1 0 r r r r r Reserved
Reserved 1 1 1 0 r r r r Reserved
Reserved 1 1 1 1 0 r r r Reserved
Reserved 1 1 1 1 1 0 r r Reserved
Reserved 1 1 1 1 1 1 0 r Reserved
Start 1 1 1 1 1 1 1 1 0 Mark end of current chunk.

4 Protocol

The overall design of the protocol between the host and the controller is to allow the host to remain in complete control over what is going on. The protocol is designed to be resiliant enough to recover even if an occasional byte is dropped.

The controller contains a static memory buffer that is either 128K, 256K, or 512K bytes in size. The primary purpose of the protocol is reliably transfer commands from the host into the controller memory buffer. It is assumed that the communications channel is relatively reliable, so we are just trying to uncover occasional errors. New data downloading can proceed in parallel with command that the controller is processing out of the buffer. The host computer is responsible for ensuring that no buffer overrun condition occurs.

The protocol downloads commands as a block of data. A pointer is kept to the begining of the data block. As each byte of data is downloaded, a simple checksum is computed. Eventually, the host processor decides to ask for the checksum back. If the checksum is correct the, data block is committed; otherwise, the insertion point is rolled back and the block is retransmitted.

In addition, there are two 3-bit chunk counters. The current chunk counter specifies the number (modulo 8) of the chunk that is being processed. The enabled chunk counter specifies the number (modulo 8) of the chunk that is allowed to be processed. Thus, the host controller, can download up to 7 blocks and enable them. The controller is idle whenever the two counters are equal.

Command
Name
Send /
Receive
Bit Description
7 6 5 4 3 2 1 0
Memory Command Send 0 d d c a x y z Store into Memory Buffer
Memory Command Send 1 0 x x x x x x Store into Memory Buffer
Control Low Set Send 1 1 0 0 l l l l Set low 4 bits of "control" byte to llll.
Control High Set Send 1 1 0 1 h h h h Set high 4 bits of "control" byte ot hhhh.
Address Low Set Send 1 1 1 0 0 0 0 0 Set Address<7:0> to control. Return llll llll the value that was set.
Receive l l l l l l l l
Address Middle Set Send 1 1 1 0 0 0 0 1 Set Address<15:8> to control. Return mmmm mmmm the value that was set.
Receive m m m m m m m m
Address High Set Send 1 1 1 0 0 0 1 0 Set Address<23:16> to control. Return hhhh hhhh the value that was set.
Receive h h h h h h h h
Static RAM Get Send 1 1 1 0 0 0 1 1 Return ssss sss the value of at address in the static RAM.
Receive s s s s s s s s
RAM Get (Unimplemented) Send 1 1 1 0 0 1 0 0 Read address from microcontroller RAM and and return as dddd dddd
Receive d d d d d d d d
Memory In Low Get Send 1 1 1 0 0 1 0 1 Return Memory_In<7:0> as llll llll
Receive l l l l l l l l
Memory In Middle Get Send 1 1 1 0 0 1 1 0 Return Memory_In<15:8> as mmmm mmmm
Receive m m m m m m m m
Memory In High Get Send 1 1 1 0 0 1 1 1 Return Memory_In<23:16> as hhhh hhhh
Receive h h h h h h h h
Memory Out Low Get Send 1 1 1 0 1 0 0 0 Return Memory_Out<7:0> as llll llll
Receive l l l l l l l l
Memory Out Middle Get Send 1 1 1 0 1 0 0 1 Return Memory_Out<15:8> as mmmm mmmm
Receive m m m m m m m m
Memory Out High Get Send 1 1 1 0 1 0 1 0 Return Memory_Out<23:16> as hhhh hhhh
Receive h h h h h h h h
Checksum Low Get Send 1 1 1 0 1 0 1 1 Return Checksum<7:0> as llll llll
Receive l l l l l l l l
Checksum High Get Send 1 1 1 0 1 1 0 0 Return Checksum<7:0> as llll llll
Receive h h h h h h h h
Chunk Currenth Get Send 1 1 1 0 1 1 0 1 Return Chunk Current; as cccc cccc
Receive c c c c c c c c
Chunk Enabled Get Send 1 1 1 0 1 1 1 0 Return Chunk Enabled; as eeee eeee
Receive e e e e e e e e
Synchronize Send 1 1 1 0 1 1 1 1 Return 1010 0101 to synchronize return stream
Receive 1 0 1 0 0 1 0 1
Chunk Enabled Increment Send 1 1 1 1 0 c c c Commit chunk ccc to be processeed. Clear checksum. Advance rollback pointer. This command is idempotent. Return 0x81 on success and 0x80 on failure.
Receive 1 0 0 0 0 0 0 x
Commit Data Block Send 1 1 1 1 1 1 0 0 Comment current data block. Clear checksum. Advance rollback pointer. Advance rollback pointer. Return 0xa5.
Receive 1 0 1 0 0 1 0 1
Rollback Data Block Send 1 1 1 1 1 1 0 1 Rollback the Data Block. Clear the checksum. This command is idempotent. Return 0xaa
Receive 1 0 1 0 1 0 1 0
Read Chunk Counters Send 1 1 1 1 1 1 1 0 Return the current chunk counter ccc and eee and the end chunk counter eee.
Receive 0 0 c c c e e e
End of Chunk Send 1 1 1 1 1 1 1 1 End of Chunk marker stored into buffer

5 Command Line

The command line for steps is:

steps [-S] [-B] [-C] [-G] [-p] [-i] [-T] cnc_file ...
where
[-S]
Generate an output summary on standard output that summarizes elapsed time and the amount of travel on each axis.
[-B]
Trace the bytes that will be sent to the buffer controller.
[-C]
Trace the RS-274 comments that are processed.
[-G]
Trace the RS-274 G and M codes.
[-p port_file]
Open communcations port that is embedded in the .cnc file.
[-i]
Generate an I/O file for Wayne's PIC simulator.
[-T]
Trace times.
cnc_file ...
cnc_file is a list of one or more files containing RS-274 commands as described in the Input File Format section. The suffix of each cnc_filemust be .cnc.

6 Interactive

In order to interactively test the firmware, the following command line interface was developed:

x|X|y|Y|z|Z|a|A [count]
Increment/decrement the A/X/Y/Z axis by [count]. This triggers automatic sending.
dump [address]
Dump 8 locations from the static RAM staring at address.
send
Send the current buffer. This only works when the x|X|y|Y|z|Z|a|A commands are not auto sending.
go chunk
Increment the current chunk to trigger stored commands.
commit
Commit the current buffer.
rollback
Rollback the current buffer.
Delay value
Set current delay to value.

7 Source Code

The code is written in my own programming language called STIPPLE. The source code currently resides in the following files:

manual.sts
A manual tester with terminal interface.
steps.sts
Main body of library code.
steps_gen.sts
The command line interface to the library.
jog.sts
The graphical user interface to the library.

8 Download

Currently, I am not keeping the code under strict version control. The lastest version of manual, steps_gen and jog are available for Linux only. Be sure to set the execute bit (i.e. "chmod +x steps_gen jog") after you download it.


Copyright © 2005-2006 by Wayne C. Gramlich All rights reserved.