---
title: "Mini CNC from CD-ROM stepper motors, Arduino and a 3D-printed body"
url: https://michalasobczak.pl/posts/mini-cnc-from-cd-rom-stepper-motors.html
author: "Michał Sobczak"
description: "A tiny two-axis CNC machine built from two old CD-ROM drive mechanisms, an Arduino with a CNC shield running grbl, and a frame designed in OpenSCAD and 3D-printed. Design notes and the software chain from G-code to steps."
published: 2026-10-25T11:00:00.000Z
updated: 2026-10-25T11:00:00.000Z
language: en
categories: ["Hobby"]
tags: ["Hardware", "3D"]
license: CC BY-NC-ND 4.0 (https://creativecommons.org/licenses/by-nc-nd/4.0/)
---
# Mini CNC from CD-ROM stepper motors, Arduino and a 3D-printed body

> **Disclaimer:** the projects described here are the result of my own independent work, done without the use of AI. This article itself was written with the help of AI.

Every old CD-ROM drive has a small stepper motor with a lead screw and a sled moving on two guide rods. That is already one axis of a CNC machine. Take two drives, put one axis on top of the other, add a controller, and you have an X/Y plotter or a laser engraver the size of a book. I built one in January 2017 and kept the design in the [designs](https://github.com/michalasobczak/designs) repository.

## Body in OpenSCAD

OpenSCAD describes a model as code: primitives (`cube`, `cylinder`) combined with `union()` and `difference()`. For mechanical parts that need exact holes and clearances this is easier than drawing, because every dimension is a number you can change in one place.

![Mini CNC frame designed in OpenSCAD with guide rods highlighted](https://michalasobczak.pl/media/projects/mini-cnc.png)

The frame is two parts: an outer frame with the X-axis guide rods and an inner carriage that slides on them and carries the Y axis. The rod holes have two diameters, `r1 = 3.1` mm where the rod should be held tight and `r2 = 3.3` mm where the carriage must slide freely:

```openscad
$fn=21;

r1=3.1;
r2=3.3;

// OUTER
union() {
    difference() {
        cube([75, 70, 8]);
        translate([3,3,-1])
            cube([69, 64, 12]);
        #translate([-0.1, 11, 5])
            rotate([0,90,0])
            cylinder(r=r1/2, h=75.2);
        #translate([-0.1, 59, 5])
            rotate([0,90,0])
            cylinder(r=r1/2, h=75.2);
    }
    // mounting tabs ...
}
```

Two small habits that save a print:

-   holes are a bit longer than the wall (`h=75.2`, starting at `-0.1`), so `difference()` cuts all the way through instead of leaving a zero-thickness skin,
-   `#` in front of an object highlights it in the preview, which is the quickest way to check that the rods really go through the holes.

Export to STL straight from OpenSCAD and print. The whole part is 75 × 70 mm.

## Electronics

-   **Arduino** with a **CNC shield** and plug-in stepper drivers. The CD-ROM motors are small bipolar steppers, so keep the driver current low or they overheat quickly.
-   **grbl** firmware on the Arduino. It reads G-code over serial and generates step/direction pulses with acceleration.

## Software chain

| Step | Tool |
| --- | --- |
| Flash grbl `.hex` to the Arduino | XLoader |
| Send G-code, jog axes, set zero | Universal Gcode Sender |

Before the first real job, set steps per millimetre in grbl (`$100`, `$101`). CD-ROM lead screws have a much finer pitch than typical CNC screws and only a few centimetres of travel, so the defaults are far off.

## What I took from it

-   E-waste is a great source of precise mechanics. A CD-ROM sled has better repeatability than anything I could build from scratch.
-   Code-based CAD fits the way I think. The same approach later went into a [wall switch designed in OpenSCAD](https://michalasobczak.pl/posts/design-and-print-wall-switch-in-openscad.html).
-   grbl + Universal Gcode Sender is a complete and boring (in a good way) control stack. All the fun is in the mechanics.

Source: [github.com/michalasobczak/designs](https://github.com/michalasobczak/designs). See also the [overview of my hands-on projects](https://michalasobczak.pl/posts/hands-on-projects-on-github.html).
