Project Brief: Robotic Arm
These are the skills that will developed by this project.
These are the project prerequisites that are required to finish this project.
These are the project goals that will be met and marked off as the project is completed.
Project Research
This is the prototype model of the claw, made out of cardboard. It opens and closes, with a delay to allow it to pick up objects. It is unable to pick up small or thin objects due to the design of the claws, however.
This is the base of the robotic arm model. It has a 180 degree range of motion to either side.
This is the robotic arm claw, constructed from wood. It can open and close with simple motion, and can grasp items firmly.
These are the servos on the sides rotating from 0 to 90 and 0 to 180.
This is a video of the robot picking an object up from one end and transporting it to the other.
#include <Servo.h>
Servo servo;
Servo bservo;
Servo cservo;
Servo dservo;
void setup() {
servo.attach(5);//arm, bottom piece
bservo.attach(6);//base, far servo
cservo.attach(7);//claw
dservo.attach(8);//base2
bservo.write(180);
dservo.write(90);
servo.write(90);
cservo.write(0);
delay(300);
dservo.write(90);
delay(300);
bservo.write(180);
delay(300);
cservo.write(45);
delay(2000);
cservo.write(0);
delay(2000);
for(int i=180; i>160; i-=1){
bservo.write(i);
delay(30);
}
bservo.write(160);
delay(300);
for(int i=90; i>0; i-=1){
servo.write(i);
delay(30);
}
servo.write(0);
delay(2000);
for(int i=0; i<60; i+=1){
cservo.write(i);
delay(30);
}
cservo.write(60);
delay(1000);
for(int i=90; i<140; i+=1){
dservo.write(i);
delay(30);
}
dservo.write(140);
delay(1000);
for(int i=60; i>0; i-=1){
cservo.write(i);
delay(30);
}
cservo.write(0);
delay(1000);
for(int i=140; i>90; i-=1){
dservo.write(i);
delay(30);
}
dservo.write(90);
delay(1000);
for(int i=0; i<180; i+=1){
servo.write(i);
delay(30);
}
servo.write(180);
delay(1000);
for(int i=90; i<140; i+=1){
dservo.write(i);
delay(30);
}
dservo.write(140);
delay(300);
for(int i=0; i<60; i+=1){
cservo.write(i);
delay(30);
}
cservo.write(60);
delay(1000);
for(int i=140; i>90; i-=1){
dservo.write(i);
delay(30);
}
dservo.write(90);
delay(300);
for(int i=160; i<180; i+=1){
bservo.write(i);
delay(30);
}
bservo.write(180);
delay(1000);
for(int i=180; i>90; i-=1){
servo.write(i);
delay(30);
}
servo.write(90);
}
void loop(){
}
This is the video for the robot coding quiz. It moves to one side, extends, picks up an object, retracts, moves to the other side, extends, places the object down, and then resets.
#include <Servo.h>
Servo servo;
Servo bservo;
Servo cservo;
Servo dservo;
void setup() {
// put your setup code here, to run once:
servo.attach(5);//arm, bottom piece
bservo.attach(6);//base, far servo
cservo.attach(7);//claw
dservo.attach(8);//base2
bservo.write(180);
dservo.write(90);
servo.write(90);
cservo.write(80);
delay(1000);
for(int i = 90; i>45;i-=1){
servo.write(i);
delay(30);
}
servo.write(45);
delay(1000);
for(int i = 180; i>160;i-=1){
bservo.write(i);
delay(30);
}
bservo.write(160);
delay(1000);
for(int i = 90; i<180;i+=1){
dservo.write(i);
delay(30);
}
dservo.write(180);
delay(1000);
for(int i = 80; i>0;i-=1){
cservo.write(i);
delay(30);
}
cservo.write(0);
delay(1000);
for(int i = 180; i>90;i-=1){
dservo.write(i);
delay(30);
}
dservo.write(90);
delay(1000);
for(int i = 160; i<180;i+=1){
bservo.write(i);
delay(30);
}
bservo.write(180);
delay(1000);
for(int i = 45; i<135;i+=1){
servo.write(i);
delay(30);
}
servo.write(135);
delay(1000);
for(int i = 180; i>160;i-=1){
bservo.write(i);
delay(30);
}
bservo.write(160);
delay(1000);
for(int i = 90; i<180;i+=1){
dservo.write(i);
delay(30);
}
dservo.write(180);
delay(1000);
for(int i = 0; i<80;i+=1){
cservo.write(i);
delay(30);
}
cservo.write(80);
int bpos = 160;
int dpos = 180;
int pos = 135;
int count = 0;
while(count < 100){
bpos+=(20/50);
dpos-=(90/50);
pos-=(45/50);
bservo.write(bpos);
delay(30);
dservo.write(dpos);
delay(30);
servo.write(pos);
delay(30);
count++;
}
bservo.write(180);
dservo.write(90);
servo.write(90);
}
void loop() {
// put your main code here, to run repeatedly:
}
This is the RGB Sensor test. The blank (pointing towards nothing) values were shown, followed by recording the values of a orange and green skittle.
Diagram of the circuit that will control the servo arm with the color view sensor.
This is the video of the robotic arm reacting to stimuli in the colorview sensor.
This is a compact, Arduino powered sorting machine that sorts from one input into 5 separate outputs.
This is an open design that shows the inner workings of the machine, allowing for easy troubleshooting and the ability to view if it functioning properly or not.
This design is similar to the first, with the added difference of having a larger chute at the end to prevent spillage.
This is a 3D-printed design that swivels and sorts in 360 degrees rather than just 180, allowing for greater distinction or more categories of sorting. It also sorts 6 types rather than 5.
This is day 1 of rapidly prototyping a sorting machine. On this day we conducted research on existing designs and sketched out a basic idea of a design.
This is day 2 of rapidly prototyping a sorting machine. Here you can see that the machine reacts to color stimuli and moves the arm accordingly.
On day 3 of rapidly prototyping, the machine was raised off of the ground a considerable amount, and a chute was added to the exit of the machine. Calibration of the bottom chute still required.
On day 4 of rapidly prototyping, a chute was added to the entrance of the machine, and a lid was added to the machine. Development began on the boxes that will hold the sorted skittles.
On this day we secured the color sensor to the machine to get consistent readings, then calibrated the chutes accordingly to sort the inputs.
This is the circuit diagram of the prototype.
#include <Servo.h>
#include <Wire.h>
#include "Adafruit_TCS34725.h"
float active = true;
float phase = 0;
float pos;
Servo servo1;
Servo servo2;
//reds = 125, 75, 60
//orang = 140, 70, 50
//yellow = 130, 80, 50
//purp = 120, 80, 60
//green = 105, 90, 60
//carboard = 105, 85, 70
#define redpin 2
#define greenpin 3
#define bluepin 4
#define commonAnode true
byte gammatable[256];
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
void setup() {
// put your setup code here, to run once:
//colorview stuff
Serial.begin(9600);
if (tcs.begin()) {
Serial.println("Found sensor");
} else {
Serial.println("No TCS34725 found ... check your connections");
while (1); // halt!
}
#if defined(ARDUINO_ARCH_ESP32)
ledcAttachPin(redpin, 1);
ledcSetup(1, 12000, 8);
ledcAttachPin(greenpin, 2);
ledcSetup(2, 12000, 8);
ledcAttachPin(bluepin, 3);
ledcSetup(3, 12000, 8);
#else
pinMode(redpin, OUTPUT);
pinMode(greenpin, OUTPUT);
pinMode(bluepin, OUTPUT);
#endif
for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x *= 255;
if (commonAnode) {
gammatable[i] = 255 - x;
} else {
gammatable[i] = x;
}
//Serial.println(gammatable[i]);
}
//servo stuff
servo1.attach(7);
servo2.attach(8);
servo1.write(0);
delay(1000);
servo1.write(90);
delay(1000);
servo2.write(60);
delay(2000);
servo2.write(120);
delay(2000);
servo2.write(90);
delay(2000);
active = false;
pos = 90;
phase = 1;
}
float red, green, blue;
void loop() {
// put your main code here, to run repeatedly:
if(phase == 1 && active == false){
active = true;
for(int i = 0; i<90; i++){
servo1.write(i);
delay(10);
}
servo1.write(90);
delay(2000);
for(int i = 90; i>45; i--){
servo1.write(i);
delay(10);
}
servo1.write(45);
delay(1000);
active = false;
phase = 2;
while(phase == 2 && active == false){
scan();
if(red >= 140 && red <= 158 && green >= 60 && green <= 72 && blue >= 51 && blue <= 72){ //red
active = true;
for(int i = 90; i>0; i--){
servo2.write(i);
delay(10);
}
pos = 0;
servo2.write(0);
delay(200);
for(int i = 45; i>0; i--){
servo1.write(i);
delay(10);
}
servo1.write(0);
} else if(red >= 125 && red <= 135 && green >= 70 && green <= 79 && blue >= 45 && blue <= 56){//purple
active = true;
for(int i = 90; i>60; i--){
servo2.write(i);
delay(10);
}
pos = 60;
servo2.write(60);
delay(200);
for(int i = 45; i>0; i--){
servo1.write(i);
delay(10);
}
servo1.write(0);
} else if(red >= 114 && red <= 122 && green >= 86 && green <= 91 && blue >= 42 && blue <= 51){//green
active = true;
for(int i = 45; i>0; i--){
servo1.write(i);
delay(10);
}
pos = 90;
servo1.write(0);
} else if(red >= 122 && red <= 139 && green >= 72 && green <= 81 && blue >= 34 && blue <= 42){//yellow
active = true;
for(int i = 90; i<120; i++){
servo2.write(i);
delay(10);
}
servo2.write(120);
delay(200);
for(int i = 45; i>0; i--){
servo1.write(i);
delay(10);
}
pos = 120;
servo1.write(0);
} else if(red >= 149 && red <= 158 && green >= 60 && green <= 66 && blue >= 37 && blue <= 44){//orange
active = true;
for(int i = 90; i<180; i++){
servo2.write(i);
delay(10);
}
servo2.write(180);
delay(200);
for(int i = 45; i>0; i--){
servo1.write(i);
delay(10);
}
pos = 180;
servo1.write(0);
}
delay(60);
}
delay(1000);
if(pos != 90){
if(pos > 90){
for(int i = pos; i>90; i--){
servo2.write(i);
delay(10);
}
} else if(pos < 90){
for(int i = pos; i<90; i++){
servo2.write(i);
delay(10);
}
}
}
servo2.write(90);
delay(200);
active = false;
phase = 1;
}
}
void scan(){
tcs.setInterrupt(false); // turn on LED
delay(60); // takes 50ms to read
tcs.getRGB(&red, &green, &blue);
tcs.setInterrupt(true); // turn off LED
Serial.print("R:\t"); Serial.print(int(red));
Serial.print("\tG:\t"); Serial.print(int(green));
Serial.print("\tB:\t"); Serial.print(int(blue));
// Serial.print("\t");
// Serial.print((int)red, HEX); Serial.print((int)green, HEX); Serial.print((int)blue, HEX);
Serial.print("\n");
#if defined(ARDUINO_ARCH_ESP32)
ledcWrite(1, gammatable[(int)red]);
ledcWrite(2, gammatable[(int)green]);
ledcWrite(3, gammatable[(int)blue]);
#else
analogWrite(redpin, gammatable[(int)red]);
analogWrite(greenpin, gammatable[(int)green]);
analogWrite(bluepin, gammatable[(int)blue]);
#endif
}
In day 6 of working on the prototype, we completed the sorting boxes where the output would be sorted to.
The three most important functions of the prototype is that it scans the skittle from the input one at a time, determines what type of skittle it is, and sorts the skittle into separate inputs. Listed here are the two functions I worked on.
The first function is the identify/process phase, where the sensor scans each skittle and identifies what color it is. It then updates the output motor, which receives the data, before updating the slide servo to the exit chamber to move the skittle to the output motor. This is the portion that received the most updates, as calibration for the sensor was difficult. This part was worked on from Day 3 onward, continually being calibrated and changed as the frame was designed. Testing the sensor motor was dependent on inputting several of the same type (color) of skittle, and recording the values the sensor would read, then adjusting the calibration values based on the sensor feedback.
The second function that I worked on is the output phase, where the exit chute moves to the correct location, and the slide motor moves the skittle to the exit, causing it to fall down and be sorted into one of five different boxes. It was created on day 4 of prototyping, and tested on both that day and day 5, as it was simple to create 5 distinct outputs and have it loop between them before linking it to the systems. Some problems that we ran into while we designed it was that it would keep physically clipping on the output boxes and catching on itself, which we fixed by making modifications to the chute, raising it above the boxes so it didn't clip them.
On day 7 we recalibrated the sensor once more, and reformatted the funnel so that it would not jam as much.
This is a video of the prototype sorting skittles. It accepts 1 skittle at a time, moves it to the sensor, scans it, detects which color the skittle is by comparing the sensor readings to a list of preset parameters, and then moving the exit chute accordingly.
Recycling Sorting Machine Research 1: Pre-existing DIY Sorter
This is a sorting machine that sorts ferrous (magnetic) metals from other objects. Scaled up, this is a way to remove metal recyclables from other materials.
Recycling Sorting Machine Research 2: Recycling Facilities
This is a general rundown on how most recycling plants/companies sort material from one another.
Recycling Sorting Machine Research 3: MRF Facility
This is a in-depth walkthrough on how MRF facilities sort recyclable material, and what they specifically look for when sorting said material.
Recycling Sorting Machine Research 4: Optimized Sorting Methods
This is an analysis that displays statistics on recycling and waste plants, and also shows the steps they take to sort out and process the many different types of material.
Stepper motor.