CAD / Mechanical Software 2024

Custom CAD
Robotic Arm

A 4-DOF robotic arm fully designed in SolidWorks with motion simulation. Servo motors are controlled via a Python script, demonstrating the bridge between mechanical design and software.

SolidWorks Python Servo Control Kinematics
// The Problem & Solution

Mechanical Design

Robotic arms are a cornerstone of industrial automation, but off-the-shelf kits offer little insight into the engineering behind them. I wanted to design every component from scratch — understanding each joint, link length, and torque requirement before a single part was printed.

Using SolidWorks, I built a fully parametric 4-DOF arm assembly. Each joint was sized to the rated stall torque of the chosen MG996R servo, and I ran a basic static analysis to confirm the shoulder joint bracket wouldn't yield under full extension with a 150 g payload.

The final arm spans 480 mm when fully extended, weighs 620 g, and uses a direct-drive wrist with a 3-finger gripper — also designed in SolidWorks and printed in PETG for its improved layer adhesion.

// The Code & Electronics

Software & Control

Four MG996R servos are driven by a PCA9685 16-channel PWM board connected to a Raspberry Pi over I²C. A Python script translates target joint angles into PWM duty cycles and sends them in a synchronised update so all joints move together smoothly.

Forward kinematics were implemented to visualise the end-effector position in real time via a simple matplotlib overlay, useful for debugging reach limits before running the physical arm.

Python arm_control.py
# Set joint angle (degrees) → PWM pulse
def set_angle(channel, angle):
    angle = max(0, min(180, angle))
    pulse = int(
        SERVO_MIN + (angle / 180) *
        (SERVO_MAX - SERVO_MIN)
    )
    pwm.set_pwm(channel, 0, pulse)

# Move all joints simultaneously
def move_to(angles: list):
    for ch, ang in enumerate(angles):
        set_angle(ch, ang)
    time.sleep(0.02)  # 20 ms settle

What I Learned

⚙️

Joint Torque Budgeting

I underestimated the torque demand on the shoulder joint in the first revision — the servo stalled under the arm's own weight at full extension. Recalculating with proper moment arms and switching to a higher-torque servo solved this and taught me to always design with worst-case loading.

📐

Parametric CAD Discipline

After the first torque revision required changes to four separate parts, I restructured the SolidWorks assembly to drive all link lengths from a single master sketch. Subsequent changes then propagated automatically — a lesson in design-for-change from the start.

🐍

Python I²C Timing

Sending all four PWM updates sequentially introduced a visible stagger between joints. I switched to batching I²C writes into a single transaction using the PCA9685's auto-increment register mode, which eliminated the lag and gave the arm a much smoother, more coordinated motion.

// Explore Further

See It in Action

Full SolidWorks files and Python source code are on GitHub. A demo walkthrough is available on YouTube.