3D Printed PCB mill

3D Printed components and other hardware to make a PCB routing machine, which inherently can do other things.

Similar projects worth following
PCB routing machine, with a software suite to create designs and control the steppers to make that design a real life thing. For funsies.

Ill get to this later.

Portable Network Graphics (PNG) - 1.66 MB - 08/29/2018 at 02:51


PCB Mill 28Aug18skb.skp

The sketchup of all the parts

SSEYO Koan Play File - 7.86 MB - 08/29/2018 at 02:50


The limited CAD program I made to easily design quick little things. The circuit board designs for the controller was made with this. Updated it to produce G Code and send it to the DCNCTerminal program.

x-zip-compressed - 1.83 MB - 08/29/2018 at 02:47



Windows program, syntax colored text editor for teh gcode subset the firmware interprets, and also sends the "gcode" to teh controller. Updated to include a parity byte for dem corupt messages u noe.

x-zip-compressed - 109.25 kB - 08/29/2018 at 02:46


Firmware 28Aug18.ino

The limited subset gcode interpreter firmware for the arduino (well the cheap cheap chinese copy) that controls the machine.

ino - 21.80 kB - 08/29/2018 at 02:43


View all 19 files

  • 2 × 255mm 8mm rod The Y axis rods to guide the Y axis carriage (holds the dremel)
  • 4 × 180mm 8mm rod The Z axis rods to guide the Z axis carraiges
  • 2 × 300mm 8mm rod The X axis rods to guide the X carriage
  • 2 × 150mm 8mm lead screw Lead screws to move Z axis carriages
  • 16 × 8mm linear bearings For the carriages

View all 16 components

  • The gcode editor and terminal

    DTeel11/16/2016 at 01:36 0 comments

    aight aight, i modified a syntax coloring editor i maed a wile bak to hilite dem gcodes, and den i made a wae to make dat program send da code dats in da editor to dee controller to mayke it do wut u want.

    da filez be uploaded, along wit da new firmware 4 dee ardweeno. nah im sayin.


    As a test, I wrote my name in DesignSparks whateverthefuckprogramitscalled, then exported it to a gerber file, then imported that to FlatCAM, which exported G Code, which I imported to this DCNC Terminal program, when then exported it via a serial connection to the controller, which then exported wood off this block of wood to make this.

    The feed rate was definitely too high on the top one, so I lowered the feedrate, and gave it another go (the one I highlighted the lettters with sharpie) and turned out aight.

  • G Code

    DTeel11/07/2016 at 00:19 0 comments

    So G Code is dumb, luckily FlatCAM outputs G Code that makes sense to me. Instead of having a whole line of commands, that need to be interpretted in a different order then the order recieved, it just sends one command at a time which is easy to interpret on an Arduino, dont need to worry about loading the entire line, and then picking through and running stuff in different orders.

    The firmware is real simple, theres a 128 byte line buffer that reads in until it gets a carriage return or line feed, once it hits that, it goes to an interpret routine which runs through and if it sees what I call a word (X,Y,Z,F,P) it will read in a real number, and store that in its associated variable. If it sees a G, it will read in an integer, then read for words, and then execute that command. If it sees an M, then it currently just ignores it and continues interpreting the line. If it sees an error, then it will update an error flag variable, and then output "error: <description here>", to let the operator know whats up. If it doesnt see an error, after interpreting it will output "ready" telling the sending program it can send the next line.

    I implemented an actual bresenham line algorithm using longs instead of floats to make the routine quicker and easier to implement fairly accurate feed rates. The only real issue is when the Z axis is the dominant axis since it has 400 steps per mm versus the X/Y which only has 80 steps per mm. With that, if the Z axis has to step 400 times, and the X axis has to step 400 times, the X axis would need a longer minimum delay time between steps then the Z axis or else the motor will stall, words suck and I dont want to put in the effort to make my brain thoughts into them.

    So far it supports G0, G1, G4, G20, G21, G90, G91, G93, G94. It'll read the M commands and just ignores them, but the only M commands I find that flatcam outputs is like spindle on and shit like that, and since Im using a manually operated dremel, thats no issue.

    For developing, I've made all the locals static to get a better idea of how much RAM I'm using, which is only 429 bytes out of 2048, which leaves plenty on the stack for parameters and return addresses. And its only using 30% of the program memory, so I still got plenty of space for adding other shit to it.

    Ima make the program that sends g code files to the controller a little fancier and then do some test cuts. I'm pretty happy with it so far.

    EDIT: I did a quick tape-a-pen-to-the-dremel-carriage-and-tape-a-notepad-to-the-y-carriage test, and it looks pretty good. I stopped it during the drill hole phase and sent it back to 0,0,0, hence the line through it all.

    versus the flatcam expected

  • moar werk

    DTeel10/12/2016 at 05:30 0 comments

    so I made another small change to make use of some scrap rod i had to reinforce the x axis, its that top spar in the new image.

    I got some particle board to get a real flat surface for the top layer, drilled some holes, cut some holes, did a light sanding and put some sealant on it, and did the same for the bottom layer. Its got a way cleaner look now, the wires now get tucked underneath through some holes in the top layer and run towards the controller. I finally fixed the controller and the keypad to the fixture with screws instead of tape to make it easier to move around.

    Im thinking instead of make a new version of my CAD program, I'll just make a program that will interpret gerber files and send the appropriate commands to the machine. That way I'll be able to use whatever CAD program I want (that exports gerber files), but whatevs, i dunno.

  • Updating the parts

    DTeel09/23/2016 at 03:32 0 comments

    So I was tweaking parts in sketchup, developed a way to tension the belts for x and y axis (z is lead screws so dont need that there) and printed them out and it works pretty good. After that I redesigned all the parts making them beefier, which makes everything stiffer, which should make it more gooder over all. I havent touched the software, but whatevs.

  • Auto leveling looking goooood

    DTeel08/03/2016 at 01:37 0 comments

    So Ive been working on that auto level thing, which turns out is pretty awesome because I can use V bits now, I can etch faster due to milling at a precise depth instead of milling at a range of depths due to the board flexed/uneven/whatevs. And the bits dont break like its going out of style.

    Heres pictures of board, and the unevenness I introduced to test the auto leveling. Its quite extreme and I dont forsee anything like this happening. I made it do 12 samples in the x axis and 12 in the y axis. I could have improved the results by increasing the sampling to 25, 20 (which will fit in the RAM just fine on the arduino, but its pushing it based on all my other globals and locals and other items pushed on the stack during its calling procedures, maybe I should make most of the locals static so I can get an accurate picture on compile since nothing is being called recursively?)

    Sorry the lighting sucks, but whatevs.

    As you can see, the bottom right hand corner where the change in surface depth was most extreme (change in depth versus change in lateral/horizantal direction) it didnt like so well, but as I said, I can increase the number of sample points to correct this. But with how extreme this example was, I shouldnt need to.

    Heres a time lapse video of it doing its thing, you can watch the Z axis coupling as a reference to see it adjust its height for the contours. It's a shitty video, for some reason my ipad wouldnt let me upload at Hi Def saying I had to be on wifi (which it was, its not a 4g or 3d ipad), but you can still see the auto level in action.

    Code wise it was pretty simple, I've done some interpolating in code in the past and I just applied that to this.

    For building the sample points, I just had 2 for loops going through the points and recording them

    void buildLevelTable(double maxDepth){
      if (maxDepth>5) maxDepth=5;//since we're using a uchar for height data, its limits are -5.1 to 5.
      for (int y=0;y<LEVELH;y++){
          for (int x=0;x<LEVELW;x++){
              for (double deep=fmax(-5,gTravelHeight);deep<=maxDepth;deep+=0.02){
                  if (!digitalRead(LEVELPIN) && !digitalRead(LEVELPIN) && !digitalRead(LEVELPIN)){

    And for the interpolation to get the z offset at the current X/Y

    double zOffset(){
    	double x=((double)gCurStepX)/80.0;
    	double y=((double)gCurStepY)/80.0;
    	double bw=gLevelWidth/(LEVELW-1);
    	double bh=gLevelHeight/(LEVELH-1);
    	int tablex=floor(x/bw);
    	int tabley=floor(y/bh);
    	if (tablex>=LEVELW-1 || tabley>=LEVELH-1) return gTravelHeight;
            if (tablex<0 || tabley<0) return -10;
    	double left=(gLevelTable[tablex][tabley+1]/25.0f-gLevelTable[tablex][tabley]/25.0f)/bh*y+gLevelTable[tablex][tabley]/25.0f;
    	double right=(gLevelTable[tablex+1][tabley+1]/25.0f-gLevelTable[tablex+1][tabley]/25.0f)/bh*y+gLevelTable[tablex+1][tabley]/25.0f;
    	return (right-left)/bw*x+left;

    Dont mind the poor code.

  • Auto leveling.

    DTeel07/31/2016 at 22:11 0 comments

    So, I had a free pin on the arduino, and I'd hate to see it go to waste, so its going to become the sense pin for auto leveling.

    I got a wire hooked up to ground, and the other wire hooked up to the free pin (D8). They both have aligator clips, so you clip one to the board, and one to the end mill, and then run the auto leveling routine.

    It probes the entire board (with a width and height you specify) at intervals you decide (so for my board, its 100mm x 70mm, and I have it probe 10 in X axis, and 7 in the Y axis) and gets the Z offset compared to home. It puts all that into a table and becomes accessible during x/y movements. Every step of the xy axis in my gotoXY routine it says "Hey, im at a new position, lets check to see what my new Z height needs to be to get that route depth i want" so it does a bunch of math and corrects the Z position to give you that cutting depth you want.

    Its a work in progress and I've gotten some nice test cuts, but Ive also found some bugs and need to decide how I want to actually have it implemented in code. right now the codes a mess, and very awkward. I have it implemented in my gotoXY routine, with a parameter asking if you want to make auto leveling corrections. I'm thinking I'll make a gotoXYAutoLevel routine that will do all this, and it will leave the gotoZ and gotoXY commands pure and free of this mess.

    or should it be gotoXYZAutoLevel? That'd probably be easier. I dont know. I'm going to find out.


  • Overview of what it is so far.

    DTeel07/31/2016 at 01:21 0 comments

    i made a lil video were i go through what i got so far and talk a lilttle about what i want to do in the future with it.

  • You always miss something.

    DTeel07/29/2016 at 06:14 0 comments

    So the design I posted a few days ago, was all kinds of wrong. Well, not all kinds, just one kind. I forgot to flip the image of the stepper driver when doing my design, so the pin locations were not correct. I would have had to of solder the headers into the bottom of the board, and then plugged them in upside down.

    Well, I didnt want to do that, so I redesigned it and in the process added a feature for a fan, or some other 12v <1A accessory you want.

    Then I milled out that new board, soldered everything into place and then tested it out. The x and y axis's worked just fine, but the Z was all dicked up. Wasnt doing nothing. Then I realized I shouldve tested that pin mapping to the arduino on a bread board before I milled that board. I was trying to use pin's A6 and A7 as digital output pins, but little did I know, you cant. You can only read from those pins.

    So to fix that and not have to etch a new board, I figured since there only input, i'll drill two new holes in those lines and put a jumper to 2 unused digital IO pins on the other side of the arduino (thank god I thought semi ahead and made traces from unused pins to drilled holes to easily fix problems like these). So I did that, and it works fine now.

    super awesome. I'll post pictures and shit once I get a new housing printed out for the new desing.

  • moarbrokebits2

    DTeel07/25/2016 at 01:17 0 comments

    Well it finished milling, and it turned out nice, and the bit is just fine. I even used the bit for drilling the holes (i then hand turned a bit into what would have been the larger holes for the headers) cuz I didnt feel like changing it out, and it worked great.

    I just need to clean it up a bit, and it'll be good to go for soldering tuesday when my new iron gets in.

  • Moar broke bits

    DTeel07/24/2016 at 23:25 0 comments

    Well, I redesigned the controller board so there is no need for any jumpers, and then I etched it out. It took 3 bits to finally get it done, and with the bit replacing it moved like .05mm to the left, and the drill points were a bit off and I said fuck it and threw it away.

    One of the reasons I found for the bit braking was, in my routines for milling the different objects, I would have it move the end mill to the desired location at fast slew speed until it was 0.1mm above the board, and then it would transition to the slower milling slew speed. Well, the board isnt exactly the flatest surface and it bows a bit in the middle, so the mill would slew super fast, and contact the board faster then it should have been, and it would break bits err now and then. So, to correct this, I changed the firmware to instead of traveling to a fixed point (0.1mm above board height) above the board, now it travels to 1/4 of the travel height (the height at which the dremel slews at fast speed around the board) and then transition to the slower mill speed. That did help quite a bit, but the 0.5mm with 5mm long point was just too weak and wore out quickly. If it was 0.5mm and only like 1mm long, it would be so much more durable I think, but its not. And I cant just trim it I dont think, or it would change the design of the bottom and not be quite as well for digging into the material vertically and produce more problems.

    So I spent a few more kozlowskis and got some nicer bits, and it seems to be working a billion times better. While I was waiting on those to come in the mail, I redesigned the controller board again to reduce the number of lines needed to be etched, making it quicker to etch, and reduce the chance of breaking these new bits.

    So with the first revision of the new board, I etched one out and did some testing with the power supply traces, and I ran about 3 constant amps from one end to the other for a few minutes to see if those traces were large enough to handle the current they'll be seeing, and they didnt even feel warm really after the end of it, so I'm sure it will suffice. I used a .7mm bit for that first board, and I'm using a 0.6mm bit for the board after this, so the traces will be even larger to provide a little more room for safety.

    The new board is currently etching right now, and I also decided to buy a nice soldering iron and one with a pencil tip so make the soldering of lots of pins in small spaces easier/nicer. Before, I was using a 5 year old radio shack soldering iron with a huge tip I filed down a bit to help with the small pins, but it still sucked.

    So thats what I have going on in my life right now. I'll solder up this new board tuesday when I get the soldering iron in the mail (god I love amazon prime) and redesign the enclosure to make it more accommodating to the new board and the connections for the key pad.

    I'm still debating if I want to make an acrylic base for this, which would be really nice, but would increase the cost of the project quite a bit from what it already is. The wood is warped just a tad bit, and I would really like to replace it, but #yototheloamiriteboiz.

View all 22 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates