The cncutil.org CNCUtil Library allows Machinests to retain the control of the milling machine where it is needed while allowing the computer to do the hard work of producing the GCODE needed for things like circular pockets, Arc pockets, etc. CNCUtil also does most of the math which tends to take up a lot of a GCODE programmer's time.
When using CNC for milling everything ultimately boils down to moving the milling bit up, down left, right, etc. in carefully controlled movements as small as 10,000 of an inch. This movement is ultimately controlled by a scripting language called GCODE which is conceptually like the LOGO turtle which Apple invented to teach graphics to children only GCODE is harder to read than most modern languages and is missing many features found in most programming languages.
When GCODE is hand written it can allow expert machinists detailed control over the actions of the machine but it can be quite cumbersome, error prone and time consuming. On the other hand it is possible to draw the desired shape in 3D CAD packages and then surrender all control over the movements of the machine which tends to produce inferior parts, use more machine time and consume more materials. &nbps; What quite often happens is that people draw with the CAD convert with CAM system and then end up manually editing the GCODE which is very time consuming because the GCODE is one big long sequence and every time the CAD image changes the CAM conversion has to be redone so the manual editing also has to be redone.
CNC Util provides an alternative solution which works in a way that most programmers find intuitive. You are able to clearly describe what you want the machine to do with a series of high level commands and the library takes care of all the mundane work necessary to generate high quality GCODE. When using CNCUtil productivity is highest when using our high level object such as arc pocketing but at any time you can drop down to detailed level control and you can even merge in existing GCODE snippets without having to manually edit the resulting output.
The way I learn best is with a series of well explained examples that explain how to accomplish increasingly complex things. For that reason this document is organized as a series of examples
The library automatically takes care of a lot of the math needed when using GCODE but sometimes you may want to use the math functionality directly such as when you need to calculate an angle when you know the location of a point.
There are a few basic knowledge items which didn't fit well as indepentant examples which we have grouped in to a separate section. I suggest looking at those after you have reviewed several examples.
Once you have deveoped a basic understanding of the library using the examples here it will be much easier to understand the full fledged projects
Detailed class, method level documentation is available in our Library Class, Method and Attribute documentation This includes comments we added to the source code and can be an invaluable aid in using the library.
This document assumes that you understand the basic CNC process along with the major components of CNC hardware and software. This is described in some detail in the CNC process portion of our overview document This is rather critical knowledge so please review this if you are not already familure with CAD, CAM, CNC Drivers, etc.
When using our library it you are ultimately giving the computer high level instructions that it uses to generate a computer scripting language called GCODE which is ultimately what is read by the CNC driver software which turns the stepper motors that move the milling head. It can be helpful but not essential to understand the basics of GCODE which is described in our Introduction to GCODE document. This one is a pretty quick read. It also provides an overview of the coordinate space used by CNC mills which is essential knowledge when planning milling jobs. GCODE is explained at a higher level in our overview document
When you are writting scripts that use our library you are ultimately writing simple Ruby programs. A basic knowledge of Ruby can be helpful but is not essential. For that matter you can accomplish quite sophisticated parts simply by reviewing our examples and our more complex projects which bring the individual concepts explained in the examples together to mill complex parts. We have published some basic ruby information in our Ruby Notes document.
Whenever you see me using a CNCShape type object it is an object which has used more primitive operations and combined them to complete a more complex task. The CNCShapeSpiral object is a good example of such an object. Normally you would never need to see how I approach milling a spiral but if you have a similar task that the built in object is not quite capable of you can take use the ruby source as an example and enhance it.
This is a task that many people want to make quite complex but it is almost absurdly simple. Image you are milling out a square pocket that is 4 inches per side and you want it to measure exactly 4 inches across.
I like to mill with a 1/2" (0.5") diameter bit. If I pace the exact center of the bit on a line it will mill out one half of it's diameter which is actually it radius of 0.5 or 0.025 inches on each side of the center point.
If I want my square to be exactly 4 inches wide and 4 inches tall then I have to move the milling head 1 bit radius to the inside to allow for the amount the bit will cut on both sides. Most of the CNCUtil pocketing and shape commands will automatically deduct the proper amount for the bit size you are using but when you resort to more primitive lines you may have to accomdate this manually.
So when using the 0.5" inch bit on a 4 inch square pocket rater than moving from 0,0 to 4,0 to 4,4 to 0,4 to 0,0 I have to move in one bit radius or 0.25 inches for each exterior coordinate. Or if I was milling an outside profile I would have to move out the same amount. The dimensinions adjusted are 0.25, 0.25 to 0.25, 3.75 to 3.75, 3.75 to 0.25, 3.75 to 0.25, 0.25.
Obviously adjusting for bit diameters is cumbersome and time consuming so all the CNCUtil pocketing commands automatically take them into account and make the adjustments automatically.
TODO: Insert picture
Examples are simple jobs that are not complex enough to consider a project and are generally intended to illustrate a single concept. Many examples include a link to a more complete piece of code that you can run as is or modify to suit your needs.
When require statements are shown it indicates that module is a required import for the functionality. A require is only needed once for a program is kept at the top of the file.
Many lines of comments have been added to the example code. These comments start with a "#" and continue to the end of the line. They are intended to explain the code and have no functional purpose. We normally do not comment this much and if you remove these comments most of the programs are 75% shorter.
require 'cncMill'
aMill = CNCMill.new
aMill.move(7,2,-0.2)
# X,Y, Z
# moves the mill from current location
# to X of 7, Y of 2 and Z of -0.2
# similar to G02 X7 Y2 Z-0.2 F5
# however CNC Util will apply limits
# so if you ask for a move outside
# the capability of your mill it will
# move change the request to stop before
# the mill would hit it's limit's.
aMill.move(0,0)
# Moves the head to the home position.
# showing the the Z and A axis are
# optional.
aMill.home()
# retracts the milling head and
# and then moves it home. This
# prevents accidental milling
# through your work piece when
# moving home.
mill.retract() knows where the air is supposed to start for a given mill so it will automatically move to that point which is normally Z=0.2. Sometimes however you may only want to retract a smaller amount say you are working inside a cavity so you can supply an absolute Z value
Plung works just like retract(). We provide the two different verbs because it provides better documentation of your intent.
One of my favoorite mistakes is to forget to mill in the negative so I specifiy a depth of 0.5 rather than -0.5 and then end up wondering why the bit never entered the work.
The plung functions are smart enough to use the current information from the milling machine, material and bits and finish versus rough milling to choose an approapriate rate of plung. example
require 'cncMill'
aMill = CNCMill.new
aMill.retract()
aMill.plung()
aMill.retract(0.6)
aMill.plung(-1.5)
aMill.home()
# Home performs a retract() before moving the
# head from it's current position to it's home
# position.
require 'cncMill'
aMill = CNCMill.new
aMill.job_start()
aMill.retract()
aMill.mill_rect(
lx = 1.0, ly = 1.0,
mx = 2.3, my = 2.4, depth= -0.5,
adjust_for_bit_radius=true)
aMill.mill_rect_centered(scx=2.5,scy=2.3,
width=0.5, length=1.5, depth= -0.5)
aMill.job_finish()
The functions for milling a simple rectangle outline is not as sophisticated as the pocket system. It will not take care of multiple passes needed mill deep grooves. however it can easily be called multiple times with increasing depth to accomplish the same thing. The first mill_rect command mills from one corner specified by lx,ly to the other corner specified by mx,my and it will adjust automatically for cutting tool diameter compensation. The second function mill_rect_centered is similar but you specify a center coordinate width and length and the software will do the math to center the rectangle over the specified center point.
require 'cncShapeCircle'
require 'cncMill'
aMill = CNCMill.new
mill_circle(aMill,
x=2.0,y=1.0, diam=0.75,
depth=-0.5,
adjust_for_bit_radius=true)
require 'cncShapeArc'
require 'cncMill'
aMill = CNCMill.new
aMill.retract
aMill.move(0.5, 0,5)
aMill.plung(-0.5)
mill_arc(aMill, xo,yo,radius, speed=nil, direction = "G03")
require 'cncShapePolygon'
mill = CNCMill.new()
mill.job_start()
mill.home()
mill_polygon(mill, cent_x=1, cent_y=1,
diam=1.5, no_sides=5, depth=-0.2)
mill.home()
mill.job_finish()
require 'cncMill'
require 'cncShapeRect'
aMill = CNCMill.new
aMill.job_start()
aMill.home
aRect = CNCShapeRect.new(aMill, 1.0,1.0, 0.25, 0.25, -0.99)
aRect.centered() # forces to center over x,y
aRect.do_mill()
aMill.retract()
mill = CNCMill.new
mill.job_start()
mill_spiral(mill, cent_x = 1.95, cent_y = 1.7,
inner_diam = 0.45, outer_diam = 3.3,
channel_thick = 0.25, wall_thick = 0.15,
depth = -0.5)
mill.job_finish()
aArc = CNCShapeArc.new(
mill = mill,
x = 1.5,
y = 1.5,
beg_min_radius = 0.65,
beg_max_radius = 0.85,
beg_angle = 0.0,
end_min_radius = 0.65,
end_max_radius = 0.90,
end_angle = 35.0,
depth = -0.2)
aArc.circ_array()
aMill = CNCMill.new
aMill.job_start()
aMill.home()
# variables used here to make
# easy for reader.
aPoly = CNCShapePolygon.new(aMill,
cent_x = 2, cent_y = 2,
start_z = 0.0, diam=0.38, num_sides=6,
depth=-8.0, degree_inc=nil)
aPoly.circ_array(
circ_x = 2,
circ_y = 2,
radius = 1.5,
beg_degree = 0,
end_degree = 360,
num_elem = 8)
aMill.job_finish()
require 'cncGeometry'
aDistB = calc_distance(x1=0.5, y1=0.5, x2=3.8, y2=-1.9)
aDist = mill.calc_distance(x1=1.1, y1=1.23, x2=1.99, y2=3.45)
aPoint = mill.apply_limits(xi,yi,zi)