Project showcase
Robotic arm playing tic tac toe controlled by Arduino

Robotic arm playing tic tac toe controlled by Arduino © GPL3+

It is about a robotic arm of 3dof + 1 controlled by arduino and visual basic that plays tic tac toe game against a human player.

  • 4,822 views
  • 9 comments
  • 27 respects

Components and supplies

About this project

Materials:

  • (1) Robotic arm with gripper.
  • (1) Web cam.
  • (1) Arduino One.
  • (1) Board of 3 x 3 squares.
  • Red and white pieces.

The web cam is for the image capture of the board. The image is analyzed by a visual basic program and using the minimax algorithm decides where the computer must place it´s piece. The program sends commands to the arduino one and this moves the robotic arm to the chosen position by the algorithm.


1- THE ROBOTIC ARM

I bought the robotic arm here but you can build your own robot.

This robotic arm contains of 3 servos S3003, 1 for the base, 1 for the shoulder and 1 for the wrist. Also uses a servo sg90 for the gripper.

It is controlled by the Arduino One which is commanded by a visual basic program.


2 - THE DIAGRAM

As shown in the first step, 4 servos are connected to the pins 5,6,9 and 10 of the arduino one.



3 - THE IMAGE CAPTURE

The web cam captures the image of the board and through a procedure in the visual basic program (you have to install the web cam library) , the image is divided into nine squares and each square is traveled for determining if contains red pixels. If so, the pixel is marked with red and later if the amount of points red of the square is greater than 60, then there is a red piece in that square and is interpreted with a "X", which is the movement of the human player.

4 - THE LOGIC OF THE GAME The visual basic program determines the position of the computer thanks to an algorithm called miniMax, which is an algorithm used in games of two players and helps to decide the best movement for the computer turn. Click here for downloading the full code in visual basic of the project. Note: the source code of the minimax algorithm used in the program was written by Ralph Main, you can see the article here.


5 - THE MOVEMENT OF THE ARM When the Artificial Intelligence of the minimax algorithm decides in which position the piece must be placed, it sends a string with the number of that position to the arduino through the serial port. The arduino receives the data and according to the position calls to the function that contains the movements in angles for moving the robotic arm. Example of code for moving the arm to the second square: 

if (dato=='2') 
{ segundaPosicion() } ...... //Move the base for(i=180;i>=88;i--)
 { base.write(i); delay(20); }
 delay(200); 
//Moves the wrist to 90 
for(i=114;i>=90;i--)
 {
 codo.write(i);
 delay(20);
 }
 delay(200);
 //Moves the shoulder to 160
 for(i=140;i<=170;i++)
 {
 hombro.write(i);
 delay(20);
 }
 delay(200); 
//Moves the wrist for(i=90;i<=102;i++)
 { codo.write(i); delay(20);
 }
 delay(200); 
//Open the gripper for(i=110;i>=90;i--)
 { 
pinza.write(i);
 delay(20);
 } 
delay(200);
 //Lifts the shoulder 
for(i=170;i>=140;i--) 
{ 
hombro.write(i); 
delay(20); 
} 
delay(200); 
posicionInicial(); //Moves to its initial position }


Download the full Arduino code here. Thanks for watching, comments, suggestions, please let me know it.

Code

Arduino codeArduino
#include <Servo.h>
int i,j;

Servo base;
Servo hombro;
Servo codo;
Servo pinza;

int angulo=0;
char dato;

int anguloBase;
int anguloHombro;
int anguloCodo;
int anguloPinza;
int anguloAgarrePinza;


  void setup() 
  {
    Serial.begin(9600);
    
     
    base.attach(5);
    hombro.attach(6);
    codo.attach(9);
    pinza.attach(10);

    anguloBase=90;
    anguloHombro=90;
    anguloCodo=90;
    anguloPinza=70;
    anguloAgarrePinza=130;
    
    
    base.write(90);
    delay(300);
    hombro.write(90);
    delay(300);
    codo.write(90);
    delay(300);
    pinza.write(70);
    delay(300);
    
    
  }
void girarBaseDerecha()
{
  anguloBase=anguloBase+2;
  base.write(anguloBase);
}

void girarBaseIzquierda()
{
  anguloBase = anguloBase-2;
  base.write(anguloBase);
}

void subirHombro()
{
  anguloHombro=anguloHombro-2;
  hombro.write(anguloHombro);
  Serial.println(anguloHombro);  
}
void bajarHombro()
{
  anguloHombro=anguloHombro+2;
  hombro.write(anguloHombro);
  Serial.println(anguloHombro);  
}

void levantarCodo()
{
  anguloCodo=anguloCodo+2;
  codo.write(anguloCodo);
}

void bajarCodo()
{
  anguloCodo=anguloCodo-2;
  codo.write(anguloCodo);
}

void abrirPinza()
{
  anguloPinza=anguloPinza-5;
  pinza.write(anguloPinza);
}

void cerrarPinza()
{
  anguloPinza=anguloPinza+5;
  pinza.write(anguloPinza);
}

void posicionInicial()
{
  for(i=90;i<=180;i++)
  {
    base.write(i);
  }  
  delay(300);
  hombro.write(90);
  delay(300);
  codo.write(90);
  delay(300);
  pinza.write(70);
}

void recogerFicha()
{
  for(i=90;i<=174;i++)
  {
    hombro.write(i);
    delay(20);
  }  
  delay(200);
  
  for(i=90;i<=114;i++)
  {
    codo.write(i);
        delay(20);
  }  
  delay(200);
  
  for(i=70;i<=anguloAgarrePinza;i++)
  {
    pinza.write(i);
    delay(20);
  }
  delay(200);
  
  for(i=176;i>=140;i--)
  {
    hombro.write(i);
        delay(20);
  }    
}
//************************************************************************++
void primeraPosicion()
{
   for(i=180;i>=92;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=140;i<=170;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=114;i<=124;i++)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=170;i<=176;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=124;i<=130;i++)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=105;i>=70;i--)
  {
    pinza.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=176;i>=140;i--);
  {
    hombro.write(i);
    delay(20);
  }
  
  posicionInicial();
  
}


void segundaPosicion()
{
  //Muevo la base
  for(i=180;i>=88;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);

  //Muevo el codo hasta 90
  for(i=114;i>=90;i--)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);


  //Muevo el hombro  hasta 160
  for(i=140;i<=170;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);

//Muevo el codo  
  for(i=90;i<=102;i++)
  {
    codo.write(i);
    delay(20);
  }  
  
  delay(200);
    
  //Abro la pinza
  for(i=110;i>=90;i--)
  {
    pinza.write(i);
    delay(20);
  }

  delay(200);

  //Subo el hombro  
  for(i=170;i>=140;i--)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  posicionInicial();
  
}

void terceraPosicion()
{
  //Muevo la base hasta los 90 grados
  for(i=180;i>=90;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);
  
   //Muevo el codo hasta los 70 grados
  for(i=114;i>=70;i--)
  {
    codo.write(i);
    delay(20);
  }
  
  //Muevo el hombro hasta 170 grados
  for(i=140;i<=170;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
   //Muevo el codo hasta los 80 grados
  for(i=70;i<=80;i++)
  {
    codo.write(i);
    delay(20);
  }
   
  delay(200);
  
  //Abro la pinza  
  for(i=105;i>=70;i--)
  {
    pinza.write(i);
    delay(20);
  }
  
  delay(200);
    
  for(i=170;i>=140;i--);
  {
    hombro.write(i);
    delay(20);
  }
  
  posicionInicial();
  
}


void cuartaPosicion()
{
  //Muevo la base
  for(i=180;i>=104;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);

  //Muevo el hombro  
  for(i=140;i<=172;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el codo  
  for(i=114;i<=122;i++)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
    
 //Muevo el hombro  
  for(i=172;i<=176;i++)
  {
    hombro.write(i);
    delay(20);
  } 
  
  delay(200);

//Muevo el codo  
  for(i=122;i<=132;i++)
  {
    codo.write(i);
    delay(20);
  }  
  
  delay(200);
    
  //Abro la pinza
  for(i=110;i>=90;i--)
  {
    pinza.write(i);
    delay(20);
  }

  delay(200);

  //Subo el hombro  
  for(i=170;i>=140;i--)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  posicionInicial();
  
}

void quintaPosicion()
{
  //Muevo la base 
  for(i=180;i>=106;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el codo
  for(i=114;i>=104;i--)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el hombro
  for(i=140;i<=170;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
   
  for(i=105;i>=70;i--)
  {
    pinza.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=170;i>=140;i--);
  {
    hombro.write(i);
    delay(20);
  }
  
  posicionInicial();
  
}

void sextaPosicion()
{
  //Muevo la base 
  for(i=180;i>=108;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el codo
  for(i=114;i>=74;i--)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el hombro
  for(i=140;i<=160;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
   
  for(i=105;i>=70;i--)
  {
    pinza.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=160;i>=140;i--);
  {
    hombro.write(i);
    delay(20);
  }
  
  posicionInicial();
  
}


void septimaPosicion()
{
  //Muevo la base
  for(i=180;i>=116;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);

  //Muevo el hombro  
  for(i=140;i<=164;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el codo  
  for(i=114;i<=120;i++)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
    
 //Muevo el hombro  
  for(i=164;i<=172;i++)
  {
    hombro.write(i);
    delay(20);
  } 
  
  delay(200);

//Muevo el codo  
  for(i=120;i<=138;i++)
  {
    codo.write(i);
    delay(20);
  }  
  
  delay(200);
    
  //Abro la pinza
  for(i=110;i>=90;i--)
  {
    pinza.write(i);
    delay(20);
  }

  delay(200);

  //Subo el hombro  
  for(i=172;i>=140;i--)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  posicionInicial();
  
}

void octavaPosicion()
{
  //Muevo la base hasta los 120 grados
  for(i=180;i>=120;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el hombro hasta los 170 grados
  for(i=140;i<=170;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el codo hasta los 94 grados
  for(i=114;i>=112;i--)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Abro la pinza  
  for(i=anguloAgarrePinza;i>=70;i--)
  {
    pinza.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=170;i>=140;i--);
  {
    hombro.write(i);
    delay(20);
  }
  
  posicionInicial();
  
}

void novenaPosicion()
{
  //Muevo la base hasta 132 grados
  for(i=180;i>=132;i--)
  {
    base.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el codo hasta los 94 grados
  for(i=114;i>=94;i--)
  {
    codo.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Muevo el hombro hasta los 170 grados
  for(i=140;i<=170;i++)
  {
    hombro.write(i);
    delay(20);
  }
  
  delay(200);
  
  //Abro la pinza  
  for(i=anguloAgarrePinza;i>=70;i--)
  {
    pinza.write(i);
    delay(20);
  }
  
  delay(200);
  
  for(i=170;i>=140;i--);
  {
    hombro.write(i);
    delay(20);
  }
  
  posicionInicial();
  
}

void happy()
{
  //Muevo el codo hacia arriba
  for(i=90;i<=180;i++);
  {
    codo.write(i);
  }
  
  delay(200);
  
  for(j=0;j<=10;j++)
  {
    
        for(i=180;i>=120;i--);
        {
          base.write(i);
        }
        
        delay(100);
        
        for(i=120;i<=180;i++);
        {
          base.write(i);
        }
        
        delay(100);
        
        for(i=180;i>=120;i--);
        {
          base.write(i);
        }
        
        delay(100);
        
        for(i=120;i<=180;i++);
        {
          base.write(i);
        }
        
        delay(100);
  }
  
  //Muevo la pinza
  for(j=0;j<=10;j++)
  
  {
  
      for(i=70;i<=140;i++);
      {
        pinza.write(i);
      }
      
      delay(200);
      
      for(i=140;i<=120;i--);
      {
        pinza.write(i);
      }
      
      delay(200);
      
      for(i=100;i<=120;i++);
      {
        pinza.write(i);
      }
      
      delay(200);
      
      for(i=140;i<=100;i--);
      {
        pinza.write(i);
      }
      
  }
  
  
}

  void loop() 
  {
    
    
    if(Serial.available()>0)
      {
        char dato= Serial.read();
          
          if(dato=='B')
            {
              girarBaseDerecha();
            }
            
          if(dato=='b')
            {
              girarBaseIzquierda();
            }
          
          if(dato=='H')
            {
              subirHombro();
            }
            
           if(dato=='h')
            {
             bajarHombro(); 
            }
            
           if(dato=='C')
             {
               levantarCodo();
             }
            
           if(dato=='c')
             {
               bajarCodo();
             }
  
          if(dato=='P')
             {
               abrirPinza();
             }
            
           if(dato=='p')
             {
               cerrarPinza();
             }
             
           if(dato=='i')
             {
               posicionInicial();
             }
             
            if(dato=='r')
             {
               recogerFicha();
             }
             
            if(dato=='1')
             {
               primeraPosicion();
             }
             
              if(dato=='2')
             {
               segundaPosicion();
             }
             
              if(dato=='3')
             {
               terceraPosicion();
             }
                          
             if(dato=='4')
             {
               cuartaPosicion();
             }
             
              if(dato=='5')
             {
              quintaPosicion();
             }
             
              if(dato=='6')
             {
              sextaPosicion();
             }
             
             if(dato=='7')
             {
               septimaPosicion();
             }

             if(dato=='8')
             {
               octavaPosicion();
             }
             
              if(dato=='9')
             {
               novenaPosicion();
             }
             
             if(dato=='w')
             {
               happy();
             }
        
        
      }
  }

Comments

Similar projects you might like

Robotic Arm Controlled by Human Arm

Project showcase by zezarandrade

  • 6,060 views
  • 0 comments
  • 11 respects

Simple Programmable Robotic Arm

Project showcase by Ryan Chan

  • 49,319 views
  • 64 comments
  • 145 respects

How to Make a Remote Controlled Robotic Hand with Arduino

Project showcase by Gabry295

  • 35,363 views
  • 5 comments
  • 110 respects

Android Controlled 6DoF Robotic Arm

Project in progress by Team Mans

  • 11,066 views
  • 0 comments
  • 17 respects

1Sheeld Controlled Robotic Arm

Project tutorial by L1Ranger

  • 2,657 views
  • 1 comment
  • 11 respects

WIZnet Controlled Robotic Arm

Project tutorial by Md. Khairul Alam

  • 2,058 views
  • 0 comments
  • 12 respects
Add projectSign up / Login