Kicking Robot Arm

by lorenamardar in Circuits > Arduino

61 Views, 0 Favorites, 0 Comments

Kicking Robot Arm

WhatsApp Image 2024-03-29 at 21.29.03_876e9eff.jpg

In the first year of studying Game Art at HKU we had to take the "If This Then That" class, which focuses on learning how to build a circuit using Arduino and make an interactive product that, when it gets an input, responds with an output (hence the name of the class). My idea was to make something chaotic, not particularly useful, but with an interactive component still and a strong personality - an arm that kicks things (say, your bottle) off the table, just like a cat would.

Supplies

Sketch Design

WhatsApp Image 2024-03-29 at 21.35.57_26f843f1.jpg

The first step was to sketch the design of what I imagined the components and specific interaction to look like. I would have an arm composed of three wooden pieces and two joints which are the motors that can each be rotated horizontally. The motor at the base of the arm would rotate continuously between 0 and 180 degrees, keeping the person interacting with it on the edge. The second motor, the "elbow" of the arm would be set in a position of somewhere over 120 degrees, making it appear as "tucked in" and would only rotate to 0 ("stretched out") when an input would be detected from the button, the first motor will rotate in the direction of the input. At the end of the "forearm" (the part being rotated by the second motor), a palm-like piece would be attached.

Understanding the Bases

WhatsApp Image 2024-03-29 at 21.29.22_fc017bd1.jpg

Since this was my project involving Arduino and working with electronic components, I tried to keep it simple at first, get the bases to work and then build and perfect starting from there. In the first photo, you can see my setup that involved simply having an SG90 servo continuously rotate and, when the button was pressed, it would rotate to a certain position before resuming its previous idle rotation.

Testing & Prototyping

WhatsApp Image 2024-03-29 at 21.29.18_21a495eb.jpg
WhatsApp Image 2024-03-29 at 21.29.12_3c80b2c4.jpg

Next up, I attached a long carton piece to the servo in order to simulate an oversimplified arm. After marking that the SG90 may tilt even due to the carton piece and would need precise counter-balancing on the shorter side of the arm, I did some research and found a stronger, more reliable Servo that could serve as the base of the arm: an MG996R, which would also need to draw power from something other than the Arduino, for which I chose a battery pack of 4 AAAs, which, connected in series, can sum up to 6V. Furthermore, I asked my teacher for feedback on my first idea and he directed me towards pressure sensors, which make detecting input from objects such as bottles ten times easier than doing so with buttons.

This testing phase was therefore meant for my very first prototype, in order to see what changes need to be made. I also tried to plan ahead, thinking about the finished product too and, since I didn't want to leave the pressure sensors exposed, I tested their input sensitivity when was protected by a piece of carton. What I discovered was that the carton would disperse the force that was applied on it enough for the sensor not to detect it, thus I needed something thinner, but still effective for my finishing touches.

Bettering the Design

WhatsApp Image 2024-03-29 at 21.35.57_9c4f5fe5.jpg

My second iteration kept most of the features of the first one, the big change being the motors that would be used and the design of the arm, which was simpler and more stable as it didn't extend too far form the base of the structure, unlike the first one. The base of the arm became a MG996R that rotates horizontally and, on the end of the first arm part, an SG90 would be attached on its side, so that the wooden piece attached to it would move on a perpendicular plane from the other one, that representing the "hand" part.

Testing and Prototyping Part 2

WhatsApp Image 2024-03-29 at 21.29.12_94a37d85.jpg
WhatsApp Image 2024-03-29 at 21.29.12_9918b00a.jpg
WhatsApp Image 2024-03-29 at 21.29.12_9ce24a9f.jpg

A second prototype was built by taping the MG996R to some spare wood and the SG90 to a smaller wood piece. I connected the battery pack to the breadboard and let both motors and the sensors draw power from it. As I will see later, this drained the batteries very quickly and led me to make the SG90 draw power from the Arduino itself, so that the batteries will be used for the MG996R (which needs the most power) and the sensors (which are almost negligible compared to the servo). I tested the angles for both motors, the ideal arm length and positions for reaching the object on the sensors no matter the exact placement and input sensitivity, which I only did on one of the sensors in this phase, due to efficiency reasons. After getting it right, I made the code for the one sensor into a function and called it for all three of them.

Code

Here is the final code that I ended up using after all the tests in the previous step:


#include <Servo.h>


int fac = 1; // variable for the direction of movement for the MG996R

int pos; // variable for the position of the MG996R

int pressure1, pressure2, pressure3; // variables to store input values from the sensors

bool complete = true, hand_down, arm_swing; //booleans to check during the "kicking"


Servo servo_11, servo_10;


void setup() {

// attaching servos to digital pins 10 and 11

  servo_11.attach(11);

  servo_10.attach(10);


//initializing positions

  servo_11.write(0);

  servo_10.write(90);

  Serial.begin(9600);

}

 

void loop() {

  //reading pressure values

  pressure1 = analogRead(A0);

  pressure2 = analogRead(A1);

  pressure3 = analogRead(A2);

  //PrintPressure(); // this function was used for testing


//if the process of "kicking" is done, the arm resumes usual movement

  if(complete == true)

    RotateServo();


//calls function Kick(), feeding it different values depending on the sensor that detects input

  if (pressure1 > 100)

    Kick(180);

  else if (pressure2 > 100)

    Kick(120);

  else if (pressure3 > 100)

    Kick(70);


}


//function responsible for idly rotating the MG996R

void RotateServo() {

  pos += fac;

  servo_11.write(pos);

  delay(100);

}


// this function was used for testing

// void PrintPressure() {

//   Serial.print("pressure1: ");

//   Serial.println(pressure1);

//   Serial.print("pressure2: ");

//   Serial.println(pressure2);

//   Serial.print("pressure3: ");

//   Serial.println(pressure3);

// }


//this function takes care of the entire kicking motion

void Kick(int position){


  //initializing/resetting booleans when the function is called

    complete = false;

    hand_down = false;

    arm_swing = false;


    //MG996R goes to position 0 to make sure it can hit the objects no matter on which sensor it is

    servo_11.write(0);

    delay(500);


    //if the 'hand" has not yet been down and the motion is not completed, the SG90 turns to 180 degrees ("extends")

    //when the desired position is reached, hand_down becomes true

    if (hand_down == false && complete == false){

      servo_10.write(180);

      if(servo_10.read() == 180){

        delay(500);

        hand_down = true;

      }

    }


    //if the "hand" is down, but the swing has not yet taken place, the MG996R is rotated to its desired position

    if (hand_down == true && arm_swing == false && complete == false){

      servo_11.write(position);

      delay (1000);

    }

   

    //when the MG996R reaches the desired position, the "hand" is "retracted" (SG90 rotates back to 0 degrees) and arm_swing becomes true

    if (servo_11.read() == position && complete == false){

      servo_10.write(0);

      arm_swing =  true;

    }


    //if the "hand" has been down and then retracted and the arm swing took place, the motion is marked as complete by making the variable true and the MG996R is returned to 0

    if (servo_10.read() == 0 && arm_swing == true && hand_down == true){

      complete = true;

      pos = 0;

    }

}

 

 

Making an Encasing and an Arm

WhatsApp Image 2024-03-29 at 21.29.11_64bbd574.jpg
WhatsApp Image 2024-03-29 at 21.29.11_12fc25c1.jpg
WhatsApp Image 2024-03-29 at 21.29.08_1f6d7380.jpg
WhatsApp Image 2024-03-29 at 21.29.08_399fd22a.jpg

During this step I downloaded a .svg file of a box with finger slots and laser-cut it, on the top of which the setup from before will be found, while inside the breadboard, the battery-pack and Arduino will be hidden and protected. I cut some holes in the sides of the box so that the cables could come out and connect to the components outside of the box and I also cut 6 smaller pieces of wood: 4 of them where used to make an encasing for the MG996R on the top of the box so that it would be kept in place, and the other 2 were longer and narrower pieces, better simulating an arm. I glued the arm pieces to their respective servos after making sure once again that the measurements were right.

Soldering

wiring.png
WhatsApp Image 2024-03-29 at 21.29.11_072e31d4.jpg

After being pleased with how everything functions, I went ahead and soldered everything together following the illustration you can see in the picture.

Final Product

WhatsApp Image 2024-03-29 at 21.29.05_f524c9c3.jpg
WhatsApp Image 2024-03-29 at 21.29.11_9eba4e97.jpg
WhatsApp Image 2024-03-29 at 21.29.03_876e9eff.jpg

Now that everything I needed was done, what followed was to assemble the whole thing together. For this, I:

  • glued the box parts together
  • placed all the components in the box
  • got the wires to go through the holes and connected everything
  • fixed the motor to the top part of the box
  • taped the sensors to their right locations
  • glued some thick, brown paper on the box to cover the sensors while not messing with the input values
  • marked the sensor locations with Xs

And there it is! Thanks for sticking around to the end.