DIY Professional Double Sided PCB




About: I am an electronics engineer, doing a PhD at the VUB in Belgium. I have a passion for making things, both useful and cool.

Nowadays, PCBs can be bought extremely cheap from China. But let's say you need one within 24 hours, making your own is then the only option. Furthermore, it's way more challenging and fun!

In this Instructable I will guide you through the whole process of making a professional double-sided PCB on a cheap CNC mill, without any chemicals! The PCB features:

  • Double sided
  • Soldermask (green layer)
  • Silkscreen (white text)
  • Copper vias
  • Though hole plating
  • Tinned pads (optional)

It has taken me a lot of experimentation to get to this point. Especially the soldermask and silkscreen have required some work to come to a streamlined process. Let's get started!

Step 1: Parts & Tools


  • CNC mill with:
    • 3.175 mm collet (like ER11 collets)
    • Z probe
  • Nail punch (for making the vias)
  • Hammer (for hitting the nail punch)
  • Sandpaper (fine grid)
  • UV light

A cheap CNC is perfectly capable for the job. Chinese units are about 150-300$.


  • PCB blanks / copper clad board
  • PCB mills: 0.2 mm, 30° tip
  • PCB drills: 1 mm and 1.5 mm
  • PCB mills: 2 mm and 3 mm
  • PCB rivets: 0.9 mm and 1.3 mm outer diameter
  • PCB UV curable solder mask (green)
  • Correcting fluid (tipp-ex)
  • 3 mm alignment pins
  • PCB and alignement pin holder
  • Liquid tin / chemical tin solution (optional)

All parts can be found for cheap on aliexpress or ebay with the names above. The chemical tin solution might be harder to find and can be quite expensive (about 50 bucks for a bottle), but is completely optional.
The PCB holder and alignment pin holder are used to mount the PCB on the CNC bed. You can print them from the zip file or the original designer, 2 copies of each file are needed.

Step 2: Software

Besides a CNC mill and some tools, we will also need 3 programs to make our own PCB

  • PCB design software to design your PCB
  • Flatcam to generate the code for the CNC mill
  • Candle to control the CNC mill

PCB design software

You can use any PCB design software you want. Popular options include: Altium designer, Circuitmaker, Eagle, Kicad,... I will assume that you know how to design PCBs and export the gerber files. If you don't know what these are, creating gerber files for a PCB is like generating a PDF for a text file. It is a standard format to save the specifications of your PCB. You can find plenty of tutorials online for this.


Flatcam is less common, but very easy to use. I will explain every step in detail and guide you through the whole process. When in doubt, take a look at the excellent Flatcam manual.
Flatcam will take our gerber files and convert them into machine movements (gcode) by a technique called isolation routing. To mill a PCB track, we have to mill the contour of the track to isolate it from the surrounding copper, hence the name.
Flatcam has 4 tabs (see picture):

  • Project: gives an overview of the files you opened or created
  • Selected: used to generate new files
  • Options: used to store default settings
  • Tool: used for double sided PCBs

We start by opening a gerber file with File>Open Gerber and it will appear under the Project tab. There are now 3 steps to convert this gerber into gcode:

  1. Generating the isolation toolpath
    • Click the gerber file in the Project tab to select it and click on the Selected tab
    • Here we can enter the settings of the tool we will use and click on Generate geometry
    • Back in the Project tab we see a new file with _iso in the extension
  2. Generating the geometry
    • Click the isolation file in the Project tab to select it and click the Selected tab
    • Now we enter depth of cut and speed and click on Generate
    • Back in the Project tab a iso_cnc file has appeared
  3. Exporting the gcode
    • Click the cnc file in the Project tab to select it and click the Selected tab
    • Click Export gcode and save the file with a .nc file extension

This easy procedure has to be repeated for every layer of your PCB. The specific settings will be covered in the upcoming steps and will be mentioned in metric units. The feed rate will depend on your actual machine. For reference: my CNC has a 300W spindle.


Candle is used to control the CNC machine; another popular option would be Chilipepr. Any software will work, as long as it has the option to make a heightmap (more on that later).
If you own a CNC machine, you'll be familiar with most options and how to control the machine. I will go into the details for the PCB specific options we will need.

Let's start milling!

Step 3: Drilling the Alignment Holes

Before we can start milling either of the two sides, we have to make sure we will be able to flip it once the top side has been milled. To do this, we will create alignment holes, such that we don't lose the positioning when flipping the board. If you only need a single sided PCB, you can skip this step.

Flatcam setup

We will use the Double-Sided PCB tool of Flatcam to do generate the alignment holes. I prefer drilling 2 holes, one at each of the far ends of the PCB, about 5 mm from the edge. Since my PCBs are 150 mm long, I place them at coordinates (5,0) and (145,0). The diameter of the hole will be 3 mm.

  1. Go to Tools>Double-Sided PCB Tool
  2. Add the location of the holes:
    • Point/box: (0,0)
    • Alignment holes: (5,0),(145,0)
    • Dril diam: 3
  3. Click Create alignment drill
  4. Go back to the Project tab: a file called Alignment Drills has been created

This has created a kind of gerber file of the two alignment holes. We can now follow the procedure I described in the previous step to turn it into gcode!

Select the file and go to the Selected tab:

  • Tool: 3mm mill
  • Settings: CNC job
    • Cut Z: -2
    • Travel Z: 1
    • Feed rate: 25

Finally, export the resulting file. It's now time to bring the gcode into Candle and mill the alignment holes.


First, place a PCB in the PCB holders, mounted to the CNC bed. Also add two alignment pin holders, but put them to the side of the PCB for now. Open your gcode file and install a 3mm mill in your CNC.

Next, set the origin vertically centered and 5 mm from the left edge of your PCB (see picture). Start the program to mill the alignment holes.

Place two 3mm alignment pins in the holes we drilled and through the alignment pin holders, as in the picture. The PCB is now firmly mounted and can be flipped in the future! From now on, never change the home position!

Step 4: Milling the Outline

We can now start creating our actual PCB. Before milling any traces, we will do the board outline and create a heightmap of the PCB.

Milling the board outline

Load your board outline gerber file into Flatcam and go to the Selected tab as usual.
Under board cutout, enter the settings mentioned below. We will mill this in 8 shallow passes.

  • Gerber File: board outline
  • Tool: 2 mm mill
  • Settings: Board cutout
    • Tool dia: 2.0
    • Margin: 1.0
    • Gap size: 0.15
    • Gaps: 4
  • Settings: CNC job
    • Cut Z: -2
    • Travel Z: 1
    • Feed rate: 200
    • Tool dia: 2
    • Multi-Depth: YES
    • Depth/pass: 0.25

After generating the gcode, install a 2 mm milling bit in the CNC and start the program!
The PCB will be held in place by 4 tabs, plenty sturdy for the coming operations.

Creating the heightmap

One crucial step to achieve good results when milling a PCB is creating the heightmap. To have a nice PCB, the depth of cut should be perfectly uniform across the whole board. Copper clads are never completely flat, so the mill would go too deep in some places and not deep enough in others.

We can avoid this by probing the height of the PCB in several spots and adjusting the mill depth accordingly, such that the depth of cut is the same everywhere. We create this heightmap with a Z probe: by attaching a crocodile clip to the milling bit and a clip to the PCB, the CNC can detect when both come in contact (since they complete a circuit). This function is implemented in Candle:

  1. Open the Heightmap dropdown menu and click Edit mode. This opens the heightmap settings.
  2. Click Auto to define the probing grid.
  3. Make sure your Z probe is correctly attached, and click Probe.
  4. When the heightmap is created, exit the menu by clicking Edit mode again
  5. Select Use heightmap.

We are now ready to mill the actual traces, let's go!

Step 5: Milling the Top

The top layer can now be milled. We will do this in 4 steps: first the copper traces are milled, next the solder mask is applied and cured, then the pads are milled and finally the silkscreen is added.

Copper layer

First we mill the copper layer with isolation routing. Generating the gcode files is the same as before, with the settings below. Set the zero Z height with your Z-probe and be sure to use the heightmap when milling to get a good result.

  • Gerber File: top layer
  • Tool: 0.2 mm 30° tip PCB mill
  • Settings: Isolation routing
    • Tool dia: 0.3
    • Width: 2
    • Pass overlap: 0.3
    • Combine passes: YES
  • Settings: CNC job
    • Cut Z: -0.12
    • Travel Z: 1
    • Feed rate: 50
    • Tool dia: 0.3
    • Multi-Depth: NO

Applying solder mask

Once the copper is milled, we apply a UV curable solder mask. Spread it over the the PCB with a squeegee in a kind of uniform layer but don't apply too much pressure. Also, leave the PCB in place, otherwise the heightmap will be useless! This is key for the next step! Once applied, cure the solder mask with a UV light until it's hard.

Milling the pads

The whole PCB is now covered in solder mask, so we have to free the pads again. We can do this by milling with a depth of zero. This is where the heightmap shows it strength: it allows to mill away the solder mask but leaves the underlying copper in tact! Since we need to mill the inside of the pads and not the outline, we enter a negative tool diameter.

  • Gerber File: top solder
  • Tool: 0.2 mm 30° tip PCB mill
  • Settings: Isolation routing
    • Tool dia: -0.3 (no typo!)
    • Width: 4
    • Pass overlap: 0.3
    • Combine passes: YES
  • Settings: CNC job
    • Cut Z: 0
    • Travel Z: 0.5
    • Feed rate: 500
    • Tool dia: 0.3
    • Multi-Depth: NO

Making the silkscreen

To finish of the front and make it look like a proper PCB we need one more thing: the silkscreen. In a professional process the text is printed on top of the soldermask, but this is difficult to reproduce. The trick I found is to mill the text in the solder mask like in the previous step, instead of printing it on top. By then applying correction fluid and sanding the top, the silkscreen is embedded into the soldermask!

  • Gerber File: top overlay
  • Tool: 0.2 mm 30° tip PCB mill
  • Settings: Isolation routing
    • Tool dia: -0.4 (no typo!)
    • Width: 1
    • Pass overlap 0.3
    • Combine passes: YES
  • Settings: CNC job
    • Cut Z: 0.03
    • Travel Z: 0.5
    • Feed rate: 200
    • Tool dia: 0.3
    • Multi-Depth: NO

The front is now done and we can move on to the backside. I leave the sanding to the end, when the PCB is completely cutout.

Step 6: Milling the Bottom

Milling the bottom is - ofcourse - very similar to the top. There is however one extra step: we need to flip the PCB and mirror the gerber files before generating the gcode.

Mirror the gerbers

First, load your gerber files for the bottom. To mirror the gerbers, we have to use the Double-Sided PCB tool once again. Select the layer via the dropdown menu and press Mirror Object. Do this for following layers:

  • Bottom layer
  • Bottom solder
  • Bottom overlay
  • Drills (nc drill files)
  • Board outline

The process of generating the gcode is now identical to the top side.

Flipping the board

Flipping the board is as easy as it sounds: release the PCB clamps but leave the alignment pins in place. Flip the board and re-secure it in the clamps. A new heightmap can now be created as before.

Step 7: Drilling the Holes & Installing Vias

The final step on the mill is to drill the holes. We will drill two sizes of holes: 1 mm for the vias, and 1.5 mm for the plated through-holes. This is one of the main advantages of milling over etching PCBs, since etching requires manual drilling.


To open the drill files, select Open Excellon instead of Open Gerber and select the correct diameters in the Selected tab. The other steps are identical.

  • Excellon File: holes
  • Tool: 1 mm and 1.5 mm drill
  • Settings: CNC job
    • Cut Z: -2.5
    • Travel: 1
    • Feed rate: 25

This was the final step, we can now take the PCB out of the CNC. and cut off the tabs holding it in place. A light sanding with a fine grid sandpaper shows off our beautiful silkscreen.

Vias and though-hole plating

The finishing step for our PCB is to install the vias and through-hole plating. You can buy these vias for cheap online in different sizes.

For the vias, use 0.9 mm sized ones and insert them into the 1 mm holes. Use a nail driver to hammer the other side shut and create a solid connection between top and bottom layer.

The plated through-holes use the 1.3 mm variant in a 1.5 mm hole. Since the hole needs to stay open, crimp these with a tool as shown in the pictures.


As an optional last step, the PCB can be tinned. This makes soldering components to the pads easier and prevents them from corrosion. We do this with a solution called liquid/chemical tin, which is essentially dissolved tin, ready to bind to any copper it is exposed to. Wear gloves when handling this stuff though!

Simply pour the liquid tin / chemical tin solution in a container big enough for your PCB and submerge your PCB. Let it sit for about 2 minutes and take out the board (wear gloves!). Rinse it under water and you will see shiny tinned pads and through hole plating!

Step 8: Final Notes

We now have a double-sided PCB with soldermask, vias, through-hole plating and silkscreen, ready for assembly. In case you are wondering what we have been milling, it is an IR based LED strip driver.

Comparison with etching a PCB

As a final note, let's address the elephant in the room: what about etching a PCB?
I have tried etching before, and personally I'm not a big fan of working with and storing chemicals. On the other hand, you don't need a CNC mill, which might be a barrier for some. One pronounced advantage of milling is that the cutout and drilling is not a manual process, and therefore has better alignement.

In terms of time, I have tried both and the time it takes is more or less equal. On the one hand you have to generate the gcode, while etching requires toner transferring (or similar) of the gerber. Where milling takes time, so does etching. Although etching is faster for larger prints, you don't have to stand next to the CNC either.

In the end it all comes down to personal preference; make PCBs the way you want and feel comfortable with! :)


When in dire need for a professional double sided PCB making your own is still the way to go. With this instructable and a CNC mill you should now be able to this! It isn't meant to compete with commercial PCBs, but it can save you if waiting for manufacturing and shipping is not an option.

Furthermore, I really liked the challenge of producing my own PCBs with only a CNC mill and including a silkscreen. Hopefully I have given you some inspiration to try it out yourself! If so, please vote for me in the PCB contest.

I hope you liked the project! Feel free to check out my other Instructables:

PCB Contest

Runner Up in the
PCB Contest



    • Growing Beyond Earth Maker Contest

      Growing Beyond Earth Maker Contest
    • Sensors Contest

      Sensors Contest
    • Barbecue Challenge

      Barbecue Challenge

    45 Discussions


    3 months ago

    Great tutorial!! a few questions:
    1) can you post a link to the UV solder mask
    2) link to the chemical tin

    4 replies

    Reply 3 months ago

    For the UV solder mask, just search on aliexpress. I don't provide links, since the suppliers change so often. Same for the chemical tin, look for "chemical tin" or "liquid tin".


    Reply 3 months ago

    thanks for reply. Im just learning how to use the cnc (missing few componentes to finish my cnc) for prototypes and already download flatCAM 8.913 beta. I use a lot of smd components, and wondering what is the min trace width I can get with cnc (I know it depends on many factors, is it possible to get trace width of .018mm? Do I have to do always the heightmap? thanks for your help


    Reply 2 months ago

    If you want to get accurate results, using a heightmap is the way to go. Unless your PCB is perfectly flat and square to your spindle, the width of the isolation cuts will vary.
    I hope your tracewidth is a typo, 0.018mm is nothing :D I've managed 0.2mm though, but not on the first try ;)


    3 months ago on Step 8

    Hi Thomas, I have mostly made a 3018 system to mimic what you did including the spindle motor and controller. However, I have figured out a problem. My CNC controller card is a later version (woodpecker 3.2A) and does not have a PWM output. The pins you pointed to are now just limit switch inputs. And it does not appear to be an easy way to change the code flashed into the controller. There is not an ISP port nor does it appear to have a bootloader so you can't do it through the USB port and would need to do some soldering on the board to add an ISP port.
    I am working on using the original 0 to 24V spindle output and passing it to a 24v PWM motor speed controller which I can pass to the motor controller you had used. The speed controller uses a potentiometer to vary the control voltage. I think I can pass the spindle voltage through a divider to pass as a control voltage. I will find out as soon as the card arrives.

    10 replies

    Reply 3 months ago

    Hi Gary
    What do you mean with the "original 0 to 24V spindle output"?
    If there is an on-board motor controller, you should be able to tap the signal off there.


    Reply 3 months ago

    I will have to look but documentation / schematics are are not available. Do you have any documentation? My card seems to look the same as yours. Guess I will drag my oscilloscope out and look.


    Reply 3 months ago

    Hi Thomas, I have to apologize, I noticed I posted my comment here instead of "Upgrade-Your-CNC".
    Anyway, I checked the and card there are 4 components. A USB to Serial, the Mega328P, a power Mosfet and a DC-DC converter to provide 12V but no motor controller (and 3 pololu stepper drivers). So I dusted off my oscilloscope and immediately got confused until it ran long enough to actually work correctly, it had been a while. I also found the candle which came with the unit actually works differently than a more recent version as well, I suspect that more recent version had a lower max RPM set but I need to look.
    So actually after probing a bit, I found that the PWM is generated by the Mega328 and then goes from D11 to the gate of the power MOSFET. 24V goes to the red terminal of the motor (It is always hot) and then the MOSFET grounds the motor so without a motor attached the positive pin always reads 24v so my initial approach of passing the motor voltage from the connector would not have worked. I had measured voltage with a motor attached and could see the voltage changing but without a load, the positive pin always reads 24V.
    The pins on the Mega328 are really tight so soldering a wire there would be risky however the bottom pin of the MOSFET is large so I will solder a pin there and run that to the 48V motor controller. Looks Like I am set.
    If you wish to modify the "Upgrade-Your-CNC", the power MOSFET is the component just above the WOODPECKER silkscreen and the Gate is the pin closest to the silkscreen. I suspect anyone who gets a CNC3018 with a later card will run into the same problem.
    Thanks, Gary


    Reply 3 months ago

    Hi Gary
    Great, I will add it to the guide!
    Could you take a picture to make it more clear?


    Reply 3 months ago

    The first image is from your instructable showing the Woodpecker GRBL 0.9. This picture identifies the Power Mosfet and the gate terminal and GND terminal. The PWM signal comes from pin 15 (D11) of the ATMEGA328 microcontroller. it is a 0-5V signal. The 24 Power goes to the pin 1 (+ terminal) of the original motor connector through the motor then to the power N channel Mosfet.
    The third picture is of a MOSFET. Vi is the PWM input (G), Vo is from the negative terminal of the spindle (D) and then GND (S). The 5v PWM signal switches the MOSFET to conduct to ground providing a current path for the spindle
    The second picture is my connections to the power MOSFET. large pins so soldering is easy versus trying to connect to pin 15 of the ATMEGA328.
    Note: my PCB is Woodpecker 3.2A GRBL which is a later version using level 1.1 of the GRBL code. On the 3.2A card, the second Zen pin is no longer connected to a PWM output but is now another limit switch input.

    Also, note my DC spindle speed controller which looks identical to your picture will not accept a DC input. The max speed coded into the GRBL ($30=1000) and the MAX speed in Candle was set to 1000. When running Candle or passing an example file with spindle speed set to 1000, the Woodpecker would go to a solid 5V. This would turn off the speed controller and spindle. If I set the spindle speed to a value between 100 and 800, the motor would run and at expected speed (100 = slow, 800=fast). However, at 1000, the motor would turn off. Looking at the PWM pin on the MOSFET with an Oscilloscope, I would see the expected PWM signal until I got close to 1000 then I would get 5V. At 100 the uptime(5v) would be small with respect to downtime (0v). At 800, I would see the opposite waveform.

    I got around this problem by setting GRBL to a max spindle speed of 1070 ($30=1070). So now when the Woodpecker card sees a speed of 1000 setting from Candle or a file (M03 S1000), I get a PWM signal with very small downtime and the motor runs and is at 46.8V. I suspect there is a threshold drop in the speed controller card so I may not be able to get higher than 46.8V anyway. I do know that if the PWM downtime is too narrow, the speed controller will treat that as solid 5v and the spindle will not run so $30=1050 was not a reliable setting

    woodpecker.JPGwoodpecker 2.jpgMOSFET.JPG

    Reply 3 months ago

    Thomas, you need to click on the jpgs in the prior reply to see the full picture. the thumbnails have trimmed off part of the pictures.


    Reply 3 months ago

    Hi Gary
    Thanks for the picture, I added it to the instructable!
    I also encountered the speed control issue and use 500 rpm for mine.
    Had not thought about updating GRBL, will definitely do that!


    Reply 3 months ago

    I bought a 2nd speed controller (this one has an external potentiometer) thinking I might have damaged the first one in trying to get it to work as I had hooked up spindle voltage to it. I set $30 back to 1000. The second on behaves identically to the first so this particular controller cannot handle a DC voltage at PWM+.
    100% PWM would have been 5V DC.

    So I set $30 back to 1070 and then measured the motor voltage when Candle called for 1000 and also when using the external potentiometer set at max. Both cases I read 46.4V.
    So setting $30 to 1070 will result in max spindle speed when Candle calls for 1000 or on pre-generated files with (M03 S1000). Remember I chose $30=1070 as that reliably worked when Candle called for 1000. Could be for some other systems, you might need to go higher on the $30 value.
    I also hooked a 3 pin switch to a Dupont connector and plugged it into the jumper slot so I can switch between Woodpecker PWM and the potentiometer.


    Reply 2 months ago

    Hi Gary
    It's quite normal that you don't get the full 48V across the motor, since you will have some voltage drop in across the mosfet etc.
    The Dupont connector is a good idea, I have mine connected to a switch to toggle between cnc and manual control :)


    4 months ago

    Thank you so much for such a great tutorial!
    I have just purchased a 3018 Pro model to mill PCB's and will use both of your guides and will post photos as well.
    I had one question which I was hoping you can help me with, there are many different sizes of pin punch for rivets.
    I was about to purchase one which is 180 Euro just before finding this tutorial!
    Would you please post a link to the correct size and model on somewhere like eBay,aliexpress or Amazon.

    1 reply

    Question 4 months ago on Step 3

    Do you think you can do surface mount components? More specifically something like VSOP (.4, .5 pin spacing). If not what is the smallest pin spacing you might be able to do? BTW I did vote for your entry. Very nicely done. Thanks.

    1 answer

    Answer 4 months ago

    Thank you!
    I have already milled PCBs for SMD work. The finest one I did so far was a TSSOP with 0.5 pitch. Here is a picture of the board, I did not add the soldermask since it was for prototyping purposes.