Most DIY robotic arm projects use one arm. But a growing number of tasks — folding, assembling, holding-while-working — genuinely need two. Dual-arm (bimanual) robots coordinate a pair of manipulators to do what a single arm physically can’t. Here’s how they work and how to approach building one.

Why two arms

A single arm can grip and move an object, but it can’t simultaneously stabilise something while a second tool acts on it. Tasks that need two arms:

  • Hold-and-work — one arm grips a part steady, the other drills, screws or applies adhesive.
  • Large/heavy object handling — two arms share the load and the reach, letting the pair carry something neither could manage alone.
  • Two-handed assembly — inserting a component that needs to be aligned by one hand while the other positions the receiving part.
  • Cloth and deformable object manipulation — folding, unfolding or untangling requires two contact points moving in coordination; this is an active robotics research area precisely because it’s hard with one arm.

Coordination strategies

Leader-follower

One arm’s motion is the “leader” — its trajectory is planned normally. The second arm’s motion is computed as an offset or mirror of the first, useful when both arms are moving a single rigid object together (think: carrying a tray). Simplest to implement; the follower’s control loop just adds a fixed transform to the leader’s commanded position.

Independent task allocation

Each arm runs its own independent program with its own goals, synchronized only at specific handoff points (e.g. “wait until arm A signals object placed, then arm B starts”). This is the easiest dual-arm pattern for a DIY build — two separate control loops, a simple flag or message passed between them at the moments that matter.

Joint bimanual planning

A single motion planner computes trajectories for both arms simultaneously, treating the pair as one combined system with twice the degrees of freedom. This is necessary when the arms’ workspaces overlap and could collide with each other mid-motion — the planner has to avoid arm-arm collisions, not just arm-environment collisions. This is the approach used in ROS MoveIt with a dual-arm URDF, and in research platforms like the ABB YuMi.

Synchronization challenges

Two arms moving toward a shared task introduce problems a single arm never has:

  • Timing. If arm A must finish placing a part before arm B starts fastening it, the control loop needs explicit synchronization — a shared variable, a serial message, or (in ROS) an action server that blocks until completion.
  • Collision between arms. Even with non-overlapping nominal paths, dynamic obstacles (the other arm’s gripper) require either workspace partitioning (each arm confined to its own region) or active collision checking during planning.
  • Shared compliance. When both arms grip the same rigid object, any disagreement in commanded position creates internal stress — the object gets squeezed or yanked. Force/torque feedback at the grippers helps detect this; without sensors, keep relative motion slow and conservative.

A DIY dual-arm build

The realistic hobby path is two independent servo arm kits, software-synchronized:

  1. Two identical arms — a pair of 4-DOF or 6-DOF kits, mounted with enough separation that their workspaces only overlap where the task requires.
  2. One controller, two PCA9685 drivers. A single Arduino Mega has enough I2C address space to drive two PCA9685 boards (different addresses via the solder jumpers) — one per arm, 16 channels each.
  3. A shared control loop. Structure your firmware or Python script around a simple state machine: each arm has its own target-position array, and a coordinator function sequences which arm moves when.
// Two PCA9685 boards at different I2C addresses
Adafruit_PWMServoDriver armA = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver armB = Adafruit_PWMServoDriver(0x41);

enum TaskState { ARM_A_PLACE, ARM_B_FASTEN, DONE };
TaskState state = ARM_A_PLACE;

void loop() {
  switch (state) {
    case ARM_A_PLACE:
      moveArm(armA, placePositions);
      if (armAReachedTarget()) state = ARM_B_FASTEN;
      break;
    case ARM_B_FASTEN:
      moveArm(armB, fastenPositions);
      if (armBReachedTarget()) state = DONE;
      break;
    case DONE:
      break;
  }
}
  1. Workspace planning first. Before any code, physically map out where each arm’s reach overlaps. Keep handoff points within both arms’ comfortable range (60–70% of reach, as with any single-arm task) and as far as practical from each other otherwise.

When dual-arm is overkill

If the task only needs holding a part still, a simple fixed jig or clamp is cheaper and more reliable than a second arm. Reach for dual-arm only when the second contact point genuinely needs to move during the task — otherwise a vice, fixture or 3D-printed jig solves the same problem with no synchronization code at all.

Where to go from here

Start with two single-arm builds you already understand — the Arduino code guide and wiring diagram apply unchanged to each arm individually. The only new work is the coordination layer between them. For complex bimanual planning, Gazebo with ROS 2 MoveIt supports dual-arm URDFs and collision-aware joint planning out of the box.

Frequently asked questions

What is a dual-arm robot?

A dual-arm (or bimanual) robot has two manipulator arms working together, either mounted on a shared base/torso or as two independent arms coordinated by one controller. They handle tasks a single arm can't: holding an object steady with one arm while the other works on it, lifting large/heavy items together, or performing two-handed assembly the way a human would.

Why use two arms instead of one stronger arm?

Many real-world tasks are inherently two-handed: opening a jar (one hand holds, one twists), folding cloth, assembling parts that need to be held and joined simultaneously, or carrying an object too large for one gripper. A single arm, however strong, can't stabilize and manipulate at the same time the way two coordinated arms can.

How do you coordinate two robot arms?

Three common strategies: leader-follower (one arm's motion drives the other's, useful for carrying a rigid object together), independent task allocation (each arm runs its own program, synchronized only at handoff points), and full bimanual planning (a single planner computes both arms' trajectories jointly, accounting for collision avoidance between the arms themselves).

Can I build a DIY dual-arm robot?

Yes — the simplest approach is two independent servo arm kits (or two 3D-printed arms) controlled from a single microcontroller or two synchronized microcontrollers communicating over serial/I2C. Coordinate them in software: same control loop, two sets of servo outputs, careful workspace planning so the arms don't collide with each other.