This page is intended to help people who wish to build / operate a 3 axis CNC router. It discusses software compatible with commercially available controller boards and a raspberry pi computer. It specifically discusses using the bCNC program on the raspberry pi to communicate with the microcontroller running grblHAL. Please note that CNC milling is not my area of training, that my experience here is very limited. This page reflects my experiences and opinions, some of which may be catastrophically wrong. Your mileage may vary. If you see glaring errors, feel free to point them out to me (j6summers@gmail.com).
Size matters (so does budget).
The build plate on our machine is about 400 mm square. Here is a link to a design that you can build to handle 4 foot by 8 foot sheet goods. Here is a link to some notes about a machine that we are building that will be capable of cutting 2 foot by four foot stock. Each design has its advantages and disadvantages. The stiffness of a machine is one consideration. Milling wood or plastic can be done with a relatively flexible machine but milling aluminum requires greater stiffness. Milling steel requires much greater stiffness and is beyond our experience.
A smaller machine will be stiffer than a larger one but will limit the size of what you can make. A machine made from aluminum extrusions will not be as stiff as one made from cast steel but it will be much less expensive.
Consider what you want to use the machine for. A machine for cutting small bits of wood will be a lot less expensive than one for milling large pieces of steel.
Our 3 axis CNC mill was assembled from a kit we bought from OpenBuilds. While OpenBuilds is no longer in business, here is a link to a hardware kit by another manufacturer that is based on the same design. Here is a video showing how it is assembled. The machine is made from aluminum V-slot rails, which are available from a number of online suppliers. MakerStore.cc is one such supplier. MakerTechStore.com is another. In addition to the aluminum rails, the build requires the following: 1. gantries that ride on wheels along the rails, 2. plates at the ends of the gantries that accept the drive screws and motor hardware, 3. drive screws, nuts, bearings and standoffs for the motors, 4. motors (NEMA 23 steppers) and couplers (that connect the motors to the drive screws, 4. a small router and mounting hardware, 5. a hefty power supply (we use 24V DC) and 6. a controller board (we use the T41U5XBB with a Teensy 4.1 microcontroller which was one of the earlier available for grblHAL), and stepper motor drivers. Of course, you need a computer to drive it. We use a Raspberry Pi model 4b.
We also built a plywood box to keep the noise and sawdust down. Sawdust made out of aluminum chips is especially hard on electronics. Don't ask how I know.
There are two types of motors used for spindles, brushed and brushless. On our current machine we use a small (1.25 hp) Makita router with a brushed motor. This works well for cutting wood products and plastics, and can be used to cut aluminum. It is not, however, ideal for all uses. Routers run at crazy high rpm. Cutting metals requires a slower turning spindle with speed control, which is something brushless DC motors (bldc) do. A brushless DC spindle requires a Variable Frequency Drive (VFD) with a DC power supply. It may need a water pump for cooling and you will need a mount for the spindle. Here is a link to a spindle kit that I am considering. For cost comparison, in February 2026 the spindle kit cost $255 while the Makita router was $150.
There are ways to slow down a router. Here is a commercial device that retails for $150. Here is a link to a discussion of building a speed controller for a router.
The controller board takes instructions (GCode) from your host computer and runs your stepper motors, turns on the spindle, monitors the end stops, etc. As mentioned above, our first CNC router used the T41U5XBB driver board with the Teensy 4.1 microcontroller. Since we built our current configuration, a number of other boards have become available. One thing that I do not like about the board we currently use is that it requires external motor drivers. More recent controllers either incorporate mounts for driver boards or have drivers incorporated.
I am currently building a second CNC router for larger wooden projects based on the LowRider from V1 Engineering and I plan to use the rodent board controller from BTT (screen shot above). At the time I bought it, the price was $56. This board incorporates the ESP32 microcontroller, has WiFi capability, and has incorporated motor drivers capable of sourcing 3A of current. Here is the link to the user manual. The rodent board comes with FluidNC firmware installed, so we are going to give that a try. Here is a link to a wiki for the rodent board from FluidNC. The grblHAL firmware for this board can be built using the web builder.
As an add-on, we built a jog-controller (described in the next section) that allows us to jog the tool around without sitting in front of the computer. The jog controller connects to the I2C interface pins, which are broken out on our current controller board.
Since our machine is in a plywood box, it is not easy to see the position of the cutter while sitting at the control computer. The jog controller (photo on the left) allows me to jog the tool around while physically in front of the router. The controller incorporates a RPi Pico microcontroller on the back of the pcb and a bunch of buttons on the front. The Pico communicates with the router controller using the I2C protocol. The grblHAL firmware is already set up to interface with a keypad, but requires that you include the "keypad" plugin when you compile. This is easily done using the web builder (described below in the Firmware section). The jog controller has buttons to jog in X, Y, and Z (plus and minus) and also 45 degrees between the x and y axes (+X+Y, +X-Y, -X+Y and -X-Y). It also has a button to toggle between three jog speeds (rapid, slow, and step). The oled display shows the current jog speed setting.
Unlike in 3D printing, milling requires that you hold the work piece in place. Holding your work piece secure is a complex issue. There are a lot of ways to do it and the right one depends on what you are trying to accomplish. Clearly, milling a hard metal requires more holding force than milling wood or plastic. In cases where minimal force is required, two-sided carpet tape works. We more frequently rely on methods that employ 5 mm threaded inserts. The inserts are set in a grid and when feasible, your work piece can have a couple of holes drilled in it to hold securely to the build plate.
The figure on the left shows an alternative method where a the work piece is held by a "pseudo-clamping" mechanism. In this scheme, there are end brackets bolted down at the high and low Y-axis ends. The work piece (the brownish piece in the figure) is held against the low Y axis end, which is parallel to the X-axis. The other side of the work piece is held by a clamped wedge, which is pressed into the work piece by the sliding wedge. Once the sliding wedge is pressed in, the bolts holding the clamping wedge are tightened down, fixing the geometry.
Tabs are commonly used to keep a workpiece from flying away when it gets cut off from the pieces that are being held down.
The first thing you need is a program that talks to the microcontroller on the driver board. A program called bCNC works well on the Raspberry Pi. You can download bCNC for free. While the instructions for installing the code are basically correct, downloading packages onto the current Pi operating systems requires you do so in a virtual environment. Here is a description of how that is done.
Like other CNC control software, bCNC has a terminal function that allows you to look at the code passed between the computer and the machine. In this terminal (accessed on the upper right tab) you can view and edit a number of machine settings. To view the settings, type $$ in the command line. Here is a page to help understand what the settings are.
The firmware you need will depend on the controller you use. Our present machine uses the Teensy 4.1 microcontroller with grblHAL firmware. One benefit of grblHAL is that you can download compiled firmware from a web builder. For the Teensy microcontroller, the web builder outputs a hex file that can be loaded using the Teensy Loader application.
The web builder has a number of tabs that allow you to customize your software. One of the tabs is "plugins". On the plugin tab you can chose to enable the keypad functionality. Even if you don't have a keypad, it doesn't hurt to have this enabled in case you decide you want one later. For my planned larger machine, I intend to use ganged Y axis motors that allow auto-squaring. Auto-squaring is an option available through the web builder. Another option is a Z-axis probe.
Another popular firmware is FluidNC which was written for ESP32 microcontrollers. The rodent controller I purchased incorporates the ESP32, so I will have the option of pursuing this in my future build. According to this link, grblHAL can be flashed onto the ESP32 using a tool from here. Here is a link to a page describing how to use the tool
Setting up your CNC router requires getting the machine settings correct. The settings include things like the number of steps the microcontroller sends to make the machine move a certain distance. To find the machine settings, type $$ into the terminal. grblHAL will respond by sending a list of machine settings and their values. Unfortunately, grblHAL does not give a description of what each setting is in this list (I think that Universal GCode Sender, UGS, does). Here is a link to a page with a listing of settings.
Common Errors: Once you load up the firmware, grblHAL is expecting normally closed limit and probe switches. If you use normally open limit switches, you will get error message from bCNC that say: "XYZHSEP". These are seven individual error messages that are associated with not having the expected hardware configuration. You can fix these by opening the terminal and sending the following commands: $5 = 7 (this inverts the x, y, and z end stops, fixing the X, Y, and Z errors). Sending $14 = 70 inverts the emergency stop (E), hold (H) and start (S) switches. Sending $6 = 1 inverts the probe switch, fixing the P error.
The fast and easy way to get from idea to product is to throw money at it. That is not what we do and I am not going to pretend to know the ins and outs of what is involved. Here is a review of some options. Autodesk Fusion offers a version with limited functionality for personal use is free for 3 years. After that, I assume that you need to pay for it. VCarve also has free versions and time limited options.
The first step in CNC milling is drawing what you want planned. This is done in Computer Aided Drafting (CAD) programs. While there are a number of good CAD programs for generating .stl files for 3D printing, this doesn't easily translate to CNC milling. Inkscape is a commonly used program for creating 2 dimensional drawings. It is not something I have experience with. One option is LibreCAD. Another option is a python based, open source program called EZDXF that has a plugin (r12writer) that allows you to generate dxf files. Once you have a two dimensional drawing, you can translate that into GCode using CAM software.
CAM is an acronym for Computer Assisted Manufacturing. Here is a reddit page that discusses some of the options.
While 3D printing usually uses .stl files, milling requires files written in GCode. Some programs require files in DXF format. We have used a program built into our controller software (bCNC). The CAM functions of bCNC are not intuitive and it takes a bit of time to figure out how to use them. Documentation is rather limited, but here is something to get started. Here is a link to a web based DXF to CAM program. Here is a link to a tutorial for using a program called FlatCAM to generate tool paths for milling pcb boards.
Another free CAM software package is called Estlcam. It is found here. I found it from the lowrider web site.
PyCAM, a cautionary tale: One CAM program that looked promising is PyCAM, an open source python based program that works with Linux. Pycam has a problem with one or more of the modules being deprecated. This is discussed in a pull-request from the GitHub page. As far as I can tell, PyCAM is not functional.
GCode can be generated from drawing files (usually in DXF format) by a number of programs. Here is a link to a web page where you can download a program for converting DXF files to GCode. Here is a link to an online program available from the folks at OpenBuilds. Here is another online program.