Well, thanks to SoD and Dave S I have written a little Python wizard to generate g-code for knurling for any length. The first try for simplicity as shown above I just cut a full lead length, which for a diamond knurl is pi x diameter of stock. Even for 12.7mm this is nearly 40mm long which is much too long for practical purposes – larger diameter knurls would be very wasteful. I realised though that if one made a knurl with an integer number of diamonds in the axial direction you can cut each "tooth" with just a zig-zag motion where the work rotates for say N teeth axially while it moves N diamonds axially, then continues to rotate for another N teeth while it moves back N diamonds. What one would then like to do is just cut another zig-zag an carry on until one has gone right round the blank, without having to make a pure rotational move to index to the next tooth. With a bit of playing around for this to happen the number of teeth and number of diamonds have to be "relatively prime", that is have no common factor other than 1. Or, one can just make the number of teeth "M" prime, in which case any number of axial diamonds up to (M-1) can be cut just with repeated zig-zag moves. I think this is the easiest approach since there isn't a particular reason to have any specific number as long as the knurl looks and feels right.
For my previous example M=37 is a nearby prime to 42 – I wanted something rather smaller than 42 to get a coarser pattern, 37 gives about a 1.08mm pitch. Here's the Python code.
import math
# Python program to generate G Code for a diamond knurl using a rotary axis on the mill.
# Parameters required:
# Initial stock diameter
# Number of circumferential "teeth" – this should be PRIME
# Length of knurl defined as the number of longitudinal teeth
# Feedrate
# Horizontal axis height above machine zero.
diameter = float(input("Stock diameter: ")
teeth = int(input("# teeth (prime): ")
length = int(input("# axial diamonds: ")
feed = float(input("feedrate: " ))
Z_feedrate = float(input("Downfeed rate; ")
height = float(input("axis height: ")
name = input("Output filename: " #include .txt or other extension
******ing Smileys! They should be closing brackets.
Thonny is free and comes as the built-in tool on the R-Pi, but I also use it on my PC. When you run it it asks for various parameters of the cut as listed, and the name of the file you want to put the results in (which will be in the same folder as the code). To get a text file include .txt on the end of the name. Note that the machine should be referenced so that X=0 is at the start or the knurl and Y=0 is on the A-axis. Z=0 for the tool tip is the machine table.
Here's a g-code example for 12.7mm diameter and 37 teeth.
G0 G49 G40 G17 G80 G50 G90
G00 Z 67.595
G00 X0 Y0
G91
G00 A 5
G01 Z -1.397 F 50.0
F 500.0
G01 X 10.783 A 97.297 ( 0 )
G01 X -10.783 A 97.297
G01 X 10.783 A 97.297 ( 1 )
G01 X -10.783 A 97.297
G01 X 10.783 A 97.297 ( 2 )
G01 X -10.783 A 97.297
G01 X 10.783 A 97.297 ( 3 )
G01 X -10.783 A 97.297
G01 X 10.783 A 97.297 ( 4 )
G01 X -10.783 A 97.297
………….
G01 X -10.783 A 97.297
G01 X 10.783 A 97.297 ( 35 )
G01 X -10.783 A 97.297
G01 X 10.783 A 97.297 ( 36 )
G01 X -10.783 A 97.297
G90
G00 Z 67.595
M5 M30
I've taken out a big block of lines in the middle to save space. Note that the code puts the "zig-zag" number in as a comment so you can keep track of what's happening on the Mach3 screen. For this example it counts 0 to 36, or 37 zigzags.
(I dunno why the smileys don't appear here…)
This is about as short as the code can be without using a subroutine but can be used on a controller that doesn't support these.
Looks good. Only real difference I can think of is knurling doesn’t “sink” below the original surface – which may or may not matter. At least with this you can guarantee a good knurl and not worry about it not tracking in.
Here's John's code in glorious technicolor, smiley's exterminated:
Couple of small points.
May not make any difference but I would use:
myFile = open( name, 'w' )
rather than:
myFile = open(name,'a' )
'a' opens the file 'name' in append mode, and if name already exists, the new G-Code will be tacked on the end, which probably isn't wanted. The 'w' open() always creates an empty new file so there's no danger of confusing the machine tool by feeding it two or more blobs of g-code in the same file.
Second, again not making any practical difference, John uses format strings mildly inappropriately in his print statements.
Ah, so that's what the f means! Noted, thanks! I thought it had something to do with "file"…
I thought, since the programme asks for a filename, I might as well use append mode. If write mode is used on an existing file, does it overwrite everything in the file? If not one still has the risk of having spurious stuff from a previous run.
One thing I haven't figured out – g code contains statements line "G01 X5" to move the X axis 5mm. My code generates "G01 X 5" with a space between the X and the digit. It doesn't seem to matter form Mach3 but might for other controllers, is there a way to suppress the space please? Maybe using that formatting trick?
Latest version with above changes. Also asks for the width of any "flat" on the end of the cutter (reducing feed appropriaetly, and corrects the formula for the depth as I initially misunderstood the geometry.
Posted pic to avoid the smileys, but happy to provide file on request, or download from **LINK**