Design and build a robotic arm with no CAD experience

Designing, printing, and controlling my first robotic arm#. Task: Designing, printing, and controlling my first robotic arm# Updated project notes: the Lab article now covers the current four-servo controller, its startup camera check, and the difference between the earlier IK experiment and the active direct-angle approach. This post records the first build. I wanted a robotic arm. I had close to zero CAD experience and had never used a 3D printer. So I wired Claude Code into FreeCAD, prompted my way through the design, printed the parts, assembled them, and then gave the arm vision and voice control via the Claude API. It's a v1 — works, has rough edges, and taught me 3D printing along the way. Here's how it came together. Part 1: using Claude Code for 3D CAD design# The first problem was the CAD. I'm building a servo-based arm, but I have effectively no CAD skills. So I built a workaround: FreeCAD + Python + Claude Code. Claude Code writes the Python geometry, FreeCAD watches the script and renders in real time. I describe what I need, iterate through conversation, and export to print. The whole arm is one macro — every part comes out of a single main.py against the FreeCAD Part workbench, using boolean CSG operations. The design is 5-DOF (two base turntables, shoulder, elbow, wrist, plus a planned gripper) built around MG996R servos fully enclosed inside the structural parts. Honeycomb lightening throughout — hex pockets in plates, flanges, and walls — to keep print times sane and parts rigid where they need to be. One quirk worth knowing: FreeCAD's macro runner chokes on Unicode, so the entire script is ASCII-only. No em-dashes, no degree symbols, no arrows in comments. It's not magic. You still need to think through dimensions, tolerances, and how parts actually fit together. But the barrier from idea to printable part dropped massively. Some parts came off the printer and went straight onto the arm. Part 2: assembling the first version# About 30 hours total — design, print, assemble. Four of the five servos are wired up: two turntables and two joints. Rotates and bends in all directions as expected. Gripper is still on the to-print list. Here's how the first build turned out: 4 servos working (2 turntables + 2 joints) — rotates and bends in all directions as expected Had to tape 2 servos — mounting tabs weren't holding them properly Glued one lid — didn't have long enough screws Cut one wall that was blocking rotation — couple cm too long Reprinted the bottom turntable — shaft was too long, the whole thing was basically levitating on a bolt Print-in-place hinge failed (offsets too small, printed solid) — replaced with a regular shaft This was also my first time ever using a 3D printer, which deserves its own footnote. Honestly satisfied for a first build. A few fixes for v1.1 — bigger servo housings, proper screws instead of glue, better mounting tabs — but the core thing works. Part 3: giving it vision and voice# Wanted the simplest possible way to make the arm recognise and react to real objects. Here's what I built: A Python controller running on my laptop holds the loop. Whisper (the base model, ~139MB, running locally on CPU) does push-to-talk speech-to-text on the spacebar. OpenCV grabs a 640×480 frame from the webcam at the moment I release the key. Both go to the Claude Vision API alongside the arm's current servo angles. Claude returns a structured JSON action — what to do, where, and how — and the controller dispatches it to the ESP32 over serial. The arm moves. It worked on the first try. One nice DX detail: if the ESP32 isn't plugged in, the controller falls back to a "dry run" mode that just logs the commands it would have sent. Lets me iterate on the brain without unplugging cables. How it decides what to do# The interesting design choice is how Claude and the local code split responsibility. Claude doesn't directly drive the servos for spatial tasks — it identifies what and where in pixel coordinates, and the local math layer figures out the geometry. The system prompt locks Claude into a strict JSON schema with six action types: reach — Claude returns pixel_x, pixel_y of the target object; the local IK pipeline does the rest. ("touch the red cup", "point at the ball") move — Claude returns raw servo angles directly. Used for expressive gestures it has freedom over. ("wave hello", "nod") dance, home, stop — single-action commands unknown — fallback for nonsense input; tools: Claude Code. Human role: The original post does not say how a person stayed involved.; limitations: The system has no gripper, preventing object manipulation, and relies on a fixed laptop camera position without spatial calibration to the arm. Motion is one-shot approximation without real-time feedback, and the FreeCAD macro runner requires ASCII-only scripts due to Unicode issues. Human intervention is necessary for physical assembly corrections and initial setup..

Tools

Claude Code

Published on Agent Work Atlas:

Overview

Designing, printing, and controlling my first robotic arm#

Workflow

Designing, printing, and controlling my first robotic arm# Updated project notes: the Lab article now covers the current four-servo controller, its startup camera check, and the difference between the earlier IK experiment and the active direct-angle approach. This post records the first build. I wanted a robotic arm. I had close to zero CAD experience and had never used a 3D printer. So I wired Claude Code into FreeCAD, prompted my way through the design, printed the parts, assembled them, and then gave the arm vision and voice control via the Claude API. It's a v1 — works, has rough edges, and taught me 3D printing along the way. Here's how it came together. Part 1: using Claude Code for 3D CAD design# The first problem was the CAD. I'm building a servo-based arm, but I have effectively no CAD skills. So I built a workaround: FreeCAD + Python + Claude Code. Claude Code writes the Python geometry, FreeCAD watches the script and renders in real time. I describe what I need, iterate through conversation, and export to print. The whole arm is one macro — every part comes out of a single main.py against the FreeCAD Part workbench, using boolean CSG operations. The design is 5-DOF (two base turntables, shoulder, elbow, wrist, plus a planned gripper) built around MG996R servos fully enclosed inside the structural parts. Honeycomb lightening throughout — hex pockets in plates, flanges, and walls — to keep print times sane and parts rigid where they need to be. One quirk worth knowing: FreeCAD's macro runner chokes on Unicode, so the entire script is ASCII-only. No em-dashes, no degree symbols, no arrows in comments. It's not magic. You still need to think through dimensions, tolerances, and how parts actually fit together. But the barrier from idea to printable part dropped massively. Some parts came off the printer and went straight onto the arm. Part 2: assembling the first version# About 30 hours total — design, print, assemble. Four of the five servos are wired up: two turntables and two joints. Rotates and bends in all directions as expected. Gripper is still on the to-print list. Here's how the first build turned out: 4 servos working (2 turntables + 2 joints) — rotates and bends in all directions as expected Had to tape 2 servos — mounting tabs weren't holding them properly Glued one lid — didn't have long enough screws Cut one wall that was blocking rotation — couple cm too long Reprinted the bottom turntable — shaft was too long, the whole thing was basically levitating on a bolt Print-in-place hinge failed (offsets too small, printed solid) — replaced with a regular shaft This was also my first time ever using a 3D printer, which deserves its own footnote. Honestly satisfied for a first build. A few fixes for v1.1 — bigger servo housings, proper screws instead of glue, better mounting tabs — but the core thing works. Part 3: giving it vision and voice# Wanted the simplest possible way to make the arm recognise and react to real objects. Here's what I built: A Python controller running on my laptop holds the loop. Whisper (the base model, ~139MB, running locally on CPU) does push-to-talk speech-to-text on the spacebar. OpenCV grabs a 640×480 frame from the webcam at the moment I release the key. Both go to the Claude Vision API alongside the arm's current servo angles. Claude returns a structured JSON action — what to do, where, and how — and the controller dispatches it to the ESP32 over serial. The arm moves. It worked on the first try. One nice DX detail: if the ESP32 isn't plugged in, the controller falls back to a "dry run" mode that just logs the commands it would have sent. Lets me iterate on the brain without unplugging cables. How it decides what to do# The interesting design choice is how Claude and the local code split responsibility. Claude doesn't directly drive the servos for spatial tasks — it identifies what and where in pixel coordinates, and the local math layer figures out the geometry. The system prompt locks Claude into a strict JSON schema with six action types: reach — Claude returns pixel_x, pixel_y of the target object; the local IK pipeline does the rest. ("touch the red cup", "point at the ball") move — Claude returns raw servo angles directly. Used for expressive gestures it has freedom over. ("wave hello", "nod") dance, home, stop — single-action commands unknown — fallback for nonsense input

Reported result

The v1 arm successfully rotates and bends with four working servos, though the gripper remains unprinted. Assembly required manual fixes like taping loose servos and reprinting parts due to tolerance errors. The vision-voice control loop worked on the first try, executing structured JSON actions sent to an ESP32, but lacks a feedback loop for mid-motion correction.

Human role

The original post does not say how a person stayed involved.

Limitations

The system has no gripper, preventing object manipulation, and relies on a fixed laptop camera position without spatial calibration to the arm. Motion is one-shot approximation without real-time feedback, and the FreeCAD macro runner requires ASCII-only scripts due to Unicode issues. Human intervention is necessary for physical assembly corrections and initial setup.

Try it

I want to replicate the robotic arm design workflow using Claude Code and FreeCAD. First, install FreeCAD and configure Claude Code to generate Python geometry scripts. Prompt Claude Code to design a 5-DOF arm structure using boolean CSG operations, ensuring the script is ASCII-only to avoid macro runner errors. Export the design to STL files and 3D print the parts. Assemble the arm with MG996R servos, manually checking for fit and tolerance issues. Next, set up a Python controller on a laptop that uses Whisper for local speech-to-text and OpenCV for webcam image capture. Connect this to the Claude Vision API to generate JSON action commands, which are then sent to an ESP32 microcontroller via serial. Before running the full system, perform a dry run where the controller logs commands without moving the hardware. Verify the JSON schema includes actions like 'reach', 'move', and 'home'. Confirm all physical connections and software dependencies are working before enabling actual servo movement. If any part fails to fit or the API returns invalid JSON, pause and adjust the design or prompt accordingly.

Original source

Source reports are not independently verified. Publication date is the catalog publication date, not the original article date.

More cases · Security & operations