Skip to main content
I took on the challenge of designing and building a 3D-printed CORE XY CNC from scratch.

There are three materials I want to be able to cut on this CNC build, PCBs, Acrylic / other Plastics, and wood, any other material that I end up being able to mill will be a welcomed bonus.

Requirement: My top priority for this CNC build is prototyping PCBs and milling acrylic, both operations require a positionally accurate machine to mill parts reliably, so the chief requirement is Accuracy.

Constraint: In addition to not having a large budget, I live in Lagos Nigeria, and for someone like me, shipping makes up about 40% of the cost of owning any tool, so the first constraint for this build is COST, the cost for the tool, and cost to ship it. As a rule, I generally avoid shipping large and heavy items, I plan on building a reasonably large CNC, and without that rule in place, this build will get expensive very quickly.

My Primary tool for this build is a 3D printer, so no custom metal parts, and only the basic woodworking tools.

Linear Motion: Deciding what linear motion system the CNC will be built around was the first and the easiest design decision I made, I already knew I could not afford to ship large linear motion parts like optical guide rails, aluminium profiles, or linear rails, the only practical option was to design my own.

I also knew the CNC had to be belt driven because the affordable alternative is trapezoidal lead screws, which, in addition to being large motion parts, are no good when chasing accuracy due to the brass nuts' play and the consequent backlash that follows.

Why a CORE XY System?

illustration of an Core XY belt system

Core XY and Accuracy

In a core XY motion system, the XY axis is controlled by two identical timing belts with a somewhat convoluted path, the belts are moved by two motors installed in a remote location on the motion system, these motors don't identify as X & Y, they are designated as A & B or 1 & 2, the reason for this is movement in either the X or Y axis is achieved by moving both motors in a specific combination, so the motors do not control any of the axes independently, whenever the motors do move independently, the resulting motion is diagonal along both X and Y.

All the advantages of a core XY system stem from having the motors controlling the axis as fixed parts of the overall motion system, compared to cartesian motion systems, the motors are not rigidly coupled to moving masses, which allows benefits such as positional repeatability even at high speeds and a higher acceleration capacity, we don't care about high acceleration on a CNC, but the positional repeatability is very valuable.

Core XY on a CNC

There are certain characteristics of the core XY kinematics that are not ideal for a CNC build and all but one of them can be corrected for in the design and in the choice of parts.

  1. Whenever the gantry in a core XY system moves diagonally (45 degrees), it is doing so using just one motor, which means that during diagonal moves, the whole weight of the gantry will have to be moved by just one motor, which can be a problem as CNC gantries are typically quite heavy.
  2. The second characteristic of a core XY system that is not ideal for a CNC build is the long belt path, this increases the possibility of belt stretch, even more so in a large-format CNC build. To mitigate this issue, I chose to use a 15mm GT2 timing belt with a steel core, this is significantly tougher than the 6mm belts found on most 3D printers.

There are two solutions to the first problem:

  1. The first solution is pretty obvious, simply choose sufficiently powerful A & B motors, if each motor is spec’d to independently handle the gantry weight, then diagonal moves will not be an issue.
  2. The second option is to use 4 motors instead of the traditional two, so 2 A motors and 2 B motors, this approach is demonstrated beautifully by Vez3D the creator of the VZBot 3d printers.

For cost reasons, I went with option A, and it will not really make sense to use Nema 17 motors given the intended size of this CNC build, even the more powerful ones will probably struggle to move the gantry, although there are geared versions that should work fine at the cost of speed of course. I chose Nema 23 x 57mm motors for this build, per my estimation, the motor will be able to handle up to 8kg with a 36 teeth pulley, which is a good starting point for this build, I also designed the motor mounts to accommodate beefier Nema 23 motors without significant changes to the overall CNC design.

Motor and 3D Housing

The third characteristic of a core XY system that we cannot correct for in a CNC build is the fact that we have to use a timing belt, to begin with, there’s a reason CNC machines are typically built with a screw-type actuator (lead screws, ball screws…), a screw type actuator makes the CNC’s motion more rigid in addition to enabling more torque capacity due to the speed reduction between the motor and the screw, we would ideally want as much rigidity and torque as we can get for a CNC build, but for the materials, I am targeting, a belt driven system is more than adequate.

Core XY and Cost Saving

It may not be immediately obvious, but a core XY system is a great choice to save on a CNC build, if I were to build a CNC with the proposed size using a cartesian motion system, I would need to use at least 4 stepper motors, a core XY system only requires 3 motors, the A and B motors, and one Z axis motor, one less stepper may not seem like a lot, but its what I like to call a refractive cost saving, lower motor count reduces stepper driver cost, wiring cost, and wiring complexity, it also gives you more controller options as there is hardly a development board that cannot at least control 3 steppers, the savings even shows up in the shipping cost & reduced power requirements.

The Motion System

The first parts I designed are the rollers, the rollers are designed as a pair, one has 2 vertical bearings and the other has horizontal bearings, the vertical roller constrains the pipe vertically, and the horizontal roller constrains the pipe horizontally, with two pairs of each the pipe is fully constrained and will only move in the desired linear direction.

The Motion System - bearings holding the pipe horizontally and vertically

The rollers also feature a tensioning screw so I can adjust for the imperfections in the 3D printing and in the assembly, individually on each roller.

tensioning screw in action

The tensioning system depicted here is actually incomplete, if you think about it, this is a rigid tension, which is only good under the assumption that the galvanized pipe is completely uniform throughout its length, and that the motion system will run perfectly straight and true, this is, however, an unrealistic assumption, and so the rollers are missing one essential component, a spring, the spring changes the rigid tension to a flexible one, this way the rollers can deform slightly to accommodate the variations in size and alignment across the length of the pipe, this should also help with dust and chips that may settle on the pipes during operation.

Unfortunately, I did not think of this during the initial design of the CNC, I am seriously kicking myself for this oversight, but, I already ordered the appropriate springs and I’ll be installing them later on, I should be doing this over on my youtube channel once the springs arrive, it should be interesting to compare the CNC’s motion with and without the springs installed.

Construction of the Motion System

The CNC requires 24 of these rollers, 18 for the left and right Y-axis carriage and 8 for the X-axis carriage.

The Belt Path

I was wondering why there were not more CNC builds featuring core XY kinematics, I stopped wondering when it came time to figure out the belt path. Because of the intricate belt path in a core XY system, it's not really something you can put aside or easily install after the fact, compared to a cartesian system, the belt path is elemental to the CNC design, so its important to tackle it early on, it in fact heavily influenced the roller design I discussed previously.

Animation of belt path

Assembling Sub-Assemblies

Assembling The CNC

Controlling the CNC

With so many options for controlling CNCs and 3D printers, I have to admit I was quite unsure of how best to control the CNC, so, instead of doing extensive research and then designing a controller that was expressly suited to the CNC, I decided to “Wing It”.

Unexpected challenges are bound to come up when controlling a new machine for the first time, and I knew I could not possibly anticipate them all, but I had just enough spares, and just enough knowledge on the topic to power through the challenges as they came up, and there were a few.

For Firmware, I chose Marlin, mainly because I am familiar with it, I knew it would support the CNC because it runs my 3D printer (sapphire plus) which is also a core XY system and is largely responsible for me considering a core XY CNC build.

For Controller, I chose to use an ESP32 board, it seemed the best of my available options, and it had just enough IO to control everything I needed to control on the CNC.


I hand-soldered a breakout board to facilitate the required connection, and that turned out well enough and I was able to compile marlin on the board.

I also needed a way to interface with the marlin firmware, 3D printers will typically have a board with an LCD and a rotary encoder, I did not get such a board on account of me Winging It, so I had to make do with what I had on hand, and it turned out what I had was actually kind of perfect for the CNC.

For the screen, I had an SSD1306 0.96inch OLED display, which after some googling I found out that someone already did the work to make the display supported by marlin.

For the encoder, I developed a magnetic rotary encoding method a few years back, one that I’ve since integrated into many of my projects, like the Ahmsville Dial, and the Pick N Place Wheel, so I figured why not the Krivee CNC as well.

The magnetic rotary encoder generates analog and digital signals, you can learn more about it here, the digital signals generated by the encoder are a bit different from what marlin expects, but it’s not impossible to adapt using the right pair from the 4 signals generated.

Signals from sensors

Bringing Up The CNC

Test Sketches

Dust collector

Motion Problem

Developing a CNC Probe

Marlin has a few bed-levelling features that work great on a 3d printer, bed levelling allows you to get a mesh of the bed, so the machine can adjust for the variation in flatness on the bed surface. On a CNC, the typical way to get such a mesh (height map) of the workpiece is to use the endmill and the workpiece itself as a switch, so the endmill could act as the switch common (C) or the normally open or normally closed (NO / NC) depending on how the signal is processed, the workpiece acts as the second part of the switch so that when the endmill touches the workpiece, the switch” is closed or open and the CNC can record the position of the workpiece on the z-axis, repeating the process all over the work surface can then be used to get a height map of the work surface.

This method is accurate but it only works if the workpiece has a conductive surface like PCBs and some metals. I plan on milling PCBs on the CNC but not all the time, I expect I’ll be milling plastic and wood most of the time, and I don't want to have to run a surfacing operation on everything I machine, so I decided to design a probe specifically suited for CNC machines, one that allows me to get a height map for any material, conductive or not.

The probe will work with marlin’s auto bed levelling feature, so it operates with the same principles as 3d printer probes.

Offset Probing “Bad”

Offset probing is when you probe a surface with a probe that's offset from the 3d printer Nozzle or CNC Endmill on the X, Y, and Z axis. The Z offset is totally fine, it's the X and Y offset that’s bad.

Say there is a defect on the X or Y axis rails, that causes a dip or a hump at some point on the axis.

Offset - defect on the X or Y axis rails, that causes a dip or a hump

If you probe this point with a probe that's offset on the X and Y axis, you’ll be recording a Z offset value that will change when the nozzle or endmill moves to that point, due to the dip or hump on the rails.

Offset - Probe at the dip or a hump

In an aligned probe, the hump or dip will always be added to the calculated z-offset because the probe is in the same X, Y position as the tip of the endmill.

Aligned - Probe at the dip or a hump

This defect is exaggerated in the pictures, in reality, the dip or hump will be quite small and is often negligible on a 3d printer because the extruded molten plastic can expand and contract to accommodate the slight variation, this variation will however show up on a CNC, especially when working on something sensitive like a PCB, so it's very important to probe with something that's aligned with the endmill on the XY plane.

Probe Design

There are two ways to approach designing a probe for a CNC, the first way is to design a probe that attaches to the spindle collet, this option allows you to have a constant probe offset because it references a fixed point on the CNC’s Z axis.

Probe design - referenced to spindle collete / shaft

The second option is to design a probe that references the tip of the endmill, you don't get a constant probe offset using this approach, but you get a constant distance between the endmill tip and the work surface.

Probe Design - referenced endmill I prefer the second approach because I won't have to remove the endmill whenever I want to probe a workpiece, also the constant endmill tip-to-probe offset allows me to quickly determine the Z height where the endmill just touches the work surface without having to plunge the endmill into the workpiece.

CNC Probe Design

Successful Cuts

Post Build Changes

This has been a very successful CNC build, I‘ve been able to mill some random objects in wood and in plastic, and I also completed the interactive air quality map build using the CNC, the only holdout, for now, is PCB milling which I will get to really soon. Everything did not go according to plan though, I got some things right and I got some things wrong.

I made a list of all the things I wanted to change and make better as I was putting the CNC together.

Most of these changes have already been applied to the final design, there are a few more things I need to get to like installing springs to the rollers and designing an official controller board for the CNC, I also need to update the cable chain on my CNC, because my current setup is just sad.

Old Cable Chain

Old Cable Chain

New Cable Chain

New Cable Chain

Old Motor mount

Old Motor mount

New Motor mount (NEMA 23, 57 - 80mm support)

New Motor mount

Old Dust Collector Nozzle

Old Dust Collector Nozzle

New Dust Collector Nozzle

New Dust Collector Nozzle - Design

New Dust Collector Nozzle - Printed

New MR125zz ball bearings (2 sizes up from the original 105zz)

New MR125zz ball bearings design

Building A Krivee CNC

The Krivee CNC is open source and you’ll find every related file and all the information you need to build one for yourself on the GitHub repository, there’s also a discord server (Krivee CNC), and you can join up for updated information on the CNC, and to share any ideas you might have, I’ll also be answering questions relating to the CNC build over there, also consider subscribing to my youtube channel to see future updates to the CNC.

CNC Specifications

Size (scalable)

Work area => 640 x 490 x 70mm (X, Y, Z)

CNC size => 1002.59 x 1064.60 x 389.60mm


PLA filament => 2kg

ABS or PETG filament => 2kg

I am a passionate Hardware Engineer, with interests in Embedded systems and Robotics. I enjoy learning new skills and challenging myself with finding creative technological solutions.
DesignSpark Electrical Logolinkedin