Robotic arm Arduino board
In this tutorial, we will learn how to make an Arduino robotic arm that can be wirelessly controlled and programmed using a custom Android app. I will show you the entire process of building it, from designing and 3D printing the robot parts, wiring up the electronics and programming the Arduino, to developing our own Android app for controlling the robotic arm.
You can watch the video below or read the written tutorial below.
Overview
Using the sliders in the app, we can manually control the movement of each servo or axis of the robot arm. Also using the “Save” button, we can record each position or step, and the robot arm can then run automatically and repeat these steps. Using the same button, we can pause the automatic operation as well as reset or delete all steps so that we can record new ones.
Arduino Robotic Arm 3D Model
First, I designed the robotic arm using Solidworks 3D modeling software. The arm has 5 degrees of freedom.
For the front 3 axes, i.e. waist, shoulder and elbow, I used MG996R servos, and for the other 2 axes, wrist roll and wrist pitch, and the gripper, I used smaller SG90 micro servos.
You can find and download this 3D model or explore it in the browser on Thangs:
Download the assembly 3D model from Thangs.
Thanks to Thangs for supporting this tutorial.
STL files for 3D printing:
Arduino Robot Arm 3D Model STEP File
3D Printing Robotic Arm
Using my new 3D printer, the Creality CR-10, I 3D printed all the parts for the Arduino robotic arm.
Here I want to give a shout out to Banggood.com for providing me with this awesome 3D printer. The print quality of the Creality CR-10 is amazing for its price, and another great thing about it is that it is almost 90% pre-assembled.
To complete the assembly we just need to connect the upper and lower component frames using some bolts and brackets and then connect the electronics with the control box using the provided cables.
Before trying, it is recommended to check if the rollers are tight enough, if not, you can simply tighten them using the eccentric nuts. That’s it, after leveling your 3D printing bed, you are ready to turn your 3D creations into reality.
It took me only a few hours to prepare all the parts for the Arduino robotic arm.
Read more: Top 15 Must-Have 3D Printer Accessories and Tools
Assembling the Robotic Arm
Ok, now we are ready to assemble the robot arm. I started by attaching the base of the first servo motor using the screws included in the package. I then fastened a fillet bolt to the output shaft of the servo.
On it I placed the upper part and fixed it with two screws.
Here again the servo goes first, then the fillet to the next section, then they are secured to each other using the bolts on the output shaft.
We can notice here that on the shoulder axis it would be better to include some kind of spring, or in my case I used a rubber band to give the servo some help since this servo also carries the entire weight of the rest of the arm as payload.
In a similar way, I continued to assemble the rest of the robot arm. As for the clamping mechanism, I used some 4mm bolts and nuts to assemble it.
Finally I connected the gripper mechanism to the last servo and the Arduino robotic arm was complete.
Arduino Robotic Arm Circuit Diagram
The next stage is to connect the electronics. The circuit diagram for this project is actually very simple. We only need an Arduino board and a HC-05 Bluetooth module to communicate with the smartphone. The control pins of the six servo motors are connected to the six digital pins of the Arduino board.
To power the servos we need 5V, but this has to come from an external power supply as the Arduino can’t handle the amount of current all of these can draw. The power supply must be able to handle at least 2A of current. So once we have everything connected together we can move on to programming the Arduino and making the Android app.
You can get the components required for this example from the following links:
- MG996R servo motor……………………………………..
- SG90 micro servo motor……………………………….
- HC-05 Bluetooth module…………………….
- Arduino development board…………………………………….
- 5V 2A DC power supply…………………….……..
Arduino Robotic Arm Code
Since the code is a bit long, for better understanding, I will post the source code of the program in sections, with explanations for each section. And I will post the complete source code at the end of the article.
So first we need to include the SoftwareSerial library for serial communication with the Bluetooth module as well as the Servo library. Both libraries are included with the Arduino IDE so you don’t have to install them externally. Then we need to define the six servos, the HC-05 Bluetooth module and some variables to store the current and previous positions of the servos, as well as an array to store the positions or steps for automatic mode.
#include <SoftwareSerial.h>
#include <Servo.h>
Servo servo01;
Servo servo02;
Servo servo03;
Servo servo04;
Servo servo05;
Servo servo06;
SoftwareSerial Bluetooth(3, 4); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)
int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // current position
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // previous position
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // for storing positions/steps
int speedDelay = 20;
int index = 0;
String dataIn = "";
Code language: Arduino (arduino)
In the setup section, we need to initialize the servos and the Bluetooth module and move the robotic arm to the initial position. We do this using the write() function, which simply moves the servo to any position between 0 and 180 degrees.
void setup() {
servo01.attach(5);
servo02.attach(6);
servo03.attach(7);
servo04.attach(8);
servo05.attach(9);
servo06.attach(10);
Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
Bluetooth.setTimeout(1);
delay(20);
// Robot arm initial position
servo1PPos = 90;
servo01.write(servo1PPos);
servo2PPos = 150;
servo02.write(servo2PPos);
servo3PPos = 35;
servo03.write(servo3PPos);
servo4PPos = 140;
servo04.write(servo4PPos);
servo5PPos = 85;
servo05.write(servo5PPos);
servo6PPos = 80;
servo06.write(servo6PPos);
}
Code language: Arduino (arduino)
Next, in the loop section, using the Bluetooth.available() function, we keep checking if there is any incoming data from the smartphone. If true, using the readString() function we read the data as a string and store it into the dataIn variable. Depending on the data that arrives, we tell the robotic arm what to do.
// Check for incoming data
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString(); // Read the data as string
Code language: Arduino (arduino)
Control Android Apps
Now let’s take a look at the Android application and see what kind of data it actually sends to the Arduino.
I made this app using the MIT App Inventor online app and this is how it works. There are two buttons on the top that are used to connect the smartphone to the HC-05 Bluetooth module. Then on the left we have an image of a robotic arm and on the right we have six sliders for controlling the servos and one slider for speed control.
Each slider has a different initial value, minimum value, and maximum value to suit the robot arm joints. At the bottom of the application, we have three buttons, SAVE, RUN, and RESET, through which we can program the robot arm to run automatically. There is also a label below that shows the number of steps we have saved. However, for more details on how to build such an application using MIT App Inventor, you can check out my other detailed tutorial.
Ok, now let’s look at the blocks behind the program or application. First, on the left we have the block for connecting the smartphone to the Bluetooth module.
Then we have the Slider block for the servo position control and the Button block for programming the robot arm. So if we change the position of a slider using the Bluetooth function .SendText we send text to the Arduino. This text contains a prefix indicating which slider has been changed and the current value of the slider.
Here are the downloads for the above MIT App Inventor project and the Android app ready to install on your smartphone:
Arduino Robotic Arm Control MIT App Inventor Project File
1 file24.85 KB Download
Arduino_Robot_Arm_Control
So, in Arduino, we use the startsWith() function to check the prefix of each incoming data, so we know what to do next. For example, if the prefix is ”s1″, we know we need to move the first servo. Using the substring() function we get the remaining text, which is the position value, which we convert to an integer and use that value to move the servo to that position.
// If "Waist" slider has changed value - Move Servo 1 to position
if (dataIn.startsWith("s1")) {
String dataInS = dataIn.substring(2, dataIn.length()); // Extract only the number. E.g. from "s1120" to "120"
servo1Pos = dataInS.toInt(); // Convert the string into integer
Code language: Arduino (arduino)
Here, we could simply call the write() function and the servo would go to that position, but this way the servo would run at maximum speed, which is too high for the robotic arm. Instead, we need to control the speed of the servo, so I used some FOR loops in order to gradually move the servo from the previous position to the current position by implementing a delay time between each iteration. By changing the delay time, the speed of the servo can be changed.
// We use for loops so we can control the speed of the servo
// If previous position is bigger then current position
if (servo1PPos > servo1Pos) {
for ( int j = servo1PPos; j >= servo1Pos; j--) { // Run servo down
servo01.write(j);
delay(20); // defines the speed at which the servo rotates
}
}
// If previous position is smaller then current position
if (servo1PPos < servo1Pos) {
for ( int j = servo1PPos; j <= servo1Pos; j++) { // Run servo up
servo01.write(j);
delay(20);
}
}
servo1PPos = servo1Pos; // set current position as previous position
}
Code language: Arduino (arduino)
The driving method of each axis of the robot arm is the same.
Below them is the “Save” button. If we press the SAVE button, the position of each servo motor is stored in an array. With each press the index increases, so the array is filled step by step.
// If button "SAVE" is pressed
if (dataIn.startsWith("SAVE")) {
servo01SP[index] = servo1PPos; // save position into the array
servo02SP[index] = servo2PPos;
servo03SP[index] = servo3PPos;
servo04SP[index] = servo4PPos;
servo05SP[index] = servo5PPos;
servo06SP[index] = servo6PPos;
index++; // Increase the array index
}
Code language: Arduino (arduino)
Then, if we press the RUN button, we call the runservo() custom function to run the stored steps. Let’s take a look at this function. So here we run the stored steps over and over again until we press the RESET button. Using a FOR loop, we iterate through all the positions stored in the array and at the same time we check if there is any incoming data from the smartphone. This data could be the RUN/PAUSE button, which pauses the robot and if clicked again, continues to move automatically. Also, if we change the position of the speed slider, we will use that value to change the delay time between each iteration in the FOR loop below, thus controlling the speed of the servo motor.
// Automatic mode custom function - run the saved steps
void runservo() {
while (dataIn != "RESET") { // Run the steps over and over again until "RESET" button is pressed
for (int i = 0; i <= index - 2; i++) { // Run through all steps(index)
if (Bluetooth.available() > 0) { // Check for incomding data
dataIn = Bluetooth.readString();
if ( dataIn == "PAUSE") { // If button "PAUSE" is pressed
while (dataIn != "RUN") { // Wait until "RUN" is pressed again
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString();
if ( dataIn == "RESET") {
break;
}
}
}
}
// If SPEED slider is changed
if (dataIn.startsWith("ss")) {
String dataInS = dataIn.substring(2, dataIn.length());
speedDelay = dataInS.toInt(); // Change servo speed (delay time)
}
}
// Servo 1
if (servo01SP[i] == servo01SP[i + 1]) {
}
if (servo01SP[i] > servo01SP[i + 1]) {
for ( int j = servo01SP[i]; j >= servo01SP[i + 1]; j--) {
servo01.write(j);
delay(speedDelay);
}
}
if (servo01SP[i] < servo01SP[i + 1]) {
for ( int j = servo01SP[i]; j <= servo01SP[i + 1]; j++) {
servo01.write(j);
delay(speedDelay);
}
}
Code language: Arduino (arduino)
In a similar way to these IF statements and FOR loops explained earlier, we move the servo to the next position. Finally, if we press the RESET button, we zero out all the data in the array and reset the index to zero so that we can reprogram the robot arm with a new movement.
// If button "RESET" is pressed
if ( dataIn == "RESET") {
memset(servo01SP, 0, sizeof(servo01SP)); // Clear the array data to 0
memset(servo02SP, 0, sizeof(servo02SP));
memset(servo03SP, 0, sizeof(servo03SP));
memset(servo04SP, 0, sizeof(servo04SP));
memset(servo05SP, 0, sizeof(servo05SP));
memset(servo06SP, 0, sizeof(servo06SP));
index = 0; // Index to 0
}
Code language: Arduino (arduino)
That’s it, now we can enjoy the robotic arm.
Here is the complete code for the Arduino robotic arm:
/*
DIY Arduino Robot Arm Smartphone Control
by Dejan, www.HowToMechatronics.com
*/
#include <SoftwareSerial.h>
#include <Servo.h>
Servo servo01;
Servo servo02;
Servo servo03;
Servo servo04;
Servo servo05;
Servo servo06;
SoftwareSerial Bluetooth(3, 4); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)
int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // current position
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // previous position
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // for storing positions/steps
int speedDelay = 20;
int index = 0;
String dataIn = "";
void setup() {
servo01.attach(5);
servo02.attach(6);
servo03.attach(7);
servo04.attach(8);
servo05.attach(9);
servo06.attach(10);
Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
Bluetooth.setTimeout(1);
delay(20);
// Robot arm initial position
servo1PPos = 90;
servo01.write(servo1PPos);
servo2PPos = 150;
servo02.write(servo2PPos);
servo3PPos = 35;
servo03.write(servo3PPos);
servo4PPos = 140;
servo04.write(servo4PPos);
servo5PPos = 85;
servo05.write(servo5PPos);
servo6PPos = 80;
servo06.write(servo6PPos);
}
void loop() {
// Check for incoming data
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString(); // Read the data as string
// If "Waist" slider has changed value - Move Servo 1 to position
if (dataIn.startsWith("s1")) {
String dataInS = dataIn.substring(2, dataIn.length()); // Extract only the number. E.g. from "s1120" to "120"
servo1Pos = dataInS.toInt(); // Convert the string into integer
// We use for loops so we can control the speed of the servo
// If previous position is bigger then current position
if (servo1PPos > servo1Pos) {
for ( int j = servo1PPos; j >= servo1Pos; j--) { // Run servo down
servo01.write(j);
delay(20); // defines the speed at which the servo rotates
}
}
// If previous position is smaller then current position
if (servo1PPos < servo1Pos) {
for ( int j = servo1PPos; j <= servo1Pos; j++) { // Run servo up
servo01.write(j);
delay(20);
}
}
servo1PPos = servo1Pos; // set current position as previous position
}
// Move Servo 2
if (dataIn.startsWith("s2")) {
String dataInS = dataIn.substring(2, dataIn.length());
servo2Pos = dataInS.toInt();
if (servo2PPos > servo2Pos) {
for ( int j = servo2PPos; j >= servo2Pos; j--) {
servo02.write(j);
delay(50);
}
}
if (servo2PPos < servo2Pos) {
for ( int j = servo2PPos; j <= servo2Pos; j++) {
servo02.write(j);
delay(50);
}
}
servo2PPos = servo2Pos;
}
// Move Servo 3
if (dataIn.startsWith("s3")) {
String dataInS = dataIn.substring(2, dataIn.length());
servo3Pos = dataInS.toInt();
if (servo3PPos > servo3Pos) {
for ( int j = servo3PPos; j >= servo3Pos; j--) {
servo03.write(j);
delay(30);
}
}
if (servo3PPos < servo3Pos) {
for ( int j = servo3PPos; j <= servo3Pos; j++) {
servo03.write(j);
delay(30);
}
}
servo3PPos = servo3Pos;
}
// Move Servo 4
if (dataIn.startsWith("s4")) {
String dataInS = dataIn.substring(2, dataIn.length());
servo4Pos = dataInS.toInt();
if (servo4PPos > servo4Pos) {
for ( int j = servo4PPos; j >= servo4Pos; j--) {
servo04.write(j);
delay(30);
}
}
if (servo4PPos < servo4Pos) {
for ( int j = servo4PPos; j <= servo4Pos; j++) {
servo04.write(j);
delay(30);
}
}
servo4PPos = servo4Pos;
}
// Move Servo 5
if (dataIn.startsWith("s5")) {
String dataInS = dataIn.substring(2, dataIn.length());
servo5Pos = dataInS.toInt();
if (servo5PPos > servo5Pos) {
for ( int j = servo5PPos; j >= servo5Pos; j--) {
servo05.write(j);
delay(30);
}
}
if (servo5PPos < servo5Pos) {
for ( int j = servo5PPos; j <= servo5Pos; j++) {
servo05.write(j);
delay(30);
}
}
servo5PPos = servo5Pos;
}
// Move Servo 6
if (dataIn.startsWith("s6")) {
String dataInS = dataIn.substring(2, dataIn.length());
servo6Pos = dataInS.toInt();
if (servo6PPos > servo6Pos) {
for ( int j = servo6PPos; j >= servo6Pos; j--) {
servo06.write(j);
delay(30);
}
}
if (servo6PPos < servo6Pos) {
for ( int j = servo6PPos; j <= servo6Pos; j++) {
servo06.write(j);
delay(30);
}
}
servo6PPos = servo6Pos;
}
// If button "SAVE" is pressed
if (dataIn.startsWith("SAVE")) {
servo01SP[index] = servo1PPos; // save position into the array
servo02SP[index] = servo2PPos;
servo03SP[index] = servo3PPos;
servo04SP[index] = servo4PPos;
servo05SP[index] = servo5PPos;
servo06SP[index] = servo6PPos;
index++; // Increase the array index
}
// If button "RUN" is pressed
if (dataIn.startsWith("RUN")) {
runservo(); // Automatic mode - run the saved steps
}
// If button "RESET" is pressed
if ( dataIn == "RESET") {
memset(servo01SP, 0, sizeof(servo01SP)); // Clear the array data to 0
memset(servo02SP, 0, sizeof(servo02SP));
memset(servo03SP, 0, sizeof(servo03SP));
memset(servo04SP, 0, sizeof(servo04SP));
memset(servo05SP, 0, sizeof(servo05SP));
memset(servo06SP, 0, sizeof(servo06SP));
index = 0; // Index to 0
}
}
}
// Automatic mode custom function - run the saved steps
void runservo() {
while (dataIn != "RESET") { // Run the steps over and over again until "RESET" button is pressed
for (int i = 0; i <= index - 2; i++) { // Run through all steps(index)
if (Bluetooth.available() > 0) { // Check for incomding data
dataIn = Bluetooth.readString();
if ( dataIn == "PAUSE") { // If button "PAUSE" is pressed
while (dataIn != "RUN") { // Wait until "RUN" is pressed again
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString();
if ( dataIn == "RESET") {
break;
}
}
}
}
// If speed slider is changed
if (dataIn.startsWith("ss")) {
String dataInS = dataIn.substring(2, dataIn.length());
speedDelay = dataInS.toInt(); // Change servo speed (delay time)
}
}
// Servo 1
if (servo01SP[i] == servo01SP[i + 1]) {
}
if (servo01SP[i] > servo01SP[i + 1]) {
for ( int j = servo01SP[i]; j >= servo01SP[i + 1]; j--) {
servo01.write(j);
delay(speedDelay);
}
}
if (servo01SP[i] < servo01SP[i + 1]) {
for ( int j = servo01SP[i]; j <= servo01SP[i + 1]; j++) {
servo01.write(j);
delay(speedDelay);
}
}
// Servo 2
if (servo02SP[i] == servo02SP[i + 1]) {
}
if (servo02SP[i] > servo02SP[i + 1]) {
for ( int j = servo02SP[i]; j >= servo02SP[i + 1]; j--) {
servo02.write(j);
delay(speedDelay);
}
}
if (servo02SP[i] < servo02SP[i + 1]) {
for ( int j = servo02SP[i]; j <= servo02SP[i + 1]; j++) {
servo02.write(j);
delay(speedDelay);
}
}
// Servo 3
if (servo03SP[i] == servo03SP[i + 1]) {
}
if (servo03SP[i] > servo03SP[i + 1]) {
for ( int j = servo03SP[i]; j >= servo03SP[i + 1]; j--) {
servo03.write(j);
delay(speedDelay);
}
}
if (servo03SP[i] < servo03SP[i + 1]) {
for ( int j = servo03SP[i]; j <= servo03SP[i + 1]; j++) {
servo03.write(j);
delay(speedDelay);
}
}
// Servo 4
if (servo04SP[i] == servo04SP[i + 1]) {
}
if (servo04SP[i] > servo04SP[i + 1]) {
for ( int j = servo04SP[i]; j >= servo04SP[i + 1]; j--) {
servo04.write(j);
delay(speedDelay);
}
}
if (servo04SP[i] < servo04SP[i + 1]) {
for ( int j = servo04SP[i]; j <= servo04SP[i + 1]; j++) {
servo04.write(j);
delay(speedDelay);
}
}
// Servo 5
if (servo05SP[i] == servo05SP[i + 1]) {
}
if (servo05SP[i] > servo05SP[i + 1]) {
for ( int j = servo05SP[i]; j >= servo05SP[i + 1]; j--) {
servo05.write(j);
delay(speedDelay);
}
}
if (servo05SP[i] < servo05SP[i + 1]) {
for ( int j = servo05SP[i]; j <= servo05SP[i + 1]; j++) {
servo05.write(j);
delay(speedDelay);
}
}
// Servo 6
if (servo06SP[i] == servo06SP[i + 1]) {
}
if (servo06SP[i] > servo06SP[i + 1]) {
for ( int j = servo06SP[i]; j >= servo06SP[i + 1]; j--) {
servo06.write(j);
delay(speedDelay);
}
}
if (servo06SP[i] < servo06SP[i + 1]) {
for ( int j = servo06SP[i]; j <= servo06SP[i + 1]; j++) {
servo06.write(j);
delay(speedDelay);
}
}
}
}
}
Code language: Arduino (arduino)
I hope you enjoyed this video and learned something new. Feel free to ask any questions in the comments section below and check out my Arduino Projects collection.