A Robot Arm That
Weaves Thread Into Art
A 2-servo robotic arm that wraps colorful thread between pegs on a board, one careful movement at a time — turning simple math into a beautiful geometric mandala.
💡 How Does a Robot "Weave" Thread?
Two ideas team up to make this work: a robot arm that can point anywhere on the board, and simple math that decides where it points next.
- A 2-servo arm (like a tiny shoulder and elbow) reaches its thread guide out to any peg on the board.
- Inverse kinematics — math that works backward from "where do I want to point?" to "what angles do my joints need?" — tells each servo exactly what angle to move to.
- A simple skip-counting pattern decides which peg to visit next, and the arm sweeps there, letting the thread catch and stretch taut behind each peg.
🤖 What's "inverse" about inverse kinematics?
Forward kinematics asks "if I set these joint angles, where does the tip end up?" Inverse kinematics asks the opposite: "I want the tip HERE — what angles do I need?" That's exactly the calculation this robot does before every single move.
🧰 What You'll Need
- 1× Arduino Uno
- 2× SG90 or MG996R servo motors
- 1× 5V power supply (separate from Arduino)
- Wooden board (~40cm circle)
- 24–36 small nails or pegs
- 2× rigid arm links (thin wood or acrylic strips)
- 1× small eyelet or bent paperclip (thread guide)
- Colorful embroidery thread or yarn (several colors)
- 1× thread spool holder with light tension
- Hot glue, screws, jumper wires
A handful of bright thread colors is all it takes — the pattern math does the rest.
⚡ Two servos need real power
Both servos moving together — especially under thread tension — can draw more current than the Arduino's onboard regulator likes. Power them from a separate 5V supply, sharing only a common ground with the Arduino.
🛠️ Build It Step by Step
Mark the peg positions
Draw a circle on the board, then mark evenly spaced points around it (24 is a great starting count) using a protractor or a printed angle template.
Hammer in the pegs
Tap a small nail into each marked point, leaving about 1.5cm sticking up so thread can wrap around it.
Build the 2-link arm
Attach the shoulder servo at the board's center, then mount the elbow servo on the end of the first arm link, and attach the second link to the elbow servo's horn.
Add the thread guide
Glue or tape a small eyelet (or bent paperclip loop) to the very tip of the second link — this is what the thread rides through as the arm moves.
Measure your link lengths
Measure the shoulder-to-elbow and elbow-to-tip distances precisely in millimeters — you'll need these exact numbers in the code.
Wire the servos
Connect both signal wires to the Arduino, and power/ground to the shared rail as shown in the circuit diagram.
Update the code with your measurements
Set N_PEGS, RADIUS, L1, and L2 in the sketch to match your actual board.
Tie off the starting thread
Tie your first thread color securely to peg 0 before uploading the code.
Upload and watch it weave
Flash the sketch — the arm should swing smoothly from peg to peg, leaving a taut thread behind it each time.
💻 The Code
This sketch does two jobs: figures out where each peg physically is, then calculates the two servo angles needed to point the arm's tip exactly there.
// Thread-Weaving Robot — Arduino + 2-servo arm // Uses inverse kinematics to visit pegs in a skip-counting pattern #include <Servo.h> Servo shoulder; Servo elbow; const int N_PEGS = 24; // how many pegs around the board const int SKIP = 5; // try 5, 7, or 11 for different patterns const float RADIUS = 90.0; // mm, arm base to peg ring const float L1 = 60.0; // mm, shoulder-to-elbow link const float L2 = 60.0; // mm, elbow-to-tip link void moveToPeg(int pegIndex) { float angle = pegIndex * (360.0 / N_PEGS) * (PI / 180.0); float x = RADIUS * cos(angle); float y = RADIUS * sin(angle); float r = sqrt(x*x + y*y); float cosTheta2 = (r*r - L1*L1 - L2*L2) / (2*L1*L2); cosTheta2 = constrain(cosTheta2, -1.0, 1.0); // guard rounding errors float theta2 = acos(cosTheta2); float theta1 = atan2(y, x) - atan2(L2*sin(theta2), L1 + L2*cos(theta2)); int shoulderDeg = degrees(theta1) + 90; // offset to fit servo's 0-180 range int elbowDeg = degrees(theta2); shoulder.write(constrain(shoulderDeg, 0, 180)); elbow.write(constrain(elbowDeg, 0, 180)); } void setup() { shoulder.attach(9); elbow.attach(10); int current = 0; moveToPeg(current); delay(1000); // pause so you can tie the thread to peg 0 for (int step = 0; step < N_PEGS * 3; step++) { // loop pattern a few times current = (current + SKIP) % N_PEGS; moveToPeg(current); delay(500); // lets the thread catch and settle on the peg } } void loop() { // the pattern finishes inside setup() — nothing more to do }
🧮 Following the math, line by line
angle, x, and y find the peg's real-world position. theta2 and theta1 are the inverse-kinematics result — the exact shoulder and elbow angles needed to reach that spot. Everything after that is just telling two servos to move there.
🌀 Choosing a Skip Number
The pattern comes entirely from one number: how many pegs to "skip" each time. This is just skip-counting — the same idea as counting by 5s or 7s — wrapped around a circle instead of a number line.
🔍 Why do some skip numbers look better?
If the peg count and skip number share no common factors (mathematicians call this being coprime), the thread visits every single peg before returning to the start — a bold, unbroken pattern. If they share a factor, the thread repeats a smaller shape over and over instead of covering the whole board.
Tested combinations that look great
| Peg Count | Skip Number | Result |
|---|---|---|
| 24 | 5 | Classic 5-point star weave |
| 24 | 7 | Sharper interlocking star |
| 30 | 7 | Dense flower-like mandala |
| 36 | 11 | Intricate layered pattern |
| 36 | 13 | Bold wide-angle star |
Try the live demo at the top of this page — change Peg Count and Skip Number and watch the shape completely transform.
❓ Frequently Asked Questions
What is inverse kinematics, really?
It's the math that works backward from a target point to the joint angles needed to reach it — instead of picking angles first and seeing where the arm ends up, you pick the destination first and calculate the angles.
Why do I need to measure my own link lengths so precisely?
The inverse kinematics formula depends entirely on accurate L1 and L2 values — even a few millimeters off can cause the arm to miss pegs slightly, especially near the edge of its reach.
The arm reaches for a peg but stops short — why?
This usually means the target point is farther away than L1 + L2 combined — no arm configuration can reach it. Double check your RADIUS isn't larger than your two link lengths added together.
How do I change thread color partway through?
Add a short pause (or a push-button wait) after a set number of steps in the code, giving you time to snip the thread, tie on a new color, and resume — a great first upgrade to try.
Can I use a stepper motor instead of servos?
Yes — a stepper gives finer, more precise positioning and is a common upgrade for larger boards, though it needs a driver board and slightly different code.
🚀 Take It Further
Automatic color changing
Add a small servo-driven thread cutter and a rotating spool holder so the robot can switch colors on its own.
Random generative art
Instead of a fixed skip number, randomly change it every loop for a one-of-a-kind pattern every time you run it.
Bigger boards, more pegs
Scale up to 72 or 100 pegs for dramatically more detailed mandalas — just recheck your link lengths can still reach the full radius.
Turn it into a plotter
Swap the thread guide for a pen holder, and the same inverse-kinematics code becomes a simple drawing robot.

Comments
Post a Comment