Skip to content

Uno · Build guide

Gesture Controlled Robotic Arm with Arduino Uno and MPU6050

Control a 4-DOF robotic arm with simple hand tilts. An MPU6050 on a glove, an Arduino Uno and a PCA9685 servo driver: full wiring, code, calibration and troubleshooting.

Difficulty
Intermediate
Read time
15 min
Board
Uno
Author
AyTee
Published
Oct 26, 2026
Views
1
Gesture Controlled Robotic Arm with Arduino Uno and MPU6050

What You Will Build

Imagine tilting your hand and watching a robotic arm copy you. In this project you will build a four-degree-of-freedom (4 DOF) robotic arm that follows the tilt of your hand. An MPU6050 motion sensor is mounted on a glove, an Arduino Uno reads it, and a PCA9685 servo driver moves the base, shoulder and elbow of the arm. A push button on the control unit opens and closes the claw.

The control scheme is easy to learn in a minute:

  • Roll your wrist (thumb up or down) and the base rotates left or right.
  • Pitch your hand (fingers toward the ceiling or the floor) and the shoulder moves forward or back.
  • The elbow moves in the opposite direction to the shoulder, so the gripper stays level as it reaches.
  • Press the button and the claw toggles between open and closed.

You will also learn the engineering that makes it work smoothly: powering servos properly, sharing an I2C bus between two devices, turning accelerometer data into angles, filtering noise, and recovering when the bus locks up.

Time: a weekend. Skill level: intermediate. You need basic soldering-free wiring skills and patience during assembly.

Image pending: The finished gesture-controlled robotic arm, with the MPU6050 glove in front of it

Components

12 items
NameQtyLink
Arduino Uno R3×1—
MPU6050 module (GY-521)×1—
PCA9685 16-channel servo driver×1—
4-DOF robotic arm chassis kit (laser-cut) with 4 hobby servos×1—
5 V DC power supply, regulated, 3 A or more×1—
Toggle switch×1—
100 µF electrolytic capacitor, 10 V or higher×1—
Push button module×1—
Glove×1—
Half-size breadboard×1—
Mini breadboard×1—
Jumper wires (male-to-male and male-to-female)×60—

Need these parts? Get this build sheet by email

Parts list with buy links, plus new builds as they're published. By subscribing you agree to our Privacy Policy. Unsubscribe anytime.

How the System Works

Three signal paths and one power path make up the whole machine. The diagram shows them together.

  • Sensing: the MPU6050 contains an accelerometer. Gravity pulls on it differently depending on how your hand is tilted, and the Arduino reads those values over I2C.
  • Processing: the Arduino converts the readings into roll and pitch angles, filters them, and maps them to servo angles.
  • Moving: the Arduino tells the PCA9685 over the same I2C bus what pulse width to produce for each of the three arm joints. The PCA9685 generates the precise 50 Hz servo signals itself, so the Arduino does not have to. The claw servo is the exception: it connects directly to Arduino pin 6 and is driven by the Servo library.
  • Power: the servos draw large currents, so they get their own 5 V supply, completely separate from the Arduino's logic power. This is the single most important design decision in the build.
System block diagram: Arduino, I2C bus with MPU6050 and PCA9685, servos, push button and the separate 5 V servo supply

Assembling the Chassis

Gather every component before you start, then sort the laser-cut pieces so you know what you are working with. Screw and bolt the joints together, fitting each servo into its slot as you go. Do not leave the servos for later, because several are hard to reach once the arm is assembled.

The claw is the part that confuses most builders. The gear linkage is not obvious from the pieces alone, so watch a video for your specific chassis before forcing parts together. The video below helped with this build.

If your kit comes with fewer bolts than expected, redistribute what you have and make sure the load-bearing joints at the base and shoulder are the most secure. They carry the most stress.

⚠️ Warning

Centre every servo before you fit its horn. With the servos on 90 degrees, attach the arm links in their mid positions. Fitting a horn at a random angle is the most common reason an arm hits its own frame later.

Setting Up the Power Supply

Connect the positive output of the 5 V DC supply to one terminal of the toggle switch, then from the other terminal into the positive rail of the breadboard. The negative output goes straight to the negative rail. Place the 100 µF capacitor across the rails with the longer leg on positive and the shorter leg on negative. It absorbs the voltage spikes the servos create and keeps the rail stable.

A regulated 5 V supply needs no adjustment, but confirm with a multimeter that the output really reads 5 V before you connect any components. Anything significantly higher will damage the servos.

Size the supply properly. Four hobby servos can each draw several hundred milliamps when moving and well over an amp if one stalls against an obstacle. A supply rated for 3 A or more leaves safe headroom. A weak supply is the usual reason for jitter, resets and sagging joints.

Wiring Everything Together

One rule above all: common ground

Every component must share the same ground. If you skip this you will see erratic readings, servos moving on their own and I2C errors. Connect all of these to the negative rail: the Arduino GND, the PCA9685 GND (both the header and the servo terminal block), the MPU6050 GND, the push button GND and the negative wire of each servo.

Servo power path

From the breadboard positive rail, connect to the V+ terminal block on the PCA9685. This is the high-current path for the three arm servos. The claw servo's red and brown wires also go to the positive and negative rails, with only its signal wire going to Arduino pin 6. Never power servos from the Arduino's 5 V pin: the Uno cannot supply that current, and it will keep resetting.

Logic connections

ConnectionFromTo
PCA9685 logic powerPCA9685 VCCArduino 5V
MPU6050 powerMPU6050 VCCArduino 5V
Push button powerButton VArduino 5V
I2C dataArduino A4SDA on both PCA9685 and MPU6050
I2C clockArduino A5SCL on both PCA9685 and MPU6050
Button signalButton SArduino pin 2
Claw servo signalServo signal wireArduino pin 6
Base servoServo plugPCA9685 channel 0
Shoulder servoServo plugPCA9685 channel 1
Elbow servoServo plugPCA9685 channel 2

Run horizontal connections across the breadboard so one Arduino pin reaches both I2C devices at the same time. The GY-521 board has its own voltage regulator, so it works fine with the Arduino's 5 V.

🚨 Danger

Do not feed 5 V into the Arduino Uno's VIN pin. VIN goes through a reverse-protection diode and a linear regulator that need about 7 V or more at the input, so 5 V there leaves the Uno's 5 V rail sagging below 5 V and causes brownouts and I2C errors. Power the Uno through its USB port (you need it for the Serial Monitor anyway). For standalone use, either apply 7 to 9 V to the barrel jack, or feed a clean regulated 5 V into the 5V pin, but never both that and USB at the same time.

Mounting the Sensor on the Glove

Glue the mini breadboard to the back of the glove, so it lies flat on the back of your hand, and plug the MPU6050 into it. Run a four-wire harness (VCC, GND, SDA, SCL) from the glove back to the control unit. Make it long enough for free movement without tugging on any connection.

Some practical advice that saves hours of debugging:

  • Mount the sensor flat. When your hand is held level, the sensor should be level. That is the "neutral" pose the code maps to the servo midpoint.
  • Keep the harness short. I2C was designed for short wires. Use the shortest cable that is comfortable, twist SDA and SCL together with a ground wire, and keep it away from servo wiring.
  • Strain-relieve the cable. Tie it to the glove wrist so pulling on the cable never pulls on the sensor.
Image pending: The MPU6050 mounted flat on a mini breadboard on the back of the glove, with the four-wire harness

Programming the Arduino

In the Arduino IDE, open Sketch → Include Library → Manage Libraries and install Adafruit PWM Servo Driver Library. Wire.h and Servo.h come with the IDE. Use a current Arduino AVR Boards package, because the sketch calls Wire.setWireTimeout() and Wire.end(), which older versions lack.

Step 1: Scan the I2C bus

Before you upload the full firmware, confirm both devices are visible. Upload this scanner and open the Serial Monitor at 9600 baud:

C++

You should see 0x68 (MPU6050) and 0x40 (PCA9685). The PCA9685 also answers on 0x70, its "all call" address, so seeing that too is normal. If either main device is missing, check the SDA and SCL wiring and the common ground.

Step 2: Check the gesture readings

Next, with the servos still unplugged, see what the sensor reports. This small sketch prints roll and pitch so you can confirm the directions and the neutral pose:

C++

Hold your hand level and both values should be close to zero. Roll the wrist and only the roll number should change. Pitch your hand and only the pitch should change. Note which direction is positive, because that decides whether your arm moves the way you expect.

Step 3: The full firmware

Once the scanner finds both devices and the readings look right, upload the main sketch. Open the Serial Monitor and you should see "Full 4DOF System Ready. Base/Shoulder/Elbow active." If the loop keeps running without freezing, your I2C bus is stable.

C++

How the Gestures Become Movement

From gravity to angles

An accelerometer at rest measures gravity. Tilt it, and gravity splits differently across its X, Y and Z axes. The two atan2() lines convert those three numbers into angles: roll from atan2(Y, Z) and pitch from atan2(-X, Z). Because gravity is the only reference, the sensor cannot tell how far you have turned your hand around the vertical axis (yaw). That is why the base is driven by wrist roll and not by rotating your hand like a steering wheel.

Mapping tilt to servo angles

The sketch treats ±60° of tilt as your comfortable range and stretches it to the servo's full 0 to 180°. A level hand (0°) gives 90°, the servo midpoint. The constrain() calls clamp the result, so a tilt beyond ±60° just holds the joint at its end instead of pushing the servo past its limit. The chart shows the relationship.

  • Base follows roll.
  • Shoulder follows pitch.
  • Elbow follows pitch in the opposite direction, which keeps the gripper roughly level as the arm reaches.
Chart: hand tilt from −90° to +90° mapped to servo angle, with the active ±60° range and clamped ends

Smoothing

Raw accelerometer data is jumpy, and servos amplify every twitch. The three lines that use alpha form an exponential moving average: each new smoothed value is 5% of the new target plus 95% of the previous smoothed value. After a sudden movement the output covers about 63% of the distance in roughly 20 loop passes and about 95% in roughly 60. The result is fluid motion with a small, deliberate lag. Raise alpha toward 0.15 for a snappier arm, or lower it for a smoother, slower one.

The claw button

The sketch reads the button as active HIGH, which matches a push button module with an on-board pull-down resistor. It toggles isClawClosed only when the reading changes from LOW to HIGH, the same edge-detection idea used in many projects, so holding the button does not repeat. The 200 ms delay is a simple debounce.

If you use a bare push button instead, add a 10 kΩ pull-down resistor from the signal pin to GND, or use the internal pull-up and invert the logic like this:

C++

Self-healing I2C

Long wires, servo noise and loose connections can make the I2C bus lock up. Wire.setWireTimeout(3000, true) stops the Arduino waiting forever, and the else branch in the loop restarts the bus and re-wakes the sensor when a transfer fails. That is why the arm recovers instead of freezing.

Safe Test Sequence

Work up to the full arm in stages so any mistake stays small:

  1. Clamp the arm base to a table or bolt it to a board, and keep fingers clear of gears and linkages.
  2. With the servos disconnected, verify the sensor readings over serial using the test sketch.
  3. Test each servo on its own, with a conservative range and a proper power supply, and check that it reaches both ends without humming or straining.
  4. Connect the full control loop and confirm the neutral pose, the direction of each joint and the end stops.
  5. Test quick gestures, slow gestures, unplugging the sensor, and resetting the controller.
  6. Always switch the power off before adjusting linkages or working near pinch points.

Calibration

Servo pulse limits

The PCA9685 counts in 4096 steps per 20 ms cycle at 50 Hz, so each step is about 4.9 µs. The sketch's SERVOMIN 150 and SERVOMAX 600 correspond to pulses of roughly 0.73 ms and 2.93 ms. Many hobby servos only expect about 0.5 to 2.5 ms, and some less. Treat the defaults as a starting point. If a servo hums or strains at either extreme, narrow the range (for example 170 and 580) until both ends are quiet.

Neutral pose and direction

If the arm drifts when your hand is level, the sensor is not mounted flat. Remount it, or offset the roll and pitch values in code. If a joint moves the wrong way, swap the two output values in its map() call, for example map(roll, -60, 60, 180, 0).

Range and sensitivity

If small gestures cause big movements, narrow the input range from ±60° to ±45°. If you cannot reach the ends comfortably, widen it. Add a small dead zone around zero if the arm creeps when you hold still.

Troubleshooting

SymptomLikely causeFix
Servos jitterWeak or wrongly routed powerFeed the servos from the 5 V supply through the PCA9685 V+ terminals, use a 3 A supply, and check the 100 µF capacitor and common ground.
Arduino resets when the arm movesServo current is pulling the Arduino rail downNever power servos from the Arduino 5V pin; give them their own supply.
I2C bus freezesLong or noisy wires, loose jointsKeep Wire.setWireTimeout(3000, true), shorten and twist the glove cable, and fit the capacitor.
No devices found by the scannerWiring or ground faultCheck A4 and A5, VCC, and that every GND meets at the common rail.
Claw opens or closes by itself at power-upButton polarity mismatchThe sketch expects active HIGH. For a bare button use INPUT_PULLUP and trigger on the falling edge as shown.
Servos move on their own, readings unstableA ground is not connectedCheck that every component shares the same ground rail.
A joint moves the wrong waySensor orientationSwap the output values in that joint's map() call, or rotate the sensor.
Arm hits its frame or hums at an endPulse range too wideReduce the angle range or tighten SERVOMIN and SERVOMAX.
Arm sags or loses strengthSupply too small or voltage dropUse a larger supply and shorter, thicker power wires.
Arm is too twitchy or too slowFilter valueRaise alpha for speed, lower it for smoothness.

Limits and Ideas for Improvement

An accelerometer-only sensor cannot separate tilt from sudden movement, so shaking your hand will also move the arm. A better design combines the gyroscope and accelerometer with a complementary or Kalman filter. Other upgrades to consider:

  • Add a flex sensor on a finger to control the claw proportionally instead of toggling.
  • Use a second MPU6050 on the forearm for independent elbow control.
  • Replace the glove cable with an HC-05 Bluetooth module or an ESP32 and ESP-NOW for a wireless glove.
  • Add an emergency stop switch that cuts servo power while leaving the Arduino alive.
  • Record and replay a gesture sequence from EEPROM.

Frequently Asked Questions

Do I need the PCA9685? Not strictly. The Arduino can drive a few servos directly, but the PCA9685 gives stable pulses, frees up pins, and keeps servo wiring tidy as you add joints.

Why not just use the Z axis for the elbow? The sketch couples the elbow to pitch instead, which keeps the gripper level and makes the arm feel natural. You can change it if you want independent control.

Can I use an Arduino Nano? Yes, it has the same I2C pins (A4 and A5) and the same libraries work. Check the board's power rules before connecting servos.

Which servos should I use? Use the ones that come with your chassis. Metal-gear servos give a firmer arm but draw more current, so size the supply accordingly.

Summary

You built a gesture-controlled robotic arm from first principles: a sensor glove that turns tilt into angles, a servo driver on a shared I2C bus, a filter that smooths the motion, and a power design that keeps the Arduino safe. You also learned how to test in stages, calibrate pulse limits, diagnose the classic servo and I2C problems, and where an accelerometer-only controller reaches its limits.

Topicsrobotic-armmpu6050arduino-unopca9685servogesture-controlimu4-dof

Questions & Answers