Back to All Blog Posts
Tutorial •EltroNerd Engineering

Arduino 6-DOF Robotic Arm with MG996R Servos and Control it via Bluetooth

This blog post walks you through creating a 6-DOF robotic arm using MG996R servo motors, controlled wirelessly via Bluetooth. It covers the hardware setup, including servo wiring and using an HC-05 module with SoftwareSerial on Arduino. The article explains the command structure for each joint (base, shoulder, elbow, wrist pitch, wrist roll, and gripper), and how to control them using a smartphone terminal app. It also includes the complete Arduino code and best practices for powering high-torque servos safely. Whether you're a robotics enthusiast or prototyping for automation, this guide offers a solid foundation for Bluetooth-controlled robotic manipulators.

Overview

This robotic arm uses 6 MG996R servos to control:

  1. Base rotation
  2. Shoulder movement
  3. Elbow movement
  4. Wrist pitch
  5. Wrist roll
  6. Gripper open/close

The arm is controlled wirelessly via Bluetooth (HC-05/HC-06) using SoftwareSerial on Arduino. Each servo receives angle values from the user through a mobile app or Bluetooth terminal.


📡 Working Steps:

  1. Power Up:

    • Servos are initialized and positioned to default angles (usually 90° for center).
    • Bluetooth module starts listening for input over SoftwareSerial.
  2. User Command:

    • You send a command like 2:130 from a mobile Bluetooth terminal (e.g., Serial Bluetooth Terminal app).
    • 2 refers to the shoulder servo, 130 is the target angle.
  3. Command Parsing:

    • The Arduino reads and parses the command.
    • It identifies which servo to control and what angle to set.
  4. Servo Actuation:

    • The chosen servo moves to the specified angle using servo.write(angle).
    • This continues in real-time as new commands are sent.

Core Components Used

  • Servo.h: Controls standard hobby servo motors.

  • SoftwareSerial.h: Enables serial communication on digital pins (used for Bluetooth).

  • 6 MG996R servos for different joints of the robotic arm:

    • Base rotation
    • Shoulder
    • Elbow
    • Wrist pitch
    • Wrist roll
    • Gripper
  • Bluetooth module (HC-05/HC-06) connected to pins 10 (RX) and 11 (TX).


Code Flow Overview

1. Initialization (setup() function)

bluetooth.begin(9600);
Serial.begin(9600);
  • Initializes communication with both Bluetooth and the Serial Monitor.
baseServo.attach(3);  // Attaches each servo to its PWM pin
...
gripperServo.attach(8);
  • Each servo is assigned to its corresponding control pin.
moveAll();
  • All servos are set to the default mid-point (90°) to ensure neutral positioning.

2. Main Loop (loop() function)

if (bluetooth.available()) {
  char command = bluetooth.read();
  Serial.print("Received: ");
  Serial.println(command);
  handleCommand(command);
  moveAll();
}
  • The program continuously waits for input from the Bluetooth module.

  • When a character is received:

    • It's printed to the Serial Monitor.
    • It's passed to the handleCommand() function to interpret which joint to move.
    • After the update, moveAll() is called to apply the new positions to all servos.

3. Command Handling (handleCommand() function)

switch (cmd) {
  case 'a': basePos = constrain(basePos - 5, 0, 180); break;
  case 'd': basePos = constrain(basePos + 5, 0, 180); break;
  ...
}
  • This function maps each received command to a specific joint movement.
  • The angle is increased or decreased in steps of 5 degrees.
  • constrain() ensures that angles never go below 0 or above 180, which are the servo’s safe limits.

Command Mappings:

Command Joint Action
a/d Base Rotate left/right
w/s Shoulder Up/down
q/e Elbow Up/down
r/f Wrist pitch Up/down
t/g Wrist roll Left/right
y/h Gripper Open/close

 


4. Servo Movement (moveAll() function)

baseServo.write(basePos);
...
delay(10);
  • Each servo is updated with the current angle value.
  • A slight delay (10 ms) ensures smooth transitions and avoids servo jitter.

Working Concept Summary

  • The robotic arm receives single-character Bluetooth commands.
  • These commands translate into incremental servo movements.
  • You can control all six degrees of freedom (including the gripper) wirelessly via a Bluetooth terminal app or controller.

Final Code

c
#include <Servo.h>
#include <SoftwareSerial.h>

SoftwareSerial bluetooth(10, 11); // RX, TX

Servo baseServo;
Servo shoulderServo;
Servo elbowServo;
Servo wristPitchServo;
Servo wristRollServo;
Servo gripperServo;

// Initial positions
int basePos = 90;
int shoulderPos = 90;
int elbowPos = 90;
int wristPitchPos = 90;
int wristRollPos = 90;
int gripperPos = 90;

void setup() {
  bluetooth.begin(9600);
  Serial.begin(9600);

  baseServo.attach(3);
  shoulderServo.attach(4);
  elbowServo.attach(5);
  wristPitchServo.attach(6);
  wristRollServo.attach(7);
  gripperServo.attach(8);

  moveAll();  // Set to initial position
}

void loop() {
  if (bluetooth.available()) {
    char command = bluetooth.read();
    Serial.print("Received: ");
    Serial.println(command);
    handleCommand(command);
    moveAll();
  }
}

void handleCommand(char cmd) {
  switch (cmd) {
    case 'a': basePos = constrain(basePos - 5, 0, 180); break;
    case 'd': basePos = constrain(basePos + 5, 0, 180); break;
    case 'w': shoulderPos = constrain(shoulderPos + 5, 0, 180); break;
    case 's': shoulderPos = constrain(shoulderPos - 5, 0, 180); break;
    case 'q': elbowPos = constrain(elbowPos + 5, 0, 180); break;
    case 'e': elbowPos = constrain(elbowPos - 5, 0, 180); break;
    case 'r': wristPitchPos = constrain(wristPitchPos + 5, 0, 180); break;
    case 'f': wristPitchPos = constrain(wristPitchPos - 5, 0, 180); break;
    case 't': wristRollPos = constrain(wristRollPos - 5, 0, 180); break;
    case 'g': wristRollPos = constrain(wristRollPos + 5, 0, 180); break;
    case 'y': gripperPos = constrain(gripperPos + 5, 0, 180); break;
    case 'h': gripperPos = constrain(gripperPos - 5, 0, 180); break;
  }
}

void moveAll() {
  baseServo.write(basePos);
  shoulderServo.write(shoulderPos);
  elbowServo.write(elbowPos);
  wristPitchServo.write(wristPitchPos);
  wristRollServo.write(wristRollPos);
  gripperServo.write(gripperPos);
  delay(10); // Slight delay for smoother motion
}

Try this project in your browser

Compile code and simulate hardware output with EltroNerd Cloud IDE.

Launch Cloud IDE