Skip to content

My Final Project: 3-Axis CNC Pen Plotter

System Diagram

Initial Final Project Idea

My final project plan is a 3-axis CNC pen plotter. As an artist, I found the concept of testing the creative limits of machine for art intriguing. In addition to the machine, I will design the base to be height adjustable so that it is able to draw on surfaces that are not necessarily level and flat. There would also be a sliding panel on the upper frame so that the machine is still able to operate on flat surfaces.

Last December, I had a meeting with Dr. David Taylor on my final project. He made me aware of looking into weeks of Fab I could incorporate into the final product. So, my current approach is to customize it further by adding sound and visual aids. A section of the frame will be resin-filled and have LED lighting within to indicate when the working pen needs to be changed to a different color, and which color it needs to be changed to. The sound output device will give me alerts about the progress, whether it be the software encountering an issue or the print being completed.

Potentially, I want to try to make it connectable through Bluetooth and and add a pad or touchscreen component where I can directly control the G-Code remotely. There could also be an AI component using ChatGPT to generate G-Code.

Garrett Nelson suggested that I could add another dimension, literally, by making the machine capable of drawing on vertical surfaces, which I thought was really interesting and could challenge me.

Finalized Final Project Idea

In my final plan, I'm leaning more heavily towards the AI aspect. My plan is now is a 3-axis AI-automated pen plotter that generates drawings based on voice input. A ReSpeaker 2-Mic Pi Hat is connected to a Raspberry Pi to capture audio, which is processed using offline or cloud-based speech-to-text software. The recognized text is passed to a local or remote instance of ChatGPT, which parses the text and outputs a corresponding drawing instruction. A Python script processes the AI response and converts it into G-code commands using predefined templates for basic shapes and patterns. The G-code is transmitted over a serial connection to a GRBL-compatible controller, which drives stepper motors controlling the X, Y, and Z axes of the pen plotter. A touchscreen attached to the Raspberry Pi provides a local user interface for system monitoring, manual command entry, and error handling. The system is designed to allow for fully automated, hands-free generation of drawings based on natural language prompts.

Bill of Materials

Project Schedule

Week Dates Goals/Tasks
Week 1 April 28 – May 4 Get Speech-to-Text + Touchscreen Working
- Set up ReSpeaker 2-Mic Pi Hat
- Install/test speech-to-text software (Vosk, Google STT, or similar)
- Confirm Raspberry Pi can capture voice and convert it to text
Week 2 May 5 – May 11 Connect Speech-to-AI
- Set up OpenAI ChatGPT API access (or local AI model)
- Send recognized text to ChatGPT
- Get a text response from ChatGPT
- Display AI response on Pi (command line or touchscreen)
Week 3 May 12 – May 18 Machine Construction
- Assemble the 3-axis pen plotter
- Install motors, belts, lead screws, or rails
- Mount the pen holder
- Wire up the stepper motors, servo motors, limit switches
- Test manual motor movement (basic electronics check)
Week 4 May 19 – May 25 G-code Generation Basic
- Write a simple Python script that takes AI output and generates basic G-code commands (ex: square, circle)
- Test manually entering sample commands and getting G-code
- Start defining simple drawing "templates"
Week 5 May 26 – May 31 Machine Movement
- Set up GRBL communication (pySerial or UGS)
- Test sending basic G-code to pen plotter (move X, Y, Z manually)
- Connect the full chain: voice → AI → G-code → movement (basic test!)
- Start troubleshooting any mechanical or wiring issues
Week 6 Jun 1 – May Jun 7 Full System Integration + Polish
- Full system test: voice → AI → G-code → machine drawing
- Finish touchscreen UI (edit/send command)
- Final video/photo documentation
- Finish website and final project presentationThis is a sketch of my idea:

System Integration

Touchscreen - Raspberry Pi 4

When I purchased the 7 Inch HDMI Touchscreen LCD Display it came with instructions on how to connect it to a Raspberry Pi. Even so, because it was my first time working with a Raspberry Pi, I was still confused. When I tried searching for tutorials online, a lot of them already assumed I had some base level of knowledge I didn't.

Figuring out where each of the three connective parts went was not necessarily the hardest part, but installing the driver was. I ended up following this tutorial to power it on even though it was different than what I had.

After that, I just inserted the MicroSD chip with the driver and powered it on and I got to the landing page.


ReSpeaker 2-Mics Pi HAT - Raspberry Pi 4

The Mic HAT is installed on GPIO headers of the Raspberry Pi. I ended up following this tutorial for the microphone.

I was originally worried that this way of connecting the microphone would block the rest of the GPIO pins I would need for other aspects of my project, but I learned stacking headers would be a solution to that.

With it attached, I was able to get the Raspberry Pi to recognize my microphone by accessing the Command Prompt window on the touchscreen.


CNC Shield - Pen Plotter

GRBL-compatible CNC shield connections with X, Y, and Z axis stepper motors, servo motor, and X, Y, and Z limit switches.


Pen Plotter Lift Mechanism

Below is the 3D parts for the lift mechanism printed out and assembled. The mechansim was inspired by How To Mechantronics' pen plotter.

The 3D printing machine part of the project is based on the DIY Machines tutorials. I downloaded the .stl files.

I had used Fusion360 for engineering class before, but I had never created a 3D model of a project/machine. I consulted ChatGPT with these prompts.

Based on what I learned, I went to Create → Insert Mesh and added all the .stl files I downloaded.

I also changed the material through Modify → Appearance and I changed it to matte black PLA.


Modeling my Final Project


Adjustable Base Design

Upper Plate

For the base part, I was inspired by one of my previous projects and Angelina Yang's Pomo-desk.

Note: My design work in this section is done in cm.

On the XY plane, I drew a 40 x 50 cm rectangle.

Then, I drew a 36 cm square within, 2 cm centered leftward. I filleted the outer rectangle to have a radius of 1.50 cm and the inner square to have 1.00.

I extruded (keyboard shortcut "e") it to have a height of 1.50 cm and filleted the other edges by 0.3 cm.

I created a sketch on the topmost plane of this object and used a center diameter circle to draw the holes the screws will go through. I was inspired by this adjustable screw's cap design, but I plan on using an M14 hex head bolt. These ChatGPT prompts helped me through the process of figuring out how to make the base adjustable and details about the hex nut/bolt.

I calculated that the center of my circles should be 1.2 cm away from a non-filleted edge.

Because I plan on using an M14, the diameter for my circles is 1.4 cm.

I extruded the circles with a negative distance and used the operation cut to make them holes.

I used Create → Thread to add the spiral thread. For a standard M14 bolt, the threat pitch is 2.0 mm.

I did the same for the other 3 holes.

Note: "s" is the keyboard shortcut that lets you search up the tool you want.

Then, I tried to change the material to wood, but I got this error when I tried to:

To fix this, I went to the sidebar and clicked on bodies, selecting the entire thing. I then dragged the material to that selected body. I chose oak wood and it worked!

I realized that for the acrylic plate to not fall down, I needed to add tabs. I made each 0.30 cm x 1.5 cm.

I extruded each 0.25 cm.

I made 8 such tabs, 2 on each inner edge of the square.


Acrylic Plate

Next, to make the acrylic plate. I drew and filleted the square identically as before (36 cm with R1.00).

For its thickness, I subtracted the thickness of the tab from the thickness of the plate.

1.2-0.25=0.95

I made the material clear acrylic.


Bottom Plate

I also changed my plan for how the way the bottom panel would be: instead of an open square identical to the upper one, it would be better for it to be filled. So I remade the wood rectangle with the same size, but without the cut-out square.

M14 Hex Nuts and Bolts Design

I was worried my current plan for height adjustment wouldnt work and I didn't want to start designing something that wouldn’t work.

I did some research and thought this video was a plausible approach. However, I still didn't know how to account for the bottom panel.

I consulted Chat, and it gave me a few options:

To make the top panel height adjustable using a screw, you could use one of the following methods:

  1. Threaded Standoff/Spacer Method Use threaded standoffs or spacers between the top and bottom panels. Drill tapped holes (threaded) in the bottom panel. Use long screws that pass through the top panel and thread into the spacers. To adjust, swap spacers of different lengths or use an adjustable-height standoff.

  2. Slot and Screw Locking Mechanism Instead of fixed holes, create vertical slots in the top panel. Use screws with nuts (or wingnuts) that can slide along the slot This allows the panel to move up and down and lock at different heights.

  3. Lead Screw Mechanism Use four lead screws (one at each corner). The screws are threaded into the bottom plate, and rotating them raises or lowers the top panel. This works similarly to adjustable tables or CNC Z-axis motion.

  4. Spring-Loaded Knob Adjusters Use spring-loaded hand screws that allow quick height adjustments. These can be threaded into inserts in the bottom panel.

Which Method is Best? For simple adjustability → Use standoffs or spacers. For smooth height control → Use lead screws. For quick adjustments → Use slots and screws with wingnuts.

I even had it generate an image.

Which was not helpful. I went with something like the lead screw mechanism. I just needed to think of how the bottom could be secured. I also needed to change the upper panel so that it is not threaded and slighly wider than the bolt, or else it would not be easily adjusted. (I also need to figure out how to make sure screws adjust to the same height if I do it manually).


Nut Design

To make a hex nut for an M14, I roughly followed this technical drawing

as well as Kevin Kennedy's Hex Nut Chamfer Tutorial.

I made a circumscribed polygon (Create → Polygon → Circumscribed Polygon) on the XY plane.

And extruded 0.909 cm.

I created a sketch on the XZ origin plane and projected a corner point using Create → Project/Include → Project. Then, I could draw out my triangluar chamfer cutout.

I used Revolve, chose that triangle as my profile, and the Z-axis as my axis.

Next, to add a hole in this body using Create → Hole, we first select the desired planar face.

Extents: all Hole type: countersink Hole tap type: tapped Threat offset: full

I actually changed it to Isometric because thats the standard for the M14 hex nut I am using.

To give the other side the chamfer as well first go to Construct → Midplane and select the top and bottom of the object.

Then go to the Create → Mirror command for solids. Select all the faces that need to be mirrored and use the midplane as mirror plane.

It worked.

However, the thread is colliding with the bottom chamfer.

This is where parametric modeling comes in clutch. I went back to the hole action and changed one of the settings to offset. I set the distance to 0.81.

It it was all good.


Bolt Design

The design I figured for the bolt was to have a section close to the head be smooth, so that it can slide into the hole of the wood (I wont need the base plane threaded anymore). The rest will have the thread, which means the bottom one would not move when I twist the hex nut. The top board will be able to easily slide up and down the long bolt, but because gravity, it can only go as far as the nut lets it.

I made the nut again but did not thread or mirror the chamfers. On it, I drew a circle slightly smaller than the holes of the base boards so it can slide in and won't be too tight of a fit.

I extruded it by 1.5 cm, the thickness of the bottom board.

I extruded it again by 30 cm, thinking it would be a new component and I can thread just that one. But then I remembered that I could just adjust how far the threading goes in the settings.

To resize these images, I had to add attr_list under markdown_extensions: in my mkdocs.yml file. Then, After the closing parenthesis I added {width=300px}

I did so by de-selecting full length and using the arrows to adjust where the threads go.


Adjustable Base Assembly

According to Chat, for full editability, I would save my files as .f3d and if I want a fixed 3D model (e.g., for printing or use as a reference), I should save as .stl.

I did not need editability, so I went with .stl. I opened it through Mesh → Create → Insert Mesh → select from my computer. I arragned the mesh objects the way I intended them to be assembled, like so:

The material appearances did not translate, so I added them back on.

I also added my nuts and bolts and tested the assimilation of one corner. I adjusted the materials again, to stainless steel, and checked what it would look like.

The bolt looks long, but it needs to be that way to maximize how far up the plate can go. I also assembled the rest.

And that is my finished base!

Here are the .f3d files of all my Fusion work thus far in the order I completed them:

Upper Base

Lower Base

Acrylic Plate

Hex Nut

M14 Bolt

Full Model


Last update: May 14, 2025