Clay
Sculpting
Robot Arm!
Build a 4-joint robotic arm that grabs, pushes, and shapes modelling clay all by itself. Control it with joystick knobs — or let it sculpt on auto-pilot! 🎨🤖
A Robot Arm That Makes Art 🎨
Imagine a robot arm with 4 bendable joints — just like your shoulder, elbow, wrist, and fingers. Each joint is powered by a tiny servo motor. You can control all 4 joints with knobs, teach it a sculpting sequence, and then hit a button to watch it repeat those moves and shape clay by itself. This is exactly how industrial robot arms work in car factories and space stations!
Your arm has 4 main joints: shoulder (rotates), elbow (bends up/down), wrist (tilts), and fingers (grip). Our robot arm has exactly the same four joints! Each joint is controlled by a servo motor that receives precise angle commands from Arduino — like a brain sending signals down your nerves. The clay is like the robot's art project. 🖼️
How Does the Robot Know Where to Move? 🤔
It's a beautiful chain of signals from your fingers to the clay!
map() function.Collect These 9 Things First 🛒
All available online or at local electronics stores. Total under ₹800!
Build Your Robot Arm! 🔨
Follow every step. Power everything off before changing wires. Ask an adult to help with cutting and gluing!
| Wire Color | Connection | What it does |
|---|---|---|
| Brown | GND | Ground / negative |
| Red | 5V | Power — must come from PCA9685, NOT Arduino! |
| Orange | Signal | PWM signal from PCA9685 — tells servo the angle |
| Segment | Length | Material | Notes |
|---|---|---|---|
| Base | 8×8 cm square | Thick cardboard / plywood | Servo 0 mounted in center pointing up |
| Upper arm | 12 cm long | Cardboard strip or popsicle sticks | Servo 1 at one end, connects to base |
| Forearm | 10 cm long | Cardboard strip | Servo 2 at joint, connects upper arm |
| Wrist+Tool | 6 cm | Cardboard + clay tool | Servo 3 controls tilt; glue tool at end |
🔩 Mount Servo 0 on Base: Hot-glue or screw Servo 0 flat on the base platform. The horn should point upward. This servo rotates the whole arm left and right.
🔩 Attach Upper Arm to Servo 0 Horn: Screw the upper arm strip to Servo 0's horn. When Servo 0 turns, the whole arm turns with it.
🔩 Mount Servo 1 at top of Upper Arm: This is the shoulder. Its horn will connect to the forearm. When Servo 1 turns, the forearm raises/lowers.
🔩 Attach Forearm to Servo 1 Horn: Connect the forearm strip to Servo 1's horn using a screw or strong tape.
🔩 Mount Servo 2 at end of Forearm: This is the elbow. Servo 3's horn connects to the wrist piece.
🔩 Add Clay Tool to Wrist: Glue a small wooden dowel, plastic spoon, or modelling tool to the final servo's horn. This is what touches the clay!
1. Open Arduino IDE on your computer.
2. Go to Sketch → Include Library → Manage Libraries
3. In the search box type: PCA9685
4. Find "Adafruit PWM Servo Driver Library" and click Install.
5. Also install "Adafruit BusIO" if prompted as a dependency.
| Arduino Pin | → | PCA9685 Pin | Wire Color |
|---|---|---|---|
| 5V | → | VCC | Red (logic power) |
| GND | → | GND | Black |
| A4 (SDA) | → | SDA | Blue |
| A5 (SCL) | → | SCL | Yellow |
| ⚡ External 5V 3A supply: (+) → PCA9685 V+ terminal | (–) → PCA9685 GND terminal | |||
| Servo | PCA9685 Channel | Joint Role | Angle Range |
|---|---|---|---|
| Servo 1 | Channel 0 | Base rotation | 0° – 180° |
| Servo 2 | Channel 1 | Shoulder up/down | 0° – 180° |
| Servo 3 | Channel 2 | Elbow bend | 0° – 150° |
| Servo 4 | Channel 3 | Wrist / tool tilt | 0° – 120° |
| Pot | Left leg | Middle (wiper) | Right leg | Controls |
|---|---|---|---|---|
| Pot 1 | 5V | → A0 | GND | Base |
| Pot 2 | 5V | → A1 | GND | Shoulder |
| Pot 3 | 5V | → A2 | GND | Elbow |
| Pot 4 | 5V | → A3 | GND | Wrist |
| Button | Pin 1 | Pin 2 | Function |
|---|---|---|---|
| Record 🔴 | Arduino D6 | GND | Save current position to sequence |
| Play ▶️ | Arduino D7 | GND | Run saved positions automatically |
The Complete Circuit 🔌
Study this carefully before wiring. The key rule: Arduino gets power from USB, PCA9685 gets its own 5V 3A supply. They share a common GND!
| From | Pin | → | To | Pin | Color |
|---|---|---|---|---|---|
| Arduino | 5V | → | PCA9685 | VCC (logic only) | Red |
| Arduino | GND | → | PCA9685 | GND (shared!) | Black |
| Arduino | A4 (SDA) | → | PCA9685 | SDA | Yellow |
| Arduino | A5 (SCL) | → | PCA9685 | SCL | Green |
| Arduino | A0 | → | Pot 1 (wiper) | Base knob | Orange |
| Arduino | A1 | → | Pot 2 (wiper) | Shoulder knob | Teal |
| Arduino | A2 | → | Pot 3 (wiper) | Elbow knob | Violet |
| Arduino | A3 | → | Pot 4 (wiper) | Wrist knob | Blue |
| Arduino | D6 | → | Button 1 | Record | Orange |
| Arduino | D7 | → | Button 2 | Play sequence | Violet |
| PCA9685 | Channel 0 | → | Servo 1 | Base rotation | Orange |
| PCA9685 | Channel 1 | → | Servo 2 | Shoulder | Teal |
| PCA9685 | Channel 2 | → | Servo 3 | Elbow | Violet |
| PCA9685 | Channel 3 | → | Servo 4 | Wrist / tool | Blue |
| 5V 3A Supply | V+ positive | → | PCA9685 | V+ power terminal | Red (dashed) |
| 5V 3A Supply | GND negative | → | PCA9685 | GND terminal | Black (dashed) |
The Complete Arduino Code 💻
Install the Adafruit PWM Servo Driver Library first (Sketch → Include Library → Manage Libraries → search "PCA9685"). Then copy and upload!
// ╔══════════════════════════════════════════════════════════╗ // ║ CLAY SCULPTING ROBOTIC ARM — MakeMindz ║ // ║ Servos: 4× SG90 via PCA9685 (I2C) ║ // ║ Control: 4 Pots (A0–A3) + Record (D6) + Play (D7) ║ // ║ Library: Adafruit PWM Servo Driver Library ║ // ╚══════════════════════════════════════════════════════════╝ #include <Wire.h> #include <Adafruit_PWMServoDriver.h> // ── Create the PCA9685 object (I2C address 0x40 is default) ── Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40); // ── Servo PWM pulse range (microseconds for SG90) ───────────── // SG90: 500µs = 0°, 1500µs = 90°, 2400µs = 180° // PCA9685 at 50Hz: 4096 ticks = 20ms (full period) // Formula: ticks = (microseconds / 20000) * 4096 const int SERVO_MIN = 102; // ~500µs → 0° const int SERVO_MID = 307; // ~1500µs → 90° const int SERVO_MAX = 491; // ~2400µs → 180° // ── Pin definitions ──────────────────────────────────────────── const int POT_BASE = A0; // Potentiometer → base servo const int POT_SHOULDER = A1; // Potentiometer → shoulder servo const int POT_ELBOW = A2; // Potentiometer → elbow servo const int POT_WRIST = A3; // Potentiometer → wrist servo const int BTN_RECORD = 6; // Record button const int BTN_PLAY = 7; // Play sequence button // ── Servo channel assignments on PCA9685 ────────────────────── const int CH_BASE = 0; const int CH_SHOULDER = 1; const int CH_ELBOW = 2; const int CH_WRIST = 3; // ── Sequence memory ──────────────────────────────────────────── // We can store up to 20 keyframe positions const int MAX_FRAMES = 20; int seqBase[MAX_FRAMES]; int seqShoulder[MAX_FRAMES]; int seqElbow[MAX_FRAMES]; int seqWrist[MAX_FRAMES]; int frameCount = 0; // ── State ───────────────────────────────────────────────────── bool isPlaying = false; long lastDebounce = 0; const int MOVE_DELAY = 600; // ms between frames during playback // ── setup() ──────────────────────────────────────────────────── void setup() { Serial.begin(9600); Serial.println("🦾 MakeMindz Clay Sculptor — Ready!"); Serial.println("Use knobs to position arm. D6=Record, D7=Play."); // Buttons with internal pull-up (no external resistor needed) pinMode(BTN_RECORD, INPUT_PULLUP); pinMode(BTN_PLAY, INPUT_PULLUP); // Start PCA9685 at 50Hz (standard servo frequency) pwm.begin(); pwm.setOscillatorFrequency(27000000); // Calibrated for accuracy pwm.setPWMFreq(50); delay(10); // Move all servos to safe home position (90° / neutral) setServo(CH_BASE, 90); setServo(CH_SHOULDER, 90); setServo(CH_ELBOW, 90); setServo(CH_WRIST, 60); delay(800); Serial.println("All servos at home position. Let's sculpt!"); } // ── loop() ───────────────────────────────────────────────────── void loop() { if (!isPlaying) { // ── MANUAL CONTROL MODE ────────────────────────────────────── // Read all 4 pots and map to servo angles int angleBase = readPotAngle(POT_BASE, 0, 180); int angleShoulder = readPotAngle(POT_SHOULDER, 10, 170); int angleElbow = readPotAngle(POT_ELBOW, 0, 150); int angleWrist = readPotAngle(POT_WRIST, 0, 120); // Send angles to servos setServo(CH_BASE, angleBase); setServo(CH_SHOULDER, angleShoulder); setServo(CH_ELBOW, angleElbow); setServo(CH_WRIST, angleWrist); // Print live readings Serial.print("Base:"); Serial.print(angleBase); Serial.print(" Shldr:"); Serial.print(angleShoulder); Serial.print(" Elbow:"); Serial.print(angleElbow); Serial.print(" Wrist:"); Serial.print(angleWrist); Serial.print(" | Frames saved: "); Serial.println(frameCount); // ── Check RECORD button ─────────────────────────────────────── if (digitalRead(BTN_RECORD) == LOW) { if (millis() - lastDebounce > 300) { lastDebounce = millis(); if (frameCount < MAX_FRAMES) { seqBase[frameCount] = angleBase; seqShoulder[frameCount] = angleShoulder; seqElbow[frameCount] = angleElbow; seqWrist[frameCount] = angleWrist; frameCount++; Serial.print("🔴 Recorded frame #"); Serial.println(frameCount); } else { Serial.println("⚠️ Memory full! Max 20 frames."); } } } } else { // ── PLAYBACK MODE — sculpt automatically! ──────────────────── Serial.println("▶️ Auto-sculpt sequence starting..."); for (int i = 0; i < frameCount; i++) { smoothMove(seqBase[i], seqShoulder[i], seqElbow[i], seqWrist[i]); Serial.print(" Playing frame "); Serial.print(i+1); Serial.print(" of "); Serial.println(frameCount); delay(MOVE_DELAY); } isPlaying = false; Serial.println("✅ Sequence complete! Clay sculpted 🎨"); } // ── Check PLAY button (works in both modes) ─────────────────── if (digitalRead(BTN_PLAY) == LOW) { if (millis() - lastDebounce > 300) { lastDebounce = millis(); if (frameCount > 0) { isPlaying = true; Serial.println("▶️ Starting auto-sculpt!"); } else { Serial.println("⚠️ No frames recorded yet. Use D6 to record!"); } } } delay(50); // ~20 updates per second } // ── FUNCTION: Read potentiometer and map to angle range ──────── int readPotAngle(int pin, int minAngle, int maxAngle) { int raw = analogRead(pin); // 0–1023 return map(raw, 0, 1023, minAngle, maxAngle); } // ── FUNCTION: Set a servo to an angle using PCA9685 ─────────── void setServo(int channel, int angle) { // Map angle (0°–180°) to PCA9685 tick count int ticks = map(angle, 0, 180, SERVO_MIN, SERVO_MAX); pwm.setPWM(channel, 0, ticks); } // ── FUNCTION: Smooth interpolated move between frames ────────── // Instead of jumping to the next position, glide there void smoothMove(int b, int s, int e, int w) { // Read current positions (last sent angles — approximated) static int curB=90, curS=90, curE=90, curW=60; int steps = 20; // Interpolation steps for smooth motion for (int i=1; i<=steps; i++) { int nb = curB + (b-curB)*i/steps; int ns = curS + (s-curS)*i/steps; int ne = curE + (e-curE)*i/steps; int nw = curW + (w-curW)*i/steps; setServo(CH_BASE, nb); setServo(CH_SHOULDER, ns); setServo(CH_ELBOW, ne); setServo(CH_WRIST, nw); delay(15); } curB=b; curS=s; curE=e; curW=w; // Update current positions }
What Does Each Part Do? 🔍
frameCount. When Play is pressed, the arm visits each saved position in order. Just like animation keyframes!smoothMove() divides the journey into 20 small steps and moves gradually, making the arm flow like a real sculptor's hand!INPUT_PULLUP, that resistor holds the pin HIGH (5V) normally. Pressing the button connects the pin to GND, making it LOW. So LOW = pressed. No extra components needed!map(raw, 0, 1023, 0, 180) linearly converts the pot's 0–1023 range to servo angle 0–180°. Turn the knob to the middle? map(512, 0, 1023, 0, 180) ≈ 90°. Full left → 0°. Full right → 180°. Simple and elegant!6 Real Engineering Skills You Just Gained 🎓
This robot arm teaches concepts used in industrial robotics, surgical robots, animation rigs, and space exploration!
Stay Safe While Building 🛡️
Servo motors move fast and with surprising force. Always have an adult nearby!
Something Not Working? 🔧
pwm.setPWM(0, 0, 307) in setup to force servo 0 to 90° and confirm it moves.readPotAngle(POT_BASE, 0, 180) to readPotAngle(POT_BASE, 180, 0) for that servo. This reverses the knob direction without physical rewiring.frameCount is less than 20. If you've recorded 20 frames, call frameCount = 0 to reset by uploading fresh code.Make Your Sculptor Even Smarter 🚀
Now that your robot arm sculpts, try these exciting upgrades!
I2C servo drivers, keyframe recording, smooth interpolation, 4 degrees of freedom. You've learned robotics that engineering students study in university. What will your robot create next?

Comments
Post a Comment