Building a CNC machine

SketchUp 3D drawing of the CNC machine model provided by

Most computer aided manufacturing systems have a common structure: a multiple axis control system. This allow for accessing a specific point in space to either remove material (laser cutter, milling machine, CNC router) or add material (3D printing). The number of axes depends on the type of machine and the flexibility needed. It can vary from two axes for a laser or plasma cutters up to five axes for the most complex milling machines. The most common tools can be controlled in three directions for the tool to reach any point in the 3D space.

After a first taste of computer aided manufacturing using a 3D printer, I realized that the mechanical part of such a system remains relatively simple. For each direction, one motor provides the motion of the tool. The most common system involves a stepper motor combined with a mechanism that converts the rotation of the motor into a translation. This can be achieved by belts or lead screws. Added to that, one or several rails are used to limit the friction forces during the motion of the tool.

Building the CNC structure

There are plenty of models available online for CNC machines. For this build, I followed instructions provided on by oomlout. The machine proposed here has the advantage of being relatively affordable and providing generous dimensions for larger projects.

The structure of the CNC is built with 1/2 plywood and made using a limited number of tools. At the moment of the build, I had access to a circular saw, a hand saw, a coping saw, a chisel and a drill. It was quite challenging but the result turned out well.

Compared to the original design, I upgraded the belts transmission with 8mm lead screws in all three directions. As the gantry providing the x-axis motion was not rigid enough to be controlled with enough precision with only one motor on one side, I duplicated the motor/lead screw system on both sides.

The stepper motors are Nema 23  (2.5A 1.3 N.m) which are powerful enough to provide enough torque while keeping a fast translation. All motors are controlled by an Arduino UNO R3 combined with a CNC shield and four DRV8825 stepper motor driver. The Aduino is powered with a 12V 30A power supply.

Testing the control board and the stepper motors

The CNC shield is a simple electronic board that reorganize the Arduino connections to simplify the connection for CNC applications.

The stepper motors are bipolar motors and have two independent windings, one winding per stator phase.

Bipolar stepper motor

A bipolar stepper motor has easy wiring arrangement but its operation is a little complex. In order to drive a bipolar stepper, we need a driver since in order to reverse the polarity of stator poles, the current needs to be reversed. That is the role of the DRV8825 Stepper Motor Driver which can be connected to the Adruino controller via a CNC shield.

The Nema stepper motors came with no plug. In order to connect them to the Arduino controller, it is necessary to install a 4 pins female Dupont connector. When connecting a stepper motor, it is important to respect the coil pairs and their polarity. If this is not provided by the manufacturer, it is easy to determine which wires belong to the same coil with a multimeter by checking which pair display a finite resistance. For the polarity, an in situ test is necessary. If the polarity is wrong, the motor will turn in the wrong direction. Changing the polarity of one of the coils is enough to get the rotation back in the right direction.

Installing the Grbl software in the Arduino

But before plugging the motors, the first step of the electronic installation consists of plugging the shield into an Arduino board and loading the communication program allowing the communication between a computer and the stepper motors. One of the most common of such programs is called Grbl. Grbl is defined as “a free, open source, high performance software developed for controlling the motion of machines that move, that make things, or that make things move” (Grbl wiki). It can run on a straight Arduino. It is used in most open source 3D printers, laser cutters and CNC machines. For more information, check out the Grbl wiki which is a great resource.

Here I used GrBl version 0.9. This version is not officially supported with the older Arduino v3.0 since on the later version of the Arduino controller some pins have been swapped for functionality reasons. Indeed, Grbl v0.9 is supporting variable spindle using the Pulse Width Modulation (PWM) output. Since PWM was available on the pin previously used by the Z-limit, these two pins have been inverted (More info about this here). This does not interfere with the main functionalities of the Arduino controller and since I am not planning to control a variable spindle nor using limit switches the first time, this has not proven to be an issue so far.

To install Grbl on my Arduino board, I did the following:

  • Downloaded and installed the Arduino IDE which can be found here. I used the version 1.8.2.
  • Downloaded the Grbl code from Grbl repository.
  • Loaded Grbl into the Arduino IDE as a Library (From the menu “Sketch” > “Include Library” > “Add .zip Library),
  • Selected the “Grbl” folder inside the “grbl-master” folder, which only contains the source files and an example directory. (If you accidentally selected the .zip file or the wrong folder, you will need to navigate to your Arduino library, delete the mistake, and re-do this step.)
  • Opened the “GrblUpload” Arduino from the menu “File” > “Examples” > “grbl” > “GrblUpload”,
  • Connected Arduino Uno to my computer with a USB cable.
  • Made sure the board is set to the Arduino Uno in the “Tool” > Board” menu
  • Checked that the serial port is selected correctly in “Tool” > “Serial Port”, in my case COM5.
  • Compiled and uploaded GRBL to my Arduino from the menu “Sketch” > “Upload”

Et voila! GRBL should compile and flash to your Arduino!

Note: flashing with a programmer also works by using the “Sketch” > “Upload Using Programmer” menu command.

Now that once the code is loaded into the Arduino, we need a way to communicate with the controller. To do so, I am using Universal G-code sender version 1.0.9 that can be found here. With this program, one can send direct instructions to control the CNC or send a complete file containing G-code instructions.

I used Universal G-code Sender to make sure Grbl is running correctly. To do so,  I set the correct communication port (COM5) and bandwith (115200 for Grbl v0.9) and made sure I got the message showing that the communication worked properly.

Setting the reference voltage of the stepper drivers

One of the important steps to set up an Arduino controller for a CNC is to adjust the current driving the stepper motors. One common approach is to increase progressively the current with the potentiometer on the driver board until the motor moves sufficiently. Though it works and limits the risk of overheating or miss steps the stepper motors are likely not setup in an optimal way.

Another method is to measure the reference voltage of the driver circuit. The driver circuit adjusts automatically the motor current based on voltage at the reference input.

For a DRV8825 driver, Pololu describes on their website, that the relationship between the stepper motor current and reference voltage is given by the following equation:

Imot = 2 * Uref

That means, if the DRV8825 needs to drive a stepper motor with 1.5A the reference voltage has to be adjusted to 0.75V. Measuring the reference voltage on the DRV8825 can be done at the center of the potentiometer on the driver.

The adjustment of the stepper motor current will be done in three steps:

  1. Identify the maximum current of your stepper motor from the datasheet
  2. measure the reference voltage at the center tap and tune it with turning the poti, note: the motor won’t be connected yet!
  3. connect the stepper motor with the controller board and check function by moving the axis

Check out the following video from Pololu for more explanations.


Plugging the motors and testing and calibration

The installation is almost done. Now its is time to plug the motors and run a final test of the electronics. It is wise to test the stepper individually to avoid damaging them all in case of problem. Without the power connected, I connected the stepper motor to the first socket to control. The motor has to be connected since the drivers are designed to ramp up the current until it reaches the current needed for the motor to run. Without a stepper motor to consume the current, the driver can overheat and be damaged so make sure a motor is connected to the driver you want to test.

Next, I connected the external power to the shield, making sure the polarity was respected. Finally, I tested the connected motor by sending a G-code command to the controller. With the Arduino connect to my computer with the USB cable, I opened a connection with Universal G-code Sender and sent a simple command like “G1 X1”. You can also use the commands in the Machine control tab. The stepper motor should move. If everything works properly, disconnect the power and repeat the process for each axis. I used the same driver for all axes to avoid damaging multiple stepper in case of error. Once every axis has been tested, I installed all the motors on the CNC and connected everything for the final setup.





  • Mini circular saw
  • Drill
  • Hand saw
  • Chisel
  • Solder Iron
  • Multimeter
  • Screwdriver


  • Plywood: Home depot
  • Steel bars: Home depot
  • Aluminum square tubes: Home depot
  • Bearings: 16x Skateboard bearings ABEC 9,, $8.45
  • Wood screws: Home depot
  • Bolts, washers and nuts: various sizes, Local hardware store, ~$30
  • Arduino CNC kit: Zyltech,, $83.98 (UNO R3 Arduino Board, CNC shield, 3x Nema 23 Stepper Motors,  12V 30A power supply, 3x Mechanical endstop switch, 4x DRV8825 stepper motor driver, Gold plated/shielded USB cable)
  • Extra Nema 23 stepper motor: Zyltech,, $17.99
  • 4 pins Dupont connectors (x4): Ebay, 2.09$ (price for 100pcs in 2 parts: housing and connector)
  • 300mm Lead screw: 8mm + Copper Nut + Coupler + 2x Pillow Bearing Block,, $12.98
  • 800mm Lead screws: 8mm + Copper Nut + Coupler + 2x Mounted ball bearing,, $39.96

17 thoughts on “Building a CNC machine

Leave a Reply

Your email address will not be published. Required fields are marked *