6DOF Robot Arm

Here we are going to make a 6 DOF or degrees of freedom arm robot. We need to understand first on how degrees of freedom is calculated.

Six degrees of freedom (6DoF) is also referred as the movement of a rigid body in three-dimensional space. It can commonly be attributed to yaw as the normal axis, pitch as transverse axis, and roll as the longitudinal axis.

Parts List

Components that was used for this build.


Installation

Screw the servo motor to the base

The 3D Parts


Connecting Everything:

Connect the Bluetooth Module to the D2, D3, GND, and 5V pins of Arduino on top of GPIO Expansion shield.

Add a wire to our DC jack adapter, tighten the screw with a screwdriver. We will use this for the input power of our robot arm.

Connect the DC Jack Adapter to GPIO Expansion Shield power terminal.

Lastly connect all the Servo motor to arduino.
*for the servo 1 connect it to D9, Gnd, 5V
*for the servo 2 connect it to the D5,Gnd,5v
*for the servo 3 connect it to the D6,Gnd,5V
*for the servo 4 connect it to the D10,Gnd,5V and
*for the servo 5 connect it to the D11,Gnd,5V of arduino


Powering-Up

Schematic Diagram

See this schematic Diagram to double check your wirings.

Code:

Arduino

First you need to Setup the Name, Pin, and the Baudrate of your Bluetooth Module


#include <SoftwareSerial.h>

SoftwareSerial hc06(2,3); //Rx, Tx

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  hc06.begin(9600);
  Serial.println("Enter AT commands:");
  
}

void loop() {
  // put your main code here, to run repeatedly:

  if (hc06.available()){
    Serial.write(hc06.read());
  }
  
  //Write from Serial Monitor to HC06
  if (Serial.available()){
    hc06.write(Serial.read());
  }  

  //need to set up to more information check this link  https://www.aranacorp.com/en/arduino-and-bluetooth-module-hc-06/
  //AT COMMAND
  //AT+NAMEROBOTARMBLE     = to set your bluetooth name to ROBOTARMBLE
  //AT+PIN0000             = to set your pin to 0000
  //AT+BAUD8   = baud to 115200   = to set the baudrate of your bluetooth to 115200
}

Time to upload your code to your Arduino Uno.


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

SoftwareSerial hc06(2,3); //Rx, Tx

Servo myservo;
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;

String cmd="";
String serId = "";
String serVal = "";


int serval0 = 90;
int serval1 = 90;
int serval2 = 90;
int serval3 = 90;
int serval4 = 40;

void setup() {
  Serial.begin(115200);
  hc06.begin(115200);
  
  myservo.attach(9);
  myservo1.attach(5);
  myservo2.attach(6);
  myservo3.attach(10);
  myservo4.attach(11);

  myservo.write(90);
  myservo1.write(90);
  myservo2.write(90);
  myservo3.write(90);
  myservo4.write(40);
}

void loop() {
  
  while(hc06.available()>0){
    cmd += (char)hc06.read();
    cmd.trim();
  }
  
  char *serIdChar = strtok(&cmd[0], ",");
  char *serValChar = strtok(NULL, ",");

  serId = serIdChar;
  serVal = serValChar;

  if(cmd!= ""){
    Serial.println(cmd);
    Serial.println(serId);
    Serial.println(serVal);
    if(serId == "0"){
      if(serval0 > serVal.toInt()){
        for(int iter = serval0; iter > serVal.toInt()+1; iter--){
          myservo.write(iter); 
          Serial.println(iter);
          delay(10);
        }
      }else{
        for(int iter = serval0; iter < serVal.toInt(); iter++){
          myservo.write(iter); 
          Serial.println(iter);
          delay(10);
        }  
      }
      
      serval0 = serVal.toInt();
    Serial.println(serval0);
    }else if(serId == "1"){
        if(serval1 > serVal.toInt()){
        for(int iter = serval1; iter > serVal.toInt()+1; iter--){
          myservo1.write(iter); 
          Serial.println(iter);
          delay(10);
        }
      }else{
        for(int iter = serval1; iter < serVal.toInt(); iter++){
          myservo1.write(iter); 
          Serial.println(iter);
          delay(10);
        }  
      }
      
      serval1 = serVal.toInt();
    Serial.println(serval1);
    
    }else if(serId == "2"){
        if(serval2 > serVal.toInt()){
        for(int iter = serval2; iter > serVal.toInt()+1; iter--){
          myservo2.write(iter); 
          Serial.println(iter);
          delay(10);
        }
      }else{
        for(int iter = serval2; iter < serVal.toInt(); iter++){
          myservo2.write(iter); 
          Serial.println(iter);
          delay(10);
        }  
      }
      
      serval2 = serVal.toInt();
    Serial.println(serval2);
    }else if(serId == "3"){
        myservo3.write(serVal.toInt());
    }else if(serId == "4"){
        int serArm = map(serVal.toInt(),0,90,40,90);
        myservo4.write(serArm);
    }
    cmd="";
    serId="";
    serVal="";
  }
    
}

Android Studio

we do the app using Android Studio. first you need to create a Basic Activity in Android Studio then add the following code.

See also  8-Channel Relay Testing via Arduino


Layout: activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main"/>

    <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"
            android:src="@drawable/ic_bluetooth_black_24dp"
            app:backgroundTint="@color/colorBlack"/>

</android.support.design.widget.CoordinatorLayout>

Layout: content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:showIn="@layout/activity_main"
        tools:context=".MainActivity"
        android:background="@drawable/bg">

    <!--<com.ramotion.fluidslider.FluidSlider-->
            <!--android:id="@+id/fluidSlider"-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="wrap_content"-->
            <!--android:layout_marginEnd="16dp"-->
            <!--android:layout_marginStart="16dp"-->
            <!--android:elevation="2dp"-->
            <!--app:layout_constraintBottom_toBottomOf="parent"-->
            <!--app:layout_constraintEnd_toEndOf="parent"-->
            <!--app:layout_constraintStart_toStartOf="parent"-->
            <!--app:layout_constraintTop_toTopOf="parent"-->
            <!--app:size="small"-->
            <!--app:duration="@android:integer/config_mediumAnimTime"-->
            <!--tools:targetApi="lollipop" />-->

    <LinearLayout android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:gravity="center"
                  android:orientation="vertical">


        <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/custom_seekbar_progress"
                android:thumb="@drawable/custom_seekbar_thumb"
                android:max="90"
                android:progress="0"
                android:padding="20dp"
                android:id="@+id/seekBararm"/>

        <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/custom_seekbar_progress"
                android:thumb="@drawable/custom_seekbar_thumb"
                android:max="180"
                android:progress="90"
                android:padding="20dp"
                android:id="@+id/seekBarancle"/>

        <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/custom_seekbar_progress"
                android:thumb="@drawable/custom_seekbar_thumb"
                android:max="180"
                android:progress="90"
                android:padding="20dp"
                android:id="@+id/seekBarelbow"/>

        <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/custom_seekbar_progress"
                android:thumb="@drawable/custom_seekbar_thumb"
                android:max="180"
                android:progress="90"
                android:padding="20dp"
                android:id="@+id/seekBarafterBase"/>
        <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/custom_seekbar_progress"
                android:thumb="@drawable/custom_seekbar_thumb"
                android:max="180"
                android:progress="90"
                android:padding="20dp"
                android:id="@+id/seekBarbase"/>

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

create a custom_seekbar_progress.xml to your drawable

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background"
          android:gravity="center_vertical|fill_horizontal">
        <shape android:shape="rectangle"
               android:tint="#000000">
            <corners android:radius="8dp"/>
            <size android:height="30dp" />
            <solid android:color="#000000" />
        </shape>
    </item>
    <item android:id="@android:id/progress"
          android:gravity="center_vertical|fill_horizontal">
        <scale android:scaleWidth="100%">
            <selector>
                <item android:state_enabled="false"
                      android:drawable="@android:color/transparent" />
                <item>
                    <shape android:shape="rectangle"
                           android:tint="#000000">
                        <corners android:radius="8dp"/>
                        <size android:height="30dp" />
                        <solid android:color="#000000" />
                    </shape>
                </item>
            </selector>
        </scale>
    </item>
</layer-list>

also create custom_seekbar_thumb.xml to your drawable

<?xml version="1.0" encoding="utf-8"?>
<shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle"
        android:thickness="4dp"
        android:useLevel="false"
        android:tint="#7ddcff">
    <solid
            android:color="#7ddcff" />
    <size
            android:width="32dp"
            android:height="32dp" />
</shape>

also create ic_bluetooth_black_24dp.xml to your drawable

<vector android:height="24dp" android:tint="#ffffff"
    android:viewportHeight="24.0" android:viewportWidth="24.0"
    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FF000000" android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/>
</vector>

and last create ic_bluetooth_connected_black_24dp.xml to your drawable

<vector android:height="24dp" android:tint="#0F03FF"
    android:viewportHeight="24.0" android:viewportWidth="24.0"
    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FF000000" android:pathData="M7,12l-2,-2 -2,2 2,2 2,-2zM17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88zM19,10l-2,2 2,2 2,-2 -2,-2z"/>
</vector>

Add this code to values > colors.xml

    <color name="colorBlack">#000000</color>

java: MainActivity.java

package com.project.robotarm;

import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SeekBar;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private SeekBar seekBarBase;
    private SeekBar seekBar1;
    private SeekBar seekBar2;
    private SeekBar seekBar3;
    private SeekBar seekBar4;

    private String dataToSend;
    private String TAG = "DEBUG";
    private BluetoothAdapter myBluetooth = null;

    private static String address = "98:D3:31:F6:1B:DB"; //address of your bluetooth module. to check the address of your bluetooth module first pair it with your android phone then check the address of the bluetooth module
    private ProgressDialog progress;
    BluetoothSocket btSocket = null;
    private boolean isBtConnected = false;
    private boolean isConnected = false;
    static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private OutputStream outStream = null;
    private InputStream inStream = null;
    Handler handler = new Handler();
    byte delimiter = 10;
    boolean stopWorker = false;
    int readBufferPosition = 0;
    byte[] readBuffer = new byte[1024];

    FloatingActionButton fab;
    @Override
    protected void onCreate( Bundle savedInstanceState ) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );
        Toolbar toolbar = findViewById( R.id.toolbar );
        setSupportActionBar( toolbar );

        seekBarBase = findViewById( R.id.seekBarbase );
        seekBar1 = findViewById( R.id.seekBarafterBase );
        seekBar2 = findViewById( R.id.seekBarelbow );
        seekBar3 = findViewById( R.id.seekBarancle );
        seekBar4 = findViewById( R.id.seekBararm );

        fab = findViewById( R.id.fab );
        fab.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick( View view ) {

                myBluetooth = BluetoothAdapter.getDefaultAdapter();
                if(myBluetooth == null)
                {
                    //Show a mensag. that thedevice has no bluetooth adapter
                    Toast.makeText(getApplicationContext(), "Bluetooth Device Not Available", Toast.LENGTH_LONG).show();
                    //finish apk
                    finish();
                }else
                {
                    if (myBluetooth.isEnabled())
                    {
                        Log.d( TAG, "Bluetooth is enable" );
                        if(isConnected){
                            Disconnect();
                        }else{
                            ConnectBT connectBT = new ConnectBT();
                            connectBT.execute( );
                        }

                    }
                    else
                    {
                        //Ask to the user turn the bluetooth on
                        Intent turnBTon = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(turnBTon,1);
                    }
                }

            }
        } );
        seekBar4.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() {
            int progress= 0;
            @Override
            public void onProgressChanged( SeekBar seekBar, int i, boolean b ) {
                progress=i;
            }

            @Override
            public void onStartTrackingTouch( SeekBar seekBar ) {

            }

            @Override
            public void onStopTrackingTouch( SeekBar seekBar ) {
                dataToSend = "4,"+Integer.toString( progress );
                writeData(dataToSend);
            }
        } );
        seekBar3.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() {
            int progress = 0;
            @Override
            public void onProgressChanged( SeekBar seekBar, int i, boolean b ) {
                progress=i;
            }

            @Override
            public void onStartTrackingTouch( SeekBar seekBar ) {

            }

            @Override
            public void onStopTrackingTouch( SeekBar seekBar ) {
                dataToSend = "3,"+Integer.toString( progress );
                writeData(dataToSend);
            }
        } );
        seekBar2.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() {
            int progress = 0;
            @Override
            public void onProgressChanged( SeekBar seekBar, int i, boolean b ) {
                progress = i;
            }

            @Override
            public void onStartTrackingTouch( SeekBar seekBar ) {

            }

            @Override
            public void onStopTrackingTouch( SeekBar seekBar ) {
                dataToSend = "2,"+Integer.toString( progress );
                writeData(dataToSend);
            }
        } );
        seekBar1.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() {
            int progress = 0;
            @Override
            public void onProgressChanged( SeekBar seekBar, int i, boolean b ) {
                progress = i;
            }

            @Override
            public void onStartTrackingTouch( SeekBar seekBar ) {

            }

            @Override
            public void onStopTrackingTouch( SeekBar seekBar ) {
                dataToSend = "1,"+Integer.toString( progress );
                writeData(dataToSend);
            }
        } );


        seekBarBase.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() {
            int progress = 0;
            @Override
            public void onProgressChanged( SeekBar seekBar, int i, boolean b ) {
                progress = i;
                msg( "Changing seekbar's progress" );
            }

            @Override
            public void onStartTrackingTouch( SeekBar seekBar ) {
                msg( "Started tracking seekbar" );
            }

            @Override
            public void onStopTrackingTouch( SeekBar seekBar ) {
                dataToSend = "0,"+Integer.toString( progress );
                writeData(dataToSend);
                msg( "Stopped tracking seekbar" );
            }
        } );
    }

    private void writeData(String data) {
        try {
            outStream = btSocket.getOutputStream();
        } catch (IOException e) {
            Log.d(TAG, "Bug BEFORE Sending stuff", e);
        }

        String message = data;
        byte[] msgBuffer = message.getBytes();

        try {
            outStream.write(msgBuffer);
        } catch (IOException e) {
            Log.d(TAG, "Bug while sending stuff", e);
        }
    }

    private void Disconnect()
    {
        if (btSocket!=null) //If the btSocket is busy
        {
            try
            {
                msg( "Bluetooth Disconnect" );
                btSocket.close(); //close connection
                btSocket = null;
                fab.setImageResource( R.drawable.ic_bluetooth_black_24dp );
                isConnected = false;
            }
            catch (IOException e)
            { msg("Error");}
        }
//        finish(); //return to the first layout
    }

    private void msg(String s)
    {
        Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onCreateOptionsMenu( Menu menu ) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate( R.menu.menu_main, menu );
        return true;
    }

    @Override
    public boolean onOptionsItemSelected( MenuItem item ) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if( id == R.id.action_settings ) {
            return true;
        }

        return super.onOptionsItemSelected( item );
    }


    private class ConnectBT extends AsyncTask<Void, Void, Void>  // UI thread
    {
        private boolean ConnectSuccess = true; //if it's here, it's almost connected

        @Override
        protected void onPreExecute()
        {
            progress = ProgressDialog.show(MainActivity.this, "Connecting...", "Please wait!!!");  //show a progress dialog
        }

        @Override
        protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
        {
            try
            {
                if (btSocket == null || !isBtConnected)
                {
                    myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
                    BluetoothDevice device = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
                    btSocket = device.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
                    BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                    btSocket.connect();//start connection
                }
            }
            catch ( IOException e)
            {
                ConnectSuccess = false;//if the try failed, you can check the exception here
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
        {
            super.onPostExecute(result);

            if (!ConnectSuccess)
            {
                msg("Connection Failed. Check the address of your BLE if it is"+address+", if not the same contact the developer. \nOr Is it a SPP Bluetooth? Try again. ");
//                finish();
            }
            else
            {
                msg("Connected.");
                isBtConnected = true;
                beginListenForData();
                fab.setImageResource( R.drawable.ic_bluetooth_connected_black_24dp );
                isConnected = true;

            }
            progress.dismiss();
        }
    }


    public void beginListenForData()   {
        try {
            inStream = btSocket.getInputStream();
        } catch (IOException e) {
        }

        Thread workerThread = new Thread(new Runnable()
        {
            public void run()
            {
                while(!Thread.currentThread().isInterrupted() && !stopWorker)
                {
                    try
                    {
                        int bytesAvailable = inStream.available();
                        if(bytesAvailable > 0)
                        {
                            byte[] packetBytes = new byte[bytesAvailable];
                            inStream.read(packetBytes);

                            for(int i=0;i<bytesAvailable;i++)
                            {
                                byte b = packetBytes[i];
                                char ch = (char)b;

                                Log.i("DEBUG", Character.toString( ch ));


                            }
                        }
                    }
                    catch (IOException ex)
                    {
                        stopWorker = true;
                        Log.d( "DEBUG", "WORKERS: Stop WORKERS TRUE" );
                    }
                }
            }
        });

        workerThread.start();
    }

}

Manifests: AndroidManifest.xml

Add this 2 permission to your Manifest:

<uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>