cog - Perl extension for cutting cycloidal gear wheels and related items out of sheet metal


  use CNC::Cog;
  use CNC::Cog::Gdcode;                  
  use CNC::Cog::Gcode; 

Of the last two modules above, only one is strictly speaking necessary at a time. They provide the output functionality for the cog module. If you use gdcode, then you will also need the perl module GD, which produces a .png file of the output instead of the G-code.

  $c=newcogpair cog(3.0,7,18);      # make a pinion and a wheel module 3, 
                                    # with 7 and 18 teeth respectively.

This generates two wheel objects, pinion and wheel, which are closely based on the british standard for cycloidal gear wheels.

  $c->cutset({cuttersize=>0.125,passes=>3,passdepth=> -0.025 }); 

This sets up some information about the cutter to be used. Things like


have a similar effect.

The function can also be called as

  $c->cutset(0.125,3,-0.025); # cuttersize, passes, passdepth

or as


Note that the passdepth should always be negative. These dimentions are in inches, as are nearly all dimentions here, except for module which has dimentions of mm. This is a bit incongrous and needs to be fixed.


Produces holes of the appropriate size (diameter) in the center of the wheel. The hole size can be any size greater than or equal to the cutter size.

  my $feed=3; 
  my $g=new Gcode("test.ngc",$feed,5);    

This produces a graphics object that generates G-code in the file specified. The feed rate will be as specified, and the cuttercompensation will be based on (in this case) tool number 5. You need to ensure that this has the same diameter as specified in thgis code in your tool table, as otherwise the cutter compensation where used will give incorrect results.

  my $g=new Gdcode("test.png",4.50 ,400,400);

This is an alternative line to the line above, and produces a similar object with the same interface, that produces a png file. It is a square file scaled 4.5 inches in the y direction and of size 400 x 400 pixels. in the example given. Note that you can increase the resolution by increasing this number but if you make it too big, as the lines are only ever 1 pixel wide some viewers may not show any lines unless you zoom in. However I often use pixel sizes between 1000 and 8000 to see the fine detail.

  $g->ginit();                # initialise the graphics object.                

  $c->{wheel}->cut($g,0,-0.75,0); # cut the wheel at this location x,y,z. 
  $c->{pinion}->cut($g,0,1.25,0); # cut the pinion here. 

  $g->gend();                 # finalise graphics operations, write files etc.                       


This package allows cutting of cog wheels from sheet metal that are tightly based on the british standard. It also allows a few other objects to be cut including a Graham style escapement, wheel bosses and holes. Objects can be stacked one on top of the other, cutting the combined object out of a solid block of metal.


The following classes are intended for top level use:

  Cog - generates a meshing pair of toothed wheels. 
  Wheel - instance of a toothed wheel.  
  Boss        - Wheel center for physical attachment
  Ring        - represents a cylendrical space, possibly needing several
                passes both in depth and radius.  
  Hole        - class for a hole. 
  Stack       - cut one or more objects on top of each other
                with this special class
  Grahamwheel - wheel for Graham escapement
  Grahamyoke  - yoke/anchor for Graham escapement 

Each of these are described below.


A Cog object has two components each of which is a Wheel. Therefore a cog object is really a pair of Wheels. They are generated to mesh with each other and the shape of the teeth especially in the pinion is influenced by how many teeth each wheel has.

The Wheels need to be individually cut.

The following methods are available:

newcogpair cutset


Can be called in two ways, either with parameters as follows:

   module    Module
   np        Number of teeth on the pinion. 
   nw        Number of teeth on the wheel. 

or it can be called with a hash reference with the following parameters:

   dpi       Diametrical Pitch, number of teeth per inch at the pitch diameter
             Note: module=1/(dpi*25.4) Either module or dpi should be used. 
   np        Number of teeth on the pinion. 
   nw        Number of teeth on the wheel. 

In both cases nw should be greater than or equal to np.

It is necessary to call cut on the wheels in a cogpair seperately to ensure they are plotted in seperate places.


This function when called on a cog pair calls the function by the same name on each of the two component wheels. The parameters are as follows:

  cuttersize   The size (diameter) of the cutter being used to cut the wheels
  passes       How many passes to make vertically. 
  passdepth    How deep to go on each pass. Should be a small negative number. 

  Alternatively a hash ref may be provided with some of the following keys: 

  passes       *
  passdepth    *
  depth        *

Descriptions are as above. Out of the parameters marked *, any two may be provided. holedepth is a synonym for depth and does not designate that there is to be a hole.


This is the basic class for a cog wheel. Methods are as follows. Note that no code is produced until the cut function is called, and that the cut function can be called more than once at different locations.


Sets up certain parameters. Identical to cog->cutset. See below.


This refers to lightening the wheel by cutting windows in it. A variety of different window shapes may be cut, all of which result in some kind of spoked wheel. You might also achieve a similar effect by cutting holes, but I have not done this. Parameters are as follows:

        spoken  Number of spokes
        wos     Total width of spokes in inches. Needs to be significantly
                    less 2pi * $br. 
        br,     Boss radius in absolute in inches, the solid bit at 
                center of wheel
        rt,     Rim thickness in inches. 
        roe,    Radius of window edge in inches, the curved radius of the
                    join between a spoke and the rim or boss
                Note: that this must be more than the cutter size or you 
                        cannot cut it! This is radius, not diameter. 
        wobf,   Width at base factor, > 1 for wider spoke base. 
                    Tapered spokes anyone ? 
        srf    Spoke rotation factor rotates spoke position this 
                    proportion of a full rotation on relative to outer rim.  
                Think rubber spokes! values 0 to 0.1 give good results. 

Not that not all values will allways work flawlessly, in particular if you make the spokes so wide that they will not fit round the boss in the center of the wheel, then this is not detected and will cause faulty output.

The linear dimentions wos, br, rt, roe may be given as strings terminating in any of the following:

t Take measurment in thousandths of an inch p Take measurment in seventy-twoths of an inch, points mm Take measurement in milli-metres i Take measurement in inches, default.

so any of the following would be valid as the second parameter of the trepan function and should give identical results.

"12.7mm" , "0.5i" , "0.5" , 0.5 , "36p", "500t", "500.0t"


Create a hole in the wheel. The hole is cut to the same depth as the wheel.

Parameters are are as follows:

       diam  Diameter of the hole in inches or other units.


Cuts a circular indented area at the center of a wheel perhaps for helping with ataching some other part mechanically.

  diam          Diameter. 
  passdepth     Depth of each cutting pass. 
  passes        Number of passes
  feed          Feed rate. Optional. If not provided, default will 
                be used. 


Actually generates code or graphical output. See below.


This object has many of the attributes of a wheel, and but represents ring-shaped space that is machined out.

A ring has the following functions:



returns inner radius in inches.


returns outer radius in inches.


See Wheel->hole()


May take either a hash reference, or the following parameters:

    cuttersize    Diameter of cutter being used
    passes        How many passes to make. 
    passdepth     Depth of each pass. 
    r1            Start radius
    r2            Final radius
    z             Depth at which to start cutting out the ring. 

In the case that a hash reference is provided, the following keys are recognised:

    cuttersize    Diameter of cutter being used
    passes        How many passes to make.
    passdepth     Depth of each pass.
    r1            Start radius
    r2            Final radius
    z             Depth at which to start cutting out the ring.
    holesize      Diameter of hole
    holedepth     Depth of hole
    holepasses    Number of passes for hole 
    holepassdepth Number of passes for the hole. Any 2 out of these last three only
                  need to be provided. 

Any linear dimention may be in non default units, see wheel-> trepan.

r1 are the initial and final radii. r1 can be greater than r2 or vice versa, but the cutting will start at r1 and move in or out as appropriate towards r2.


Actually generates code or graphical output. See below.


The stack class is used for cutting 2 or more objects at the same point on a piece of metal. It is assumed that they will be stacked in the order smallest on top and largest under neath, and that each object will have an area that is not machined in the center so that the object above can be machined there. The stack function automatically machines out space surrounding smaller objects so that the way is clear to machine the larger objects underneath.

Methods are as follows:



Creates a new stack object to which other objects may latter be added.

Parameters are as follows:


These values are used as defaults or for new objects created as part of the stacking process, not for the objects in the stack itself.


Takes 1 or more objects and adds them into the stack. The objects should be in the order, the object nearest the top to be first. Add should be used only to add larger objects if it is used more than once.


like add, alo takes 1 or more objects and inserts them into the stack , except that objects are inserted before all those that currently exist. Smaller objects should be inserted. They will be machined nearer the surface.


All the objects in the stack will be cut at the x and y co-ordinates given, starting at the z co-ordinate given with further objects plotted lower down to suit.

Takes parameters x, y, z.


This is subclassed from wheel and so all wheel methods apply. A Graham wheel is defined as a a wheel with straight sided teeth, the sides being inline with a point offset from the wheel center so that the teeth slope. The teeth may be narrower at the top than the bottem, and the relative amont of space on the wheel circumference given to the tooth and the intertooth gap may be controlled. The tooth is topped with a shape that may be chosen from a number of alternatives.


The new function of the Grahamwheel class needs to passed a hash with some or all of the following parameters:

  lift              If a flat tooth top is used then this parameter can be 
                    used to increase the height of the trailing edge of the
                    tooth top. 
  nteeth            How many teeth to have.
  externald         The external diameter of the wheel. 
  toothdepth        How deep the spaces between teeth should be.
  toothtop          Size in degrees of the top of the tooth. 
  toothtoppc        Alternatively, size as a percentage of 1 tooth-and-gap. 
  toothbase         Size in degrees of the tooth at the base
  toothbasepc       Alternatively, size as % of tooth-and-gap. 
  offset            In degrees of top of tooth from bottom. 
  holesize          If set, gives a hole at center of wheel. 
  topshape          Should be one of the following strings: 
                       flat       Gives a flat tooth top
                       circ       Similar to flat, but give a circular
                                  shape centered on the wheel center. As
                                  This is a large distance, this is nearly 
                                  flat. Flat may work better with the lift
                                  parameter set. 
                       bicirc     Two approx quarter circles are used with 
                                  a flat piece in between them 
                       circlead   The leading edge only is rounded. 
                       circtrail  The trailing edge only is rounded
                       semi       A (near) semi circle of the right diameter 
                                  is used. 
  toothradius       The radius used in bicirc, circlead and circtrail
  toothradiuspc     Alternative using percentage of tooth-and-gap
  filletradius      radius used at botto of tooth. Must be greater than cutter


The cut function takes an optional extra rotation parameter theta as well as conventional x,y and z parameters. See below.



New takes a has which may contain any of the following parameters: Nearly all parameters may have l or r added to the end in case different parameters are required for left and right, otherwise both left and right sides will be the same. This does not of course mean symetric since lift is always applied in such a way as to lift the yoke.

Parameters that may have l and/or r applied are as follows:


Parameters and their meanings are as follows:

    lift        lift degrees (of pendulum swing)
                This is the angle that force would be applied to the pendulum
                if no rounding on wheel or yoke tooth edges is used. If these 
                are used then the angle of applied force will be greater. 
    r           Innerradius of yoke.   
    armwidth    This is the thickness of the non-tooth part of the yoke. 
    width       Thickness of the teeth. 
    innerradius Cosmetic - This is the radius of inner curves, except
                for the lower one. 
    outerradius Cosmetic - This is the radius of outer curves, except 
                for the upper one. 
    topradius   Cosmetic - radius of top curve
    botradius   Cosmetic - radius of bottom curve
    angle       This is the angle subtended by the tooth at the suspension 
    holesize    Diameter of a hole (if any) place at the pivot point. 
    leradius    Leading edge radius, if any. (Otherwise, sharp) Trailing edge
                is always sharp. 
    droopangle  Angle that yoke top makes with horizontal. 

Quantities marked cosmetic are cosmetic only in the sense that they do not affect opperation directly. The inner radii need to be bigger than the cutter as otherwise cutting will not be possible. All of these as well as being specified in arbitrary units in the normal way, may also be specified as percent in which case this is taken as percent of armwidth. For example


Where angles are supplied, these can be supplied in radians by appending an r to the value:


Such values are lift angle droopangle

As is normally the case, linear dimentions may have units appended and will be converted. These are

r armwidth width innerradius outerradius botradius topradius holesize leradius

and l-r varients.

Example Code For Graham

The Graham wheel and yoke are in a more experimental state than the rest of the code. The code below is the code I used:

  my $nteeth=40; 
  my $w=new Grahamwheel({
                offset=>2,      # degrees 
                toothbase=>30,  # percent of whole tooth gap. 
                toothtoppc=>8,   # percent of whole tooth gap, ie of 360/nteeth
                lift=>0.00,  # inches
                filletradius=>0.033,    # radius used to cut tooth gap, in 
                               # inches, should be just greater than cutter. 

  my $sheetthickness=0.135; # Nominally an 1/8 inch sheet, Make slightly more
                            # to get a clean cut 
  $w->cutset(1/16,5,-$sheetthickness/5); # cuttersize, passes, passdepth
  $w->bossindent(0.25,-0.015,1);  # diameter indent, depth indent, num passes

  my $cuty=0;  # set non zero, eg -0.9 to seperate parts for cutting. 
  $w->cut($g,0,$cuty-0.2,0,0); # cut the wheel. 

  my $pi=4.0 * atan2(1, 1);

  my $ns=8.75;  # how many teeth to span, more gives less swing 
  my $angle=16;  # working face angle, from center line.
  my $a=360*$ns/$nteeth/2; # angle between yolk tooth and vertical at wheel center

  # externald - toothdepth/2 from above   
  my $h=(1.75-0.1/2)/2/cos($a*$pi/180); # This is dist between centeres of 
                                        # yoke and wheel. Gives 90 deg line 
                                        # of action. 
  my $R=sqrt($h**2-(1.75/2)**2);        # length of arm

  my $droop=$a-$angle; # Droop angle. 
  my $ltg=2*$pi*(1.75-0.2)/2/40;        # linear tooth gap, used to get 
  print "ltg=$ltg\n";                   # size of yoke teeth about right

  $w=new Grahamyoke({ droopangle=>$droop,

  $w->cutset(1/16,5,-$sheetthickness/5); # cuttersize, passes, passdepth


Comments On The Code

There is a lot of ugliness here. Many constants are added in and then written in explicitly further down. I know this. Its clear that some further encapsulation is needed. I've not done that yet because I've not yet finished testing my escapement. I include the code because its difficult to see what I'm doing without it. Its a basis for you to experiment.


Cuts a cylendrical piece of metal with or without a hole at the center. Intended to be attached (in some way) to a wheel a grubscrew maybe enabling attachment to a shaft.

Methods are as follows:



Parameters are



Actually generates code or graphical output. See below.


Methods are as follows:



    cuttersize      Cuttersize, less than or equal to hole diameter. 
    passes          Number of passes 
    passdepth       Depth of each pass
    diameter        Diameter of hole


Actually generates code or graphical output. See below.


This is a convienence class used in cutting Grahamwheel and Grahamyoke. It effectively stores an array of points to cut and enables certain operations like rotateion or translation on the pointset. As it turns out its a much better way of generating parts and wheels than that used in parts written earlier. Well, you live and learn.

Not required for use of high level functions.

General methods

General methods for most classes are as follows.

cut new (covered above.)


parameters are as follows:

    x      Placement location x coordinate.
    y      Placement location y coordinate
    z      Placement location z. You should normally set up the machine
           so that z=0 corresponds to the metal surface. z can be set to some
           neagative quantity if some metal has already been machined away. 
    theta  Available only on Grahamwheel and Grahamyoke, adds an optional 
           rotation to the pieces. Used mainly in checking design of 
           generated pieces before committing to metal. 

It is possible to call cut any number of times on an object, at a different place in the x-y plane to cut out another instance of the object.


Generate a new object. Parameters vary, see above.


G-code is a many headed serpent, and I cannot say what the compatability with your version or machine will be. What I can say is that the code produced uses only the most basic primatives: moves in straight lines and arcs, so that I expect it to be compatible with much. However, it is certainly possible that your set up requires some different code or initialisation or finalisation. I'd like to hear about this.

The code has been tested on a Sherline table top CNC Mill, using EMC to drive it, so the varient of G-code used is that understood by EMC.


Before you feed any G-code generated by this module to a machine tool you should satisfy yourself by whatever method, that it is safe to do so. Machine tools can be dangerous if used improperly and nothing in this document should be taken as implying that this is not so. USE AT YOUR RISK!


When using Gdcode and GD, there appear to be inaccuracies in some of the arc functions. These show up as small disjoints in the lines near one end of an arc. I have not been able to track this down.

I have not got round to involute gears yet.

Installation doesnt work correctly under Unix operating systems due to faults in packaging and the packaging system that need a cleverer man than I to fathom.


Some examples with photographs are here:

Its possible that this has grown since this package was posted on CPAN. If not then the same documentation can be found installed with the perl source files.

The theoretical material for gearwheels (with the exception of the Graham classes) draws heavily on this reference:

The EMC home page is here:

This defines the varient of G-code that I am using a subset of.


Mark Winder <>


Copyright 2005 by Mark Winder

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

I would be intrested to hear from anbody who has comments or experiance of its use.