Using LineGrinder to make PCBs

Contiuing from this post about using my CNC machine to create PCBs, here is an update on the tool chain from designing circuit board to milling them on my CNC machine. This process is still not perfect, but this is just to remind me of the settings and hopefully it might be useful to other people.

The tool chain I use tries to include free and open source programs (but I rate ‘ease of use’ above ‘open-source-ness’).

The tool chain at present is:

  1. KiCAD – To design the circuit schematics and circuit boards
  2. LineGrinder – To generate the g-code from gerber files
  3. LinuxCNC (previously called EMC2)- To control the CNC machine based upon the G-code.

I have written a post on the CNC machine at re-innovation. It is a relatively small machine with a bed of 300mm x 200mm and a depth of 70mm. I have been using it to cut acrylic parts, drill holes for etched circuit boards and cut holes into boxes for some prototypes.

I have been messing around with LineGrinder which is a free and open program, but only available for Windows. I am using it on a Windows 7 machine.

A useful on-line tool, the G-Code commenter can be found here. This takes G-Code and adds human-readable comments next to each line. This turned out to be very useful for decoding the output of LineGrinder. G-code is relatively human-readable, but I have not memorised all the G-code commands yet.

Here are my notes on getting the correct outputs from KiCAD and the settings within LineGrinder to mill PCBs.

This is the PCB in KiCAD I was trying to mill. I set an Auxillary axis (0,0) point to the top left corner of this board (the same set-up as my CNC 0,0 point).

Go to File -> Plot and you will get this list of options. I wanted the front and back copper and the PCB_edges to be produced. Check those boxes and click ‘Plot’. I also need a drill file.

Click on ‘Generate Drill File’. I used: ‘millimeters’, ‘keep zeros’, ‘Auxillary Axis’ and ‘Mirror y axis’ and then clicked ‘OK’.

Open up LineGrinder and try and open the .drl file you have just created in KiCAD.

I got this error message which says that the .drl file is in mm, but the settings are in inches.

So click on the ‘Settings’ tab and change Application data to ‘Millimeters’. Click on the .drl option on the left had side and you will get the various properties shown here. In these properties you can set the drill depth, drill feed rate, drill moving height and other options.

Click ‘Generate G-code’ and hopefully it will compile correctly. Go back to the ‘Plot View’ tab and click on ‘Drill G-code’. Mine looked like this, which is good. Save the drill g-code.

You can view the generated g-code which is a good idea to check. When I first looked at this I had made some errors and needed to adjust the values explained above.

The next thing to do is open the gerber file for the copper. I was making a single sided PCB and just wanted the back copper. This would be milled from the top, so I needed to reverse the file. Open your .gbl file for the back copper (the file from KiCAD is not automatically recognised, but does open correctly as a gerber file).

Again there are options associated with this type of file. I chose an isolation cut, but I needed to change back to inches. I could not find a way of exporting from KiCAD in mm. Things to note include the ‘Y Flip’ (as I was producing a file for the bottom copper, but cutting it from the top, if you see what I mean) and the ZCutLevel which was -0.002 inches. I might need to adjust that.

I created the G-code and then viewed i using the viewer. It looked as above. The text on the board is the correct way around, which means it is correct. This screen shot was done when I had a ground plane, hence it is quite complex. It was too complex for my CNC and so I needed to remove the copper fill from the KiCAD board. This made everything run much more smoothly and reliably.

Also check this with the drill output file – are holes where you think they should be?

The last features were the board edge milling and board levelling. This is a great feature, but I could not get it to flip on the Y axis, so could not use this feature. Line Grinder can read in the board edges and create the board edge mill path (along with tabs to hold the board) and also perform a board levelling pass which flattens a piece of sacrificial substrate to the correct depth and exactly flat so the isolation cut will work correctly.

This is the board edge mill path (along with tabs). I cannot find a way to flip this on the Y axis, hence I could not use this for my board. It would work if I were to drill and cut on one side and then flip over. I will try this another day….

This is the board levelling output – it creates a box around the board edge and levels an area bigger than the board. This is good, but I alredy have a levelled board to use so I did not need it for this test.

Now we use these g-code files for LinuxCNC, which controls my CNC machine.


There were some issues with opening the g-code with LinuxCNC – mainly due to an error from the G02 and G03 commands, which draw an arc. I solved this error by removing the copper fill (this would not be needed, as this will happen automatically with isolation routing). The issue had been the tiny cuts around the holes connected to the copper fill plane (this was connected to ground in my case).

The next issue was due to the drill file and isolation file not fitting on top of each other. I had created the drill file using ‘Mirror Y axis’ option in KiCAD. The isolation path is created using the ‘Flip Y’ function. This meant that the drill file had positive X and Y values, while the isolation path g-code had positive X values, but negative Y values. They would match up but only with adjustment of the origin. This was a hassle. You cannot flip the drill file using LineGrinder (maybe a feature for next time?).

I have come up with a workaround, which gets me where I need to be, but is not very automated and is a bit of a hassle.

The isolation path generated also creates some code to do small ‘pecks’ at the points where the drill holes are meant to be. This is to aid hand-drilling of the PCB. I decided to go into the G-Code and adjust these points to make them the actual drill holes. To do this I needed to find that section of code (which is luckily called ‘Pad Touchdown’):

Where the line (… pad touchdown start …) is, I added a move in the Z axis (G01 Z1.000) (This was in inches), so I have room to change the bit from the isolation cutter to the drill bit. I then a generic ‘change tools’ command (T01). This will cause the code to stop and ask for the new tool bit.

The second time I ran this code, it did not ask for the tool to be changed (and ruined an isolation bit as it plunged into the substrate!). The reason is that once the machine thinks it has the correct tool, it will not ask again. So I needed to change the tool to a different tool right at the beginning so that it will always ask to change tools. This meant adding code as shown here:

I was now ready to try this all out…

The CNC machine has a milled flat bed. This ensures a level substrate so we get even isolation paths.

I used some scrap single sided copper clad board.

This was stuck to the milled flat bed using double sided carpet tape. This worked OK, but the copper clad board had a slight warp and the tape was not strong enough to hold it totally flat. I should have kept the copper clad board with a weight on it to keep it flat. It did not make a huge difference on this relatively simple circuit board.

Above is a 45 degree isolation routing bit. This has a very sharp tip to cut away the copper.

This is the PCB after both isolation routing and drilling. An attempt where the drill did not hit the isolation path can be seen on another bit of the copper clad board.

This is the final board after I had cut it out.

The prototype board with components.

The underside of the PCB. It was a 2 sided design, hence there are some jumper wires on this board. I had actually made no mistakes with the circuit design of this board, which is unusual for me.a

The board was a ‘shield’ for an Arduino clone, to run and RGB  LED unit. Here it is plugged in and working.

Things to improve:

  • Strength of sticking down substrate (the copper board still had a warp, which meant uneven isolation traces).
  • How to produce drill files correctly or include different sized drill holes.


I’ll put up relevant links here:


Leave a Reply

Your email address will not be published. Required fields are marked *