Overview
This robotic arm uses 6 MG996R servos to control:
- Base rotation
- Shoulder movement
- Elbow movement
- Wrist pitch
- Wrist roll
- 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:
Power Up:
- Servos are initialized and positioned to default angles (usually 90° for center).
- Bluetooth module starts listening for input over
SoftwareSerial.
User Command:
- You send a command like
2:130from a mobile Bluetooth terminal (e.g., Serial Bluetooth Terminal app). 2refers to the shoulder servo,130is the target angle.
- You send a command like
Command Parsing:
- The Arduino reads and parses the command.
- It identifies which servo to control and what angle to set.
Servo Actuation:
- The chosen servo moves to the specified angle using
servo.write(angle). - This continues in real-time as new commands are sent.
- The chosen servo moves to the specified angle using
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
#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
}