Our project is to build a robotic arm, so that we can build the skills needed for our second semester project.
While this image and website may not be the most applicable to my project, since it is not servo-powered and includes the arm, while I am only making the claw out of cardboard, this image did help me envision the joints of the claw, and future arm. This was useful as an example of a similar project to mine.
This is a similar project to what I am doing, and so it was useful for providing information and inspiration for my cardboard claw. Not only is it a cardboard claw-arm made using servos, like mine will be, but it also includes directions so that I can incorporate any useful elements into my design.
For the next stage of the project, the wooden arm, I got to use an example built by my teacher. To the left is a picture of part of the example arm that I worked to copy.
Above is my first sketch of my ideas for this project. While not very deatailed, it does show where I imagine the joints and servos will be, with connecting materials in between
This image is what I planned for my cardboard claw. While not very clear, is does show the general shape for the cardboard pieces, and where the servos will go, and where it will be held.
This is my first attempt to build a cardboard claw. While was mostly functional, there were weaknesses and flaws in the design that need to be corrected,
To the left is my attempt to build the base of the arm. It is mostly functional, with the correct range of motion, but it does not have the sides included.
To the left is one of my initial efforts to have the robotic arm grab an object, and move it from left to right. However, this is not done perfectly, as the range of motion is limited, and it is not yet capable of grabbing something from ground level
This video shows my attempt to make my robotic arm "dance," to the extent that a robotic arm can dance. This is going to be joined with a song later on, but this is my attempt to code just the movement, if not the rhythm of robot dancing.
This is a video of my early attempts to make the sensor detect colors correctly. At this point, objectColor=1 means it sees red, and 2 is for green. At close ranges, it can detect these colors, but farther away it still is unreliable, and I haven't been able to test for its ability to detect blue yet. The code still needs to be adjusted, but it is showing some functionality.
This is a circuit diagram of my wiring after combining the RGB sensor and servos to run on the same arduino.
My first alteration to the prototype was to add a second, taller, connecting piece to the servos, and trim the cardboard pieces so that they wouldn't hit the bridges. I did this to make the bridges safer, so they wouldn't come apart when the claw started working.
While the physical design was functional, the initial coding was not. The "claws" went so far to up and down that they tore the design apart, and the bridges disconnected.
#include <Servo.h>
Servo servo1;
Servo servo2;
int pos = 125;
int pos2 = 125;
void setup() {
servo1.attach(5);
servo2.attach(6);
}
void loop() {
servo1.write(pos);
servo2.write(pos2);
delay(3000);
servo1.write(80);
servo2.write(80);
delay(15000);
}
Above is the final code used for the claws. I adjusted the values for the servos sot hat they moved within an acceptable range of motion, and correctly pinched light objects.
To the left is a video of my cardboard claw correctly functioning and picking up a small cardboard box. While it cannot pick up heavy objects, it is capable of picking up light objects like a piece of paper or a small piece of cardboard.
Above is a picture of my finished wooden arm base, that will be built on for the rest of the arm. It has a functional range of motion and the sides have been glued in.
#include <Servo.h>
Servo ServoBase;
void setup() {
ServoBase.attach(5);
}
void loop() {
ServoBase.write(0);
delay(2000);
ServoBase.write(180);
delay(2000);
}
When my initial build of the claw failed to function correctly, I had to stabilize it by including an extra piece, which required deconstructing my claw and reassembling it
Above is a video of my arm having the correct range of motion, showing it has been calibrated correctly and coded to show this.
Above is a video of my other servo having the correct range of motion, showing it has been calibrated correctly and coded to show this.
This video shows my robotic arm functioning, with the servo in the claw coded to show the correct range of movement. In addition, I demonstrated that each joint and servo turns correctly, making the arm movable to the correct positions.
The video shows that some improvement has been made to the coding of the arm. It can grab at ground level, however it does not reliably hold objects when moving, and still has a limited range of motion.
The video shows that the coding has improved to the point that the wooden arm can grab an object from ground level, move it to the the leftmost part of its range of motion, and then repeat the process. This is still not perfect however, since it moves too quickly, and it at risk of dropping the object.
#include <Servo.h>
Servo clawservo;
Servo ServoLeft;
Servo ServoRight;
Servo ServoBase;
int SLStart (167);
int SRStart (170);
void setup() {
clawservo.attach(8);
ServoLeft.attach(7);
ServoRight.attach(6);
ServoBase.attach(5);
}
void loop() {
ServoBase.write(180);
clawservo.write(180);
ServoLeft.write(135);
ServoRight.write(120);
delay(1000);
clawservo.write(90);
delay(2000);
ServoBase.write(140);
ServoLeft.write(180);
ServoRight.write(130);
delay(2000);
ServoBase.write(30);
delay(1000);
clawservo.write(180);
delay(2000);
}
In the video, I tried to get my robot to time its movements to line up with a 144 bpm metronome. I had some success, but it is still not completely working. While the first claw movements do line up with the tempo, the second ones do not. Also, starting the metronome and the movements at the same time is an issue that makes this unreliable.
#include <Servo.h>
Servo clawservo;
Servo ServoLeft;
Servo ServoRight;
Servo ServoBase;
int SL (140);
int SR (110);
int SB (180);
void setup() {
clawservo.attach(8);
ServoLeft.attach(7);
ServoRight.attach(6);
ServoBase.attach(5);
}
void loop() {
SL = 140;
SR = 110;
SB = 180;
ServoBase.write(SB);
clawservo.write(180);
ServoLeft.write(SL);
ServoRight.write(SR);
delay(410);
for (SL = 130; SL < 180; SL += 2) {
ServoLeft.write(SL);
delay(5);
}
ServoRight.write(SR);
delay(410);
clawservo.write(90);
delay(410);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
for (SB = 180; SB > 140; SB -= 1) {
ServoBase.write(SB);
delay(10.25);
}
for (SL = 180; SL > 165; SL -= 3) {
ServoLeft.write(SL);
delay(41);
}
for (SR = 110; SR < 130; SR += 2) {
ServoRight.write(SR);
delay(20.5);
}
delay(820);
for (SB = 140; SB < 160; SB += 2) {
ServoBase.write(SB);
delay(41);
}
delay(410);
for (SB = 160; SB > 120; SB -= 2) {
ServoBase.write(SB);
delay(20.5);
}
delay(410);
for (SL = 165; SL < 170; SL += 1) {
ServoLeft.write(SL);
delay(20.5);
}
for (SR = 130; SR > 80; SR -= 2) {
ServoRight.write(SR);
delay(12.3);
}
delay(820);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
clawservo.write(180);
delay(410);
clawservo.write(90);
delay(410);
for (SR = 80; SR > 60; SR -= 2) {
ServoRight.write(SR);
delay(5);
}
delay(410);
for (SR = 60; SR < 120; SR += 2) {
ServoRight.write(SR);
delay(13.66666667);
}
delay(410);
for (SR = 120; SR > 60; SR -= 2) {
ServoRight.write(SR);
delay(13.66666667);
}
delay(410);
for (SR = 60; SR < 120; SR += 2) {
ServoRight.write(SR);
delay(13.66666667);
}
delay(410);
for (SR = 120; SR > 60; SR -= 2) {
ServoRight.write(SR);
delay(13.66666667);
}
delay(410);
for (SR = 60; SR < 120; SR += 2) {
ServoRight.write(SR);
delay(13.66666667);
}
delay(820);
for (SB = 120; SB < 160; SB += 2) {
ServoBase.write(SB);
delay(20.5);
}
for (SR = 120; SR < 155; SR += 2){
ServoRight.write(SR);
delay(22.778);
}
for (SL = 170; SL < 180; SL += 1){
ServoLeft.write(SL);
delay(41);
}
delay(820);
for (SR= 155; SR > 50; SR -= 2){
ServoRight.write(SR);
delay(7.736);
}
delay(820);
for (SB = 160; SB > 115; SB -= 2) {
ServoBase.write(SB);
delay(17.826);
}
delay(410);
for (SR= 50; SR < 110; SR += 2){
ServoRight.write(SR);
delay(13.667);
}
delay(410);
for (SL = 180; SL > 135; SL -= 2){
ServoLeft.write(SL);
delay(17.826);
}
delay(410);
for (SL = 135; SL < 180; SL += 2){
ServoLeft.write(SL);
delay(17.826);
}
for (SR= 110; SR > 50; SR -= 2){
ServoRight.write(SR);
delay(13.667);
}
delay(410);
for (SR= 50; SR < 110; SR += 2){
ServoRight.write(SR);
delay(13.667);
}
delay(410);
for (SR= 110; SR > 50; SR -= 2){
ServoRight.write(SR);
delay(13.667);
}
delay(410);
for (SR= 50; SR < 110; SR += 2){
ServoRight.write(SR);
delay(13.667);
}
delay(410);
for (SR = 110; SR > 80; SR -= 2){
ServoRight.write(SR);
delay(27.333);
}
for (SL = 180; SL > 150; SL -= 2){
ServoLeft.write(SL);
delay(27.333);
}
//finale
for (SB = 115; SB > 90; SB -= 2) {
ServoBase.write(SB);
delay(31.538);
}
delay(205);
for (SL = 150; SL < 180; SL += 3) {
ServoLeft.write(SL);
delay(20.5);
}
for (SR = 80; SR < 155; SR += 3) {
ServoRight.write(SR);
delay(8.2);
}
delay(2050);
//reset
for (SB = 90; SB < 180; SB += 2) {
ServoBase.write(SB);
delay(10.25);
}
for (SR = 155; SR > 110; SR -= 2) {
ServoRight.write(SR);
delay(17.826);
}
for (SL = 180; SL > 140; SL -= 2) {
ServoLeft.write(SL);
delay(20.5);
}
delay(2050);
}
Using a song with the tempo the robot is coded for, the robot now moves with the song, which I did by changing the delays in the coding to match the beat of the song, so that the movements will line up with the amount of time each beat takes.
As a test, I was assigned a series of motions that I had to make my robot mimic, creating the code within a one and a half hour class period, this video is that code functioning.
#include <Servo.h>
Servo clawservo;
Servo ServoLeft;
Servo ServoRight;
Servo ServoBase;
int CLAW = 0;
int BASE = 0;
int LEFT = 0;
int RIGHT = 0;
void setup() {
clawservo.attach(8);
ServoLeft.attach(7);
ServoRight.attach(6);
ServoBase.attach(5);
}
void loop() {
ServoBase.write(70);
clawservo.write(180);
ServoLeft.write(180);
ServoRight.write(90);
delay(1000);
for (BASE = 70; BASE < 120; BASE += 1) {
ServoBase.write(BASE);
delay(10);
}
delay(1000);
for (LEFT = 180; LEFT > 160; LEFT -= 1){
ServoLeft.write(LEFT);
delay(10);
}
delay(1000);
for (RIGHT = 90; RIGHT < 145; RIGHT += 2){
ServoRight.write(RIGHT);
delay(10);
}
delay(1000);
for (CLAW = 180; CLAW > 90; CLAW -= 2){
clawservo.write(CLAW);
delay(10);
}
delay(1000);
for (RIGHT = 145; RIGHT > 90; RIGHT -= 2){
ServoRight.write(RIGHT);
delay(10);
}
for (LEFT = 160; LEFT < 170; LEFT += 1){
ServoLeft.write(LEFT);
delay(15);
}
delay(1000);
for (LEFT = 170; LEFT < 180; LEFT += 1){
ServoLeft.write(LEFT);
delay(15);
}
delay(1000);
for (BASE = 120; BASE > 20; BASE -= 2){
ServoBase.write(BASE);
delay(10);
}
delay(1000);
for (LEFT = 180; LEFT > 160; LEFT -= 1){
ServoLeft.write(LEFT);
delay(20);
}
delay(1000);
for (LEFT = 160; LEFT > 150; LEFT -= 1){
ServoLeft.write(LEFT);
delay(15);
}
for (RIGHT = 90; RIGHT < 145; RIGHT += 1){
ServoRight.write(RIGHT);
delay(10);
}
delay(1000);
for (CLAW = 90; CLAW < 180; CLAW += 2){
clawservo.write(CLAW);
delay(10);
}
delay(1000);
for (LEFT = 150; LEFT < 180; LEFT += 1){
ServoLeft.write(LEFT);
delay(15);
}
for (RIGHT = 145; RIGHT > 90; RIGHT -= 1){
ServoRight.write(RIGHT);
delay(10);
}
for (BASE = 20; BASE < 70; BASE += 2){
ServoBase.write(BASE);
delay(10);
}
delay(1000);
}
This video shows my robot detecting and responding to colors as it scans a small area. It will turn to different angles depending on which color it detects when it encounters an object.