FlatCam and bCNC for Scratch Milling

Milling a PCB requires two ‘abnormal’ things – you must convert the circuit image to G-Code contours, and you must drill to a very exact depth relative to the not-so-level surface of the copper. Fortunately there are two wonderful open source programs that can handle these requirements – FlatCam and bCNC.

FlatCam has the ability to import gerbers and drill files, and output G-Code. As a bonus, it can remove extra copper by generating multiple contours around traces, and a built-in tool for generating two sided boards.

bCNC can run G-Code and other instructions on most milling machines. It has built in support for autoleveling, which allows you to calibrate the G-Code to the precise heights of different parts of your copper clad board.

These programs can be a little hard to get used to, but once over the hump they are very powerful, and the code underneath is very solid. Here is a step by step of my process – if you have a better process or new ideas, *please* let me know. This is far from the final word on anything.


Preparing a project in FlatCam requires many small step that need to be done in the correct order. It’s a task that is ripe for scripting, and it seems to have excellent support for scripting, so once this process stabilizes I will try to automate this all. In the meantime it is really helpful to lock in some defaults for your setup. This can be done by changing settings in Edit>Preferences – this will not only save you time, but it will prevent many little errors that come with entering so many parameters.

First, import your front copper gerber file (File>Open>Gerber, or Ctrl G). The FlatCam workflow is gerber files generate geometry files (which have vector shapes and contours), and then geometry files generate G-Code (that will control your milling machine). The Project tab holds all of these imported and generated files, and the Selected tab is used for adjusting the settings. On the right side is the plot area that shows a preview each file. All files are visible by default, but you can right click on elements in the project an Enable or Disable them from plotting.

Double clicking on the first gerber file will bring up the Gerber Object settings (this automatically moves to the Selected tab). There are two tasks here, setting the offset and then the number of passes to make.

We need to put the gerber file into the exact position we’ve set up with our mill jig. Because we can generate multiple files per gerber, this is best done first thing. Go to the Transformations section at the bottom, and enter the offset from the home position for your jig. This should be the offset from (0,0) to center of the bottom left pin. Note this is not the bottom left corner of your board – the pin positions are the only truth here. The format is (xx,yy). This move is always relative to the current position so be careful, hitting offset twice will move it twice. If things get screwed up don’t worry, you can just delete things in the project and re-import the gerber (that sounds like a joke, but it’s actually really easy to start over once your default settings are in place).

Next is set the number of passes. I usually only use one pass and it works fine, but for a little extra ease of soldering you can use two. You will have to experiment with optimal settings for your setup. The depth you scratch determines your contour width, and you want the two contours to slightly overlap (with no marker at all in the middle). I usually select Combine – this generates a single G-Code file rather that one for each pass.

Two Sided Boards

For a single sided board we would be ready to generate the isolation geometry, however for a two sided board we’ll need to do some flipping. This is done with the super useful and appropriately named “2-Sided PCB” tool, found in the Tool menu (Alt-D). Make sure you have properly ‘Offset’ all layers before this step.

Assuming you have rectangular edges, this is a very simple process (if not you can use alignment holes, or plain old math). First, we are flipping the board side to side which is along the Y axis, not closest to farthest which is along the X axis. Second, it is imperative you flip the back copper and drill files, not the front. It will look all correct if you flip the front, and all the drill holes will line up, however when you go to solder you’ll realize all your chips are expecting a mirror image of what they are. Yes I’ve done that.

Select Mirror Axis: Y and Reference: Point, drag select your boards, and then simple click ‘Calculate Bounds Values’. This will fill in all the parameters needed for the flip. Next move up to the Mirror Operation section and make sure your bottom copper layer is selected. Mirror that layer as well as the Excellon drill file. That’s it, we are now ready to generate geometry.

Geometry and G-Code

Returning to the Gerber Object, you can now Generate Isolation Geometry. This will open the Geometry Object settings, where you set the tool parameters. The important thing here is Cut Z – that is the depth you will scribe into the copper layer. This needs to make a groove wide enough to ensure no bridging between traces, both with etching and soldering. I find -0.04 mm works for me. I’ve tried doing to passes with the same geometry, once at -0.03 and a second time at -0.05. This works as well, though I didn’t find it particularly better, just took a little longer due to two passes. If you have trouble with soldering and etching you are probably better experimenting with multiple passes (as set in the Gerber Object) than varying depths. Also use stronger and warmer etchant, as a fast etch does as much to ensure no bridges as a deep groove does.

The other things to notice, you do not spin the scriber bit, it just drags along. So Spindle Speed: 0. And look at those feedrates! I set the X,Y feedrate to 2500 mm/min because that is getting to the top speed of the Nomad 883. Really there is almost no cutting force as the bit is just dragged through a tiny amount of copper and some ink. The Z rate of 400 mm/min is also probably conservative, but it doesn’t spend much time going up and down. Also the retraction height can be very low (Travel Z: 1 mm) due to the board being leveled.

With that, you can click generate CNCJob Object and export the first G-Code file by clicking the Save CNC Code button. When moving to the back layer, the tools will be back to defaults, so if you’ve changed those be sure to readjust. Also if you do change anything, you will need to click ‘Apply Parameters to all Tools’ – that will make more sense in the Excellon drill file. You can store custom tools and settings in FlatCam, but because scribing is so simple I’ve only ever needed defaults once they were set up. Once you are used to the process, you can start milling the front PCB as soon as it’s ready, then while it is running process the back side and drills.

If your machine and software supports tool changes, you can export all the drills at once from the Excellon Object. With PCB drills, I use the same speeds and feeds for all sizes. I set the spindle speed to max (10,000 rpms in the Nomad 883’s case), and then adjust the feedrate. I’m not too aggressive here as drilling doesn’t take that long and those bits are fragile. I also drill slightly offset holes to allow putting SMD’s inside the board — probably not the recommended use case for these tiny bits.

If you need to export bits separately, just make sure you only have one selected at a time. It will help a lot to name the exported G-Code with the drill bit size in the filename, as there will no longer be prompts at tool change time. Lastly, double check the tool feeds and speeds for each bit.

Lastly you can carve out the board along its edges if that is needed for your prototype. You can use the edge cuts layer, or even a design from Fusion 360 or CorelDraw if you prefer, as the exact location of the board is known. I use bits, specifically designed for cutting PCBs, but most small bits should work. Safety note: this is the only step that generates fine PCB dust. It is very important that you have a good filter on your vacuum, ideally a HEPA filter, but a small particle filter works too. You can also cover the area being milled with drops of oil if using a plastic jig — this will capture a lot of the dust (though make a slight mess of your jig). FR4 is a type of fiberglass, and breathing in tiny shards of glass is as healthy as it sounds.