Garden Shed CNC

Making a CNC machine as cheaply as I can with things I have in my shed

Similar projects worth following
I have a shed that houses my soldering iron, drill and drill stand, Dremel and box of hand tools. I like making things in there a lot, but it would be really nice to have more tools to speed things up. Unfortunately I can't really justify the expense of buying big machines.

I saw the excellent Makesmith CNC project ( here on and thought wow, I have some of those servos and they are filthy cheap! If I can get a few other parts I can put something like that together without having to invest in stepper motors and motor controller boards. I've been hunting down parts and putting things together ever since.

I don't really know how to make or use this sort of machine, so I'm trying to document any mistakes and revelations I have along the way.

First Tests:

Its pretty noisy, I think I may have to build a box to muffle the sound or my neighbors may ask me to stop!

Here are the first test pieces (sandpaper is to stop them moving around):

For the first one (on the left) the Z axis broke (screw fell out) and stopped going up and down. I fixed it for the second one, but realised I had a software issue putting the shape in the wrong place. The third one worked fine, so I tried to cut out a more complex shape next (the skull head of a monster from a computer game I'm working on). For the first cut I ran out of wood, but got the size right for the second.

By this point the end mill was starting to burn the wood a bit, and the Z axis was losing its position a little. Since then I've been working on the code (which is available on GitHub) and have started to get some really exciting results:

Tools I have used so far:

  • Drill and cheap drill stand
  • Dremel
  • wood saw
  • coping saw
  • a little 2.5mm tap

Drilling accurate holes has definitely been one of the hardest things with this project. I had to remake several parts when everything didn't line up quite right. When I tried to fit the bearings onto the rod after drilling a slightly wonky hole (sawdust under the part) it tore the balls out of two of the linear bearings.

Cutting accurate lines was also something I couldn't do, so everything was put together by eye. A drill press and a bandsaw would be really nice things to have! At least I can now cut and drill accurately (though very slowly) on my CNC machine.

The tap (like the Dremel) is one of those tools I never realised I needed until I had it, and now I find all sorts of ways to make use of it. It is a wondrous thing to own and everyone should own at least one.

Things I had lying around that have been used:

  • Plywood and other wood of various shapes, sizes and thickness.
  • My trusty Dremel.
  • A slightly rusty Arduino Leonardo that still works!
  • wire and connectors and buttons
  • woodscrews and machine screws

I'm using every single pin on the Arduino. At one point I thought I was going to have to buy a Mega, but then I realised you can use the analog pins as digital ones.

Things I have had to buy (so far):

  • 6x servos (I had a few and only needed 3 but wanted lots of spares in case I broke some) £10.25
  • pack of 10 thrust bearings £11.98
  • pack of 12 linear bearings £6.17
  • second pack of 12 linear bearings after I broke two of the originals (oops!) £6.17
  • 6x 400mm steel rails £22.74
  • 5x M5 400mm threaded rod (two spares woo!) £6.35
  • pack of 10 roller lever arm microswitches £2.48
  • bag of M5 square nuts £1.75
  • bag of M5 four prong T nuts £2.35
  • pack of 5 2mm ball nose end mills £13.49

Total so far (including postage): £83.73

Not too bad, considering a 3D printer comes in at around £400 minimum last time I looked. Everything was from ebay. I nearly abandoned the idea when I realised how expensive metal rails are. I did not expect a quarter of the cost of the project to be on those.


Since the limit switches came in packs of 10 I decided to keep things simple and try and use three of them to keep track of the position of each axis. I didn't want to build some sort of optical/magnet based thing if I didn't have to. I cut down a T nut into a square shape and fitted the switch so it would click in and out

The servo attaches to the threaded rod with a bit of aluminium tube with little home made set screws fitted to it. They fall out due to the vibration of course, so I probably need to superglue them in or something.

One of the axes wasn't counting properly so I changed the profile a bit which was a big improvement. I should probably do the other two. I also put tape on the switch to stop it wiggling on the nail mounts.


On the Arduino end I decided to keep things as simple as possible. You send a G Code command over the serial port and it executes it and sends back confirmation. I had a bit of a look for libraries for interpreting G Code and calculating lines and curves, but...

Read more »

  • Success!

    penleeki10/12/2015 at 20:39 0 comments

    I finally got the drifting problems sorted out! I added a lot of data logging to the code and spotted the switch bouncing when I ran it drawing circles over and over.

    Its not terribly easy to read as I needed the data compact so I could scan through large amounts of it. What is happening though is that each step is taking anywhere from 40-130ms to complete, but then there is a point where the switch fires at 103ms 104ms 105ms after receiving an instruction to move. This means the switch is closing, but then opening and closing again within 2ms.

    I added some simple code to reject any switch changes that happen too quickly to the Arduino Sketch:

        // De bouncing
    lastclick_millis[axis] = millis();
    Since the normal switch changes were happening at around 40ms and up, and the bounces were all 2ms and less I figured rejecting anything below 20ms was a fairly safe boundary.

    Then I set my H shape test cutting, and it worked perfectly! Here it is after a quick light sand and a coat of mineral oil, with a 9v battery for scale:

    Now on to getting the auto start/stop working and cutting more things!

  • The Debugging Adventures Continue

    penleeki09/22/2015 at 22:27 0 comments

    It turns out that leaving debugging code in your project can sometimes be a really great thing. I was going to video the axis mechanism and see if I could spot anything odd happening that might explain the drift, when suddenly during moving it into position I got a couple of these though the serial port:

    [rogue axis 1 ]
    This was the warning I put in to check if the servo was overshooting at all (axis 1 is the X axis). It turns out it does overshoot, and my limited earlier tests didn't pick it up because it doesn't happen that often.

    I got all excited and put code into the Arduino sketch to track the movement past when it is supposed to be moving, and adjust the internally recorded position accordingly. Then I tried to cut another shape, and there was still drift.

    Once I got over the disappointment I decided to record the axis anyway to see what happens in more detail when it drifts. I marked the side of the linkage with a black dot so that I could easily spot when it went out of alignment. Then I set the video recorder going and had it move in tiny circles (2.4mm or 2 complete turns in diameter) over and over again until I spotted the black dot lose alignment. Then I stepped through the frames trying to count along the steps taken and see what happened:

    There is this interesting little bit where it backtracks as if it thinks it has overshot by one (when it hasn't). The problem is though that the count on the left and the count on the right should match up and they don't. Even if the extra tick from thinking it has overshot is added it ends up one short. Without it ends up two short (which is the actual physical amount it ends up off by).

    The debugging trace for the red bit looks normal, but the blue bit looks like this:

    --curved line---
    from x: -24 y: 0 z: 0
    to x: 0 y: 0 z: 0
    center x: -12 y: 0 z: 0
    steps 34
    c1-132 c0 -100 c0 -117 c1 -173 c1 -129 c0 -98 c0 -113 c0 -155 c1 -152 c1 -112 
    c0 -75 c1 -143 c0 -62 c0 -120 c1 -75 c0 -93 c0 -83 c1 -107 c1 -60 c1 -103 
    c1 -111 c1 -90 c1 -124 
    c0[rogue axis 1 ] -82 
    c1[rogue axis 1 ]-171 
    c0 -167 c0 -167 c0 -185 c0 -139 c0 -128 c1 -131 c0 -124 c0 -101 c1 -107
    ENDED AT: 0 y: 0 z: 0
    Which is interesting because there are two points where it thought that the servo had overshot (the ones that say "[rogue axis 1]"). I only see one spot where it backtracks on the video though. If the backtrack was the first point we see in the data, the second would be during the backtrack which would put the count off by two. If however the first point it overshoots doesn't backtrack and the second does, that makes the count correct, so is the only theory that makes sense to me unless there is a software bug somewhere.

    What is clear from all this though is that the switch is detecting extra presses where none are happening. I think my next step is going to be programming in a way to measure more precisely the interval between switch clicks on a specific axis and when they happen related to servo commands so I can get a better idea exactly what is happening.

  • More drift debugging

    penleeki09/20/2015 at 11:09 0 comments

    I had an idea as to why the X axis might be drifting. Because it is moving faster than the other two axes, I thought that if the code was operating slowly enough it might be clicking the switch in and back out before I could check for a change of state. Then if calculating the curve was taking longer than a straight line that would explain the drift getting worse during curves.

    curve calculation: 0ms --- operation 117ms
    curve calculation: 1ms  --- operation 149ms
    straight line calculation: 1ms ---- operation 151ms
    straight line calculation: 0ms ---- operation 178ms
    Unfortunately the data doesn't back that lovely elegant theory up at all. The time it takes to move 0.1mm and click the switch is 117ms and above, and the time it takes my completely unoptimized code to do all the calculations in between is somewhere between 0ms and 1ms. That is nowhere near enough time for an extra click to slip through. Foiled by the marvels of modern microcontrollers!

    I also added code to the Arduino Sketch to check if the switch was being clicked whilst the servo was supposed to be turned off, in case the motor wasn't stopping right away when it was told to, but got no results.

    Back to deep thought on the matter. At least I'm finding lots of things that aren't wrong with my project!

  • Drift debugging

    penleeki09/19/2015 at 21:59 0 comments

    I've been trying to figure out why the X axis drifts over time, and its a tricky problem. To try and understand what is going on I added some data logging code to the Arduino sketch, and plotted out how many cycles the code waits for each axis to step forward one place (0.1mm), as it moves back and forth from X0 to X10 a few times. The results have been a bit confusing. Here is the X axis:

    Looks surprisingly regular. I'd expect to see spikes of double time if it was missing a count, or spikes down to a very low number if the switch was bouncing or something. The servo takes a bit longer to do the first step after you send it a command, so I guess there is a little delay between turning it on and the motor getting up to speed.

    In comparison the Y axis (which keeps position perfectly) is way more messy.

    It is running slower than the X axis, which explains why the servo sounds different. I'm guessing all the parts don't line up quite as perfectly on this axis so it has to work a bit harder. There are also spikes that look like it occasionally loses a count, or gets stuck. This axis stays in perfect alignment so maybe it is sticking briefly for some reason.

    The Z axis also looks bad:

    When lowering the cutter (the red and purple lines) the switch seems to occasionally count twice very quickly, and when raising it (green and blue) it occasionally sticks or misses a count like the Y axis does. Drift on this axis is less critical because typically there is a lot less up/down movement when cutting stuff, so there isn't time for it to add up to disastrous levels. I should probably de-bounce this switch and then test for drift though.

    To make sure I hadn't made a mistake with the data I recorded some more X axis:

    Yep, still looks pretty good.

    I also did some more test cutting and the X axis seems to lose tracking faster if I am cutting circles. Clearly something more complex is going on here that a dodgy switch, so I think I'll have to give it some more thought before I try anything else.

  • Source code update

    penleeki09/17/2015 at 21:47 0 comments

    I've fixed some issues with the source code relating to the problems from my last tests. To see if there was any improvement I threw the Fusion 360 G-Code on there and this happened:

    Complex shape cutting success! On the third pass down into the wood I noticed the Y axis had drifted by maybe half a millimeter though, so I stopped it there. This has happened on some of the other tests too, but the other two axes seem to be perfect. I'm guessing this must be some sort of mechanical issue, so I'll need to try and figure out what is happening there.

    The Arduino is also stopping to have a little think in between commands also, which is a problem when the program generates lots of little curves like on this model. There is probably a little optimisation to be done there.

    Super happy to be finally cutting out exciting things though, I'm starting to feel very close to having an actual useful machine!

  • Testing

    penleeki09/16/2015 at 13:39 0 comments

    I seem to have some small issues with reliability at the moment that I am trying to sort out. I cut a little scale on a piece of scrap to check that the proportions are correct on my axes, which came out perfectly:

    But the rest of my testing was a bit hit and miss:

    I initially tried to feed it some G-Code generated from Fusion 360 (top right) but it got a bit confused on one of the curves and started wandering off.

    I then did a few curve tests feeding instructions one at a time(top left), which seemed to work fine, so I then decided to test the repeatability by cutting the shape on the bottom left all the way through in 1mm increments. I got 7mm in when suddenly it started to go off script and cut diagonally into the material. At that point I shut it down.

    I think I'm going to need better methods to debug what is happening in the Arduino when something weird happens. I'm also going to check my parsing code with a wider range of data to see what happened with the Fusion 360 G-Code.

  • Source code is up on GitHub

    penleeki09/13/2015 at 16:03 0 comments

    I finally got the curve calculating code working on the machine, so everything is now up on GitHub!

    I got the straight line code (G-Code command 1) working quite quickly, but the curve code (G-Code commands 2 and 3) took quite a while to get sorted. I started off with a little Flash prototype as that was quickest and simplest to debug:

    Then converted it into C, and tested it with a little console test program. This had quite a few problems I needed to fix before it would work, as my C is rather rusty:

    And then duck taped a felt tip pen to the CNC machine for a quick test on the hardware:

    Success! Can't wait to try it on some wood now! For the moment it only works on the XY axis, but the vast majority of curves would be on that plane anyway, so I'm not super keen to add support for the other axes just yet.

    I would probably advise against trying to use the code as is since I wrote it for my specific machine and don't really want to develop it further than that (that's not really the fun bit for me). It is also still a work in progress and largely untested. It may come in handy to pick through for anyone else building something similar though, as I couldn't find many resources when I was writing it. The curves and lines and servo switching all took a fair amount of hunting around for ideas and trying things, since I wanted to do it without storing huge amounts of data in the Arduino memory.

    The repository also includes my Unity scripts for generating G-Code and transmitting it to the Arduino:

    These are very early versions and pretty rough around the edges but I plan to develop them a bit more to be more robust and useful as more than just testing tools.

    I think before that though I need to make sure the hardware is reliable, and cut some more stuff to get more familiar with how to use the machine best.

  • Heat is the enemy! (also vice)

    penleeki09/12/2015 at 19:58 0 comments

    I've been doing some reading up on how to CNC, and I think I've figured out why the end mill from my first tests went blunt. I was worried about breaking the end mill or the CNC machine by running the Dremel too slow so I had it on max speed. It turns out though that the Dremel runs very fast for a typical CNC machine, and when you spin the end mill too fast it heats up more as it cuts. When it heats up too much the metal gets buggered up and goes blunt very fast. As a result for future tests I plan to run the Dremel on the slowest setting, and program in frequent breaks to give the end mill a break in which to cool down.

    I also made a vice platform to hold the wood more securely as I cut. I started out making a copy of the existing plywood platform, and cutting bits off and screwing bits on:

    Then I made a sliding jaw that is held in place by the slot. it has a bit of metal ruler at the bottom as I wasn't sure I'd have enough clearance for a wooden piece.

    Then I put the two together and added a bit of threaded rod, and fitted it onto the rails:

    The threaded rod is short because a long one would interfere with the bed moving back and forth. If I need to cut something small though I can just put a bit of scrap wood between the threaded rod and the jaw. I also cut a bevel into the inner side of the jaws using the CNC machine, which I managed to do without overheating the router bit.

    I also made a little knob for the threaded rod with my drill and some scrap aluminium tapped for a screw:

    It holds whatever I put in there nice and securely with no wiggle in any direction, success!

View all 8 project logs

Enjoy this project?



Saabman wrote 06/18/2018 at 22:43 point

that’s great.  I love projects built out of junk - they don’t always work the best but they get the job done. 

  Are you sure? yes | no

steve_cook wrote 12/14/2015 at 22:34 point

The initial cut was particularly noisy because you tried to do it in one go, three or four steps would be quieter and put less of a strain on your motor etc.

  Are you sure? yes | no

penleeki wrote 12/14/2015 at 22:56 point

This is true! I'm finding through trial and error that the shallower the cuts are the better for many reasons. Unfortunately because my machine is so slow compared to a stepper motor one I can't drop below a certain point or the cutting time gets ridiculous.

Even shallow though its still noisy enough that I'm glad its winter and the neighbours are all indoors behind double glazed windows :)

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

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