Engineer

Eytan I

Area of Interest

Computer Engineering/Computer Science

School

SAR High School

Grade

Incoming Senior

Main Project: 4 Joint Robotic Arm

Final Milestone: Neaten up wires and code, and add a gyroscope function

For my final milestone, I made my robotic arm much more condensed, easier to carry, and smooth. In order to make it more visually appearing, I removed almost all of the jumper wires, and replaced them with non-bendable wires. Additionally, I soldered the 4 servo motors, HC-06 Bluetooth Module, and switch into a proto-sheild. A proto-sheild has strips of powered and grounded places to solder, allowing companants to be able to be connected to power and ground very easily. Another modification I made was adding notes to my code and cleaning it up. This way, those looking for guidance in my code could be more well guided. Lastly, a large modification that I made was adding a mode of control which is through using a gyroscope sensor. I made it so that if the device turns to the left, so does the arm, and if the device leans forward, the arm does as well. This modification was fascinating for me to try, and very thrilling. I then added a close and open claws button to it to make it more practical. A major problem I had was figuring out how to communicate multiple values to the arduino and for the arduino to know which arm the command corresponds to. I ended up sending back numbers in the 100’s for the x axis and 200’s for the y axis. This way I was able to allow both to be read and set different commands for each.

img_6279

What my arm could do

  1. Mode One
    1. When the arm initializes, it is in mode one. In mode one, the arm is controlled through 4 potentiometers.
      1. A potentiometer is a variable resistor. The potentiometer allows me to control the current let into the arduino read pin and turn that into a value
    2. In mode one, the arm is also searching for two possible events
      1. The button is pushed
      2. A command is sent through the Bluetooth module
    3. If those take place…
      1. If a button is pressed the mode is changed to two
      2. If a command is received, the arm moves to a central position and then the mode is changed to three
  2. Mode Two
    1. Mode two is the autonomous mode of the project.
    2. How it works
      1. The arm first goes to a starting position of  all the way to the right, down, and claw open
      2. The arm starts rotating to the left, while constantly checking the distance sensors.
      3. If an object is read to be closer than 20 cm, the object stops
      4. It then moves forward(which involves moving up and forward due to the way the arm is engineered) until it reaches 3 cm
      5. Once it is 3 cm away, the claws of the body close, and the object is brought up
      6. The mode is changed back two one
    3. Mode Three
      1. Mode three is entered by connecting the kindle app to the Bluetooth module and sending any signal
      2. The mode begins by gradually bringing the arm from the position of the potentiometers to the starting position of the mode(Center, medium height, arms open).
      3. When one presses down a button it sends a number to the arduino and the arduino reads that as a command
      4. When the button is released, another number is sent and the arduino stops carrying out the action
      5. The controller can also click on “mode 1” or “mode 2” to make the arm gradually go into position to go into those modes, and then enter them.
      6. LASTLY, there is a button that says Gyroscope.
        1. When one clicks that button they are brought to a new screen on the app. The app measures the x and y tilt of the kindle and sends values back to the kindle telling it to move left or right, and forward and backwards.

BEFORE

Before this milestone, all of my wires were bendable jumper wires. Additionally, I had two breadboards to hold all my components. I took out the main bread board, and soldered all of its components to a proto-sheild. Additionally, I replaced the wires still needed with rigid wire. The few bendable wires present are needed to allow for slack for the servos.

AFTER

img_6276-1
img_6280-2

MIT App Inventor

screenshot_20190726-112920
screenshot_20190726-113204

MIT App Inventor has two parts to it, the design workshop, and the code workshop. In this milestone I used the design workshop to make the layout of the app look very nice. I also added to the code. The code could be accessed using this link.

screenshot-5
screenshot-6
screenshot-4
#include <Servo.h>

Servo myservo1; // create servo object to control a servo
Servo myservo2; // create servo object to control a servo
Servo myservo3; // create servo object to control a servo
Servo myservo4; // create servo object to control a servo

int potpin1 = 0; // analog pin used to connect the potentiometer
int potpin2 = A1; // analog pin used to connect the potentiometer
int potpin3 = A2; // analog pin used to connect the potentiometer
int potpin4 = A3; // analog pin used to connect the potentiometer


int val1 = 0; // variable to read the value from the analog pin
int val1avg = 0; // variable to read the value from the analog pin
int val1RevertTo; // variable that keeps value of potentiameter
int val2 = 0; // variable to read the value from the analog pin
int val2avg = 0; // variable to read the value from the analog pin
int val2RevertTo; // variable that keeps value of potentiameter
int val3 = 0; // variable to read the value from the analog pin
int val3avg = 0; // variable to read the value from the analog pin
int val3RevertTo ; // variable that keeps value of potentiameter
int val4 = 0; // variable to read the value from the analog pin
int val4avg = 0; // variable to read the value from the analog pin
int val4RevertTo; // variable that keeps value of potentiameter
int timeslooped = 0; // variable to read the value from the analog pin

// For ultrasonic
const int trigPin = 6;
const int echoPin = 5;
// defines variables
long duration;
int distance;

int mode = 1; //Mode of either manual, autonomous, or bluetooth
int setposition = 0; // variable that allows arm to fully get to starting spot in mode 2
int rotatingPosition = 1; // part of rotating function in mode 2
bool clockwise = true; // part of rotating function in mode 2
bool foundObject = false; // part of search function in mode 2
int endposition = 0; // part of rotating function in mode 2


#include <SoftwareSerial.h> // Allows communication with Bluetooth

SoftwareSerial mySerial(0, 1); // RX, TX
int data = ""; // variable for ncoming data
int miniData = 0; 
int miniData2 = 0;// variables for data in gyroscope mode
int blueServo1 = 90; // variables for orientation of servos while in bluetooth mode
int blueServo2 = 90;
int blueServo3 = 45;
int blueServo4 = 90; // variables for orientation of servos while in bluetooth mode
int dataTenNum = 0;

void setup() {
myservo1.attach(9); // attaches the servo1 on pin 9 to the servo object
myservo2.attach(10); // attaches the servo2 on pin 10 to the servo object
myservo3.attach(11); // attaches the servo3 on pin 11 to the servo object
myservo4.attach(3); // attaches the servo4 on pin 4 to the servo object

pinMode(2, INPUT); // attach button reader
pinMode(8, OUTPUT); // attach mode indicator LED

pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input


// Open serial communications and wait for port to open:
Serial.begin(57600);
pinMode(8, OUTPUT);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}


Serial.println("Initiated");

// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
mySerial.println("Hello, world?");
}


void loop() {

checkForButton(); // function that checks if the button is pressed and if it is, changes modes
if (mode == 3)
{
myservo1.write(blueServo1);
myservo2.write(blueServo2);
myservo3.write(blueServo3);
myservo4.write(blueServo4); // start servos at certain position
if (mySerial.available() and data != 11) // if recieve data and not in gyroscope mode
{
data = mySerial.read(); // define data as the num recieved from BT
Serial.write(data);
Serial.print(data);
delay(100);


}

while (data == 11) //When data is 11, and stay in function until it is not
{

miniData = mySerial.read(); // new variable is for the data recieved while in 11


if (miniData > 80 and miniData < 120) // input sent from BLUETOOTH for x axis
{
myservo1.write(map(miniData, 90, 110, 180, 0)); // scale it and move base servo
}
if ((miniData) > 180 and miniData < 220)
{

myservo4.write(map(miniData, 190, 210, 60, 180));
myservo2.write(map(miniData, 190, 210, 60, 180)); // move arm up and forwards
}
if ((miniData) == 13)
{

myservo3.write(90); // open arm
}
if ((miniData) == 14)
{

myservo3.write(0); // close arm
}
if ((miniData) == 15)
{
data = 30;
return();// leave gyroscope mode
}
}
if (data == 10) // search and stop function
{

if (( abs(blueServo1 - 1)) > 3 or ( abs(blueServo4 - 108)) > 3 or ( abs(blueServo2 - 60)) > 3)
{ // this variable ensures that all arms are in correct possition before starting to search
goGraduallyTowards(&blueServo1, 1); // function that gradually increments a value to another value
goGraduallyTowards(&blueServo4, 108);
goGraduallyTowards(&blueServo3, 90);
goGraduallyTowards(&blueServo2, 60);
myservo1.write(blueServo1); // sets the servo position according to the scaled value
myservo2.write(blueServo2);
myservo3.write(blueServo3);
myservo4.write(blueServo4);
Serial.println("STILL SETTING");
foundObject = false;
dataTenNum++;
}
else if (foundObject == false and dataTenNum > 10) // if position is in start, and object is not yet found
{

goAround(); // function that sweeps arm across and searches for object in proximity
Serial.print("GOING AROUND");
}
else if ( foundObject == true and dataTenNum > 10) // if position is in start, and object is not yet found
{

setposition = 0;
foundObject = false;
blueServo1 = rotatingPosition;
blueServo2 = 60;
blueServo3 = 90;
blueServo4 = 108;
data = 30;
rotatingPosition = 0; // reset all variables and make it leave function
}
}

else if (data == 1 ) // brings the arm to position of the potentiameters and then back to mode 1
{
while (( abs(blueServo2 - val2RevertTo)) > 3 and ( abs(blueServo1 - val1RevertTo)) > 3)
{
goGraduallyTowards(&blueServo1, val1RevertTo);
goGraduallyTowards(&blueServo2, val2RevertTo);
goGraduallyTowards(&blueServo3, val3RevertTo);
goGraduallyTowards(&blueServo4, val4RevertTo);
myservo1.write(blueServo1); // sets the servo position according to the scaled value
myservo2.write(blueServo2);
myservo3.write(blueServo3);
myservo4.write(blueServo4);
delay(10);
}
mode = 1;
}
else if (data == 2 ) // enter mode 2
{

while (( abs(blueServo2 - val2RevertTo)) > 3 and ( abs(blueServo1 - val1RevertTo)) > 3)
{
goGraduallyTowards(&blueServo1, val1RevertTo);
goGraduallyTowards(&blueServo2, val2RevertTo);
goGraduallyTowards(&blueServo3, val3RevertTo);
goGraduallyTowards(&blueServo4, val4RevertTo);
myservo1.write(blueServo1); // sets the servo position according to the scaled value
myservo2.write(blueServo2);
myservo3.write(blueServo3);
myservo4.write(blueServo4);
delay(50);
}

mode = 2;


}
else if (data == 3 and blueServo1 < 180 ) // base right
{
blueServo1 = blueServo1 + 1;
delay(20);

}
else if (data == 4 and blueServo1 > 0) //base left
{
blueServo1 = blueServo1 - 1;
delay(20);

}
else if (data == 9 and blueServo2 < 180 ) // arm up
{
blueServo2 = blueServo2 + 1;
delay(20);

}
else if (data == 0 and blueServo2 > 60) //arm down
{

blueServo2 = blueServo2 - 1;
delay(20);
}
else if (data == 7 and blueServo3 < 90 ) //claw open
{

blueServo3 = blueServo3 + 1;
delay(20);

}
else if (data == 8 and blueServo3 > 0) // claw close
{

blueServo3 = blueServo3 - 1;
delay(20);
}
else if (data == 5 and blueServo4 < 180) //claw forward
{

blueServo4 = blueServo4 + 1;
delay(20);

}
else if (data == 6 and blueServo4 > 60) //claw back
{

blueServo4 = blueServo4 - 1;
delay(20);
}

}

if (mode == 1) // if in manual mode
{
if (mySerial.available()) { //if data is recieved while in mode 1

while (( abs(blueServo2 - val2RevertTo)) > 3 and ( abs(blueServo1 - val1RevertTo)) > 3)
{
goGraduallyTowards(&val1avg, 90);
goGraduallyTowards(&val2avg, 90);
goGraduallyTowards(&val3avg, 45);
goGraduallyTowards(&val4avg, 90);
myservo1.write(val1avg); // go to starting position of BT mode
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
val1RevertTo = val1avg;
val2RevertTo = val2avg;
val4RevertTo = val3avg;
val4RevertTo = val4avg;
delay(20);
}


mode = 3;
blueServo1 = 90;
blueServo2 = 90;
blueServo3 = 45;
blueServo4 = 90;
}
//NOW REGULAR MANUAL CODE
timeslooped = timeslooped + 1;
val1 = val1 + analogRead(potpin1); // reads the value of the potentiometer (value between 0 and 1023) and makes the value, the sum of seven
val2 = val2 + analogRead(potpin2); // this is to make it jitter less because it is an average
val3 = val3 + analogRead(potpin3);
val4 = val4 + analogRead(potpin4);

if (timeslooped >= 7) //if seven values have been added
{
val1avg = val1 / 7; // take an average
val2avg = val2 / 7;
val3avg = val3 / 7;
val4avg = val4 / 7;

val1avg = map(val1avg, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180), using the average value
val2avg = map(val2avg, 0, 1023, 60, 180);
val3avg = map(val3avg, 2, 1023, 0, 90);
val4avg = map(val4avg, 0, 1023, 60, 180);


val1RevertTo = val1avg;
val2RevertTo = val2avg;
val3RevertTo = val3avg;
val4RevertTo = val4avg;

myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
//
timeslooped = 0; // reset loop
val1 = 0;
val2 = 0;
val3 = 0;
val4 = 0;
}
}
else if ( mode == 2)
{

if (setposition < 200) { // this variable ensures that all arms are in correct possition before starting to search
goGraduallyTowards(&val1avg, 1); // function that gradually increments a value to another value
goGraduallyTowards(&val4avg, 108);
goGraduallyTowards(&val3avg, 90);
goGraduallyTowards(&val2avg, 60);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
Serial.println("STILL SETTING");
}
else if (setposition >= 200 and foundObject == false) // if position is in start, and object is not yet found
{

goAround(); // function that sweeps arm across and searches for object in proximity

}

else if (setposition >= 200 and foundObject == true)
{

while (distance > 4 and distance < 20) // if object is found, make the arm go forward(and up to stay at level) until 3 cm away from object
{
Ultrasonic();
val2avg = val2avg + 4;
val4avg = val4avg + 3;
// val4avg=val4avg+5;
delay(200);
myservo2.write(val2avg);
myservo4.write(val4avg);
Serial.println(distance);
}
while ((distance <= 4) or (distance > 20)) // once within 3 (or the reading reads incorrect value because it is too close) close arms
{
if (val3avg > 0) {
val3avg--;
delay(30);
myservo3.write(val3avg);
}

else if (val3avg < 70) //and (abs(val4avg-130)>5) and (abs(val2avg-90)>5) // once arms are closed, move object back and up
{
if (endposition < 50)
{
val1 = analogRead(potpin1); // reads the value of the potentiometer (value between 0 and 1023) and makes the value, the sum of seven
val2 = analogRead(potpin2); // this is to make it jitter less because it is an average
val3 = analogRead(potpin3);
val4 = analogRead(potpin4);

val1 = map(val1, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180), using the average value
val2 = map(val2, 0, 1023, 60, 180);
val3 = map(val3, 2, 1023, 0, 90);
val4 = map(val4, 0, 1023, 60, 180);
goGraduallyTowards(&val1avg, val1);
goGraduallyTowards(&val2avg, val2);
goGraduallyTowards(&val3avg, val3);
goGraduallyTowards(&val4avg, val4);
myservo4.write(val4avg); //
myservo2.write(val2avg); //
myservo1.write(val1avg); //
myservo3.write(val3avg); //
endposition = endposition + 1;
Serial.println("STILL HERE");
Serial.println(endposition);
}
else if (endposition >= 50)
{
setposition = 0; // go back to mode one and reset variables
rotatingPosition = 1;
clockwise = true;
foundObject = false;
mode = 1;
endposition = 0;
Serial.println("YES");
Serial.println("MODE");
Serial.println(mode);
return (mode);

}
}
}


}

}

}

int goGraduallyTowards(int *x, int y)
{
Serial.println("GRADUAL");
if ( (abs(*x - y)) < 3)
{
setposition = setposition + 1;

//
}
else if ( *x < y)
{
*x = *x + 1;
Serial.println("value x up");
Serial.println(*x);
//delay(500);
}
else if ( *x > y)
{
*x = *x - 1;
Serial.println(*x);
Serial.println("value x down");
// delay(500);
}

//return x;

}
//PROBLEM--- DOESNT RESET NUMBER OF INT X
//MODEL LIKE OTHER ONE


int goAround()
{

while (( rotatingPosition < 180 ) and (clockwise == true) )
{
Ultrasonic();
rotatingPosition = rotatingPosition + 3;
delay(200);
Serial.println( distance);
myservo1.write(rotatingPosition);

if (distance < 20)
{
foundObject = true;
return (distance);

}


}
while (( rotatingPosition >= 180) and (clockwise == true))
{
clockwise = false;
rotatingPosition = 178;
myservo1.write(rotatingPosition);

return (rotatingPosition);

}
while (( rotatingPosition > 1) and (clockwise == false))
{
rotatingPosition = rotatingPosition - 3;
delay(30);
Serial.println( rotatingPosition);

myservo1.write(rotatingPosition);


}

while (( rotatingPosition <= 1) and (clockwise == false))
{
rotatingPosition = 1;
clockwise = true;
myservo1.write(rotatingPosition);
return (rotatingPosition);

}

}
int Ultrasonic()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
Serial.println(distance);
}

int checkForButton()
{


if (digitalRead(2) == true) // IF SWITCH IS PRESSED
{
delay(500);

if (mode == 1)
{
mode = 2;
val1RevertTo = val1avg;
val2RevertTo = val2avg;
val3RevertTo = val3avg;
val4RevertTo = val4avg;
Serial.println("MAKING ");
}
else if (mode == 2) /// if the mode is one, make it two. If two, make one
{

mode = 1;
goGraduallyTowards(&val1avg, val1RevertTo);
goGraduallyTowards(&val2avg, val2RevertTo);
goGraduallyTowards(&val3avg, val3RevertTo);
goGraduallyTowards(&val4avg, val4RevertTo);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
Serial.println("MOVING BACK");

}
}
if (digitalRead(2) == true) // IF SWITCH IS PRESSED
{
delay(500);
// Serial.println("READ"); //print read
if (mode == 1)
{
mode = 2;
val1RevertTo = val1avg;
val2RevertTo = val2avg;
val3RevertTo = val3avg;
val4RevertTo = val4avg;
}
else if (mode == 2 and (abs(val1avg - val1RevertTo) < 5) ) /// if the mode is one, make it two. If two, make one
{
mode = 1;
goGraduallyTowards(&val1avg, val1RevertTo);
goGraduallyTowards(&val2avg, val2RevertTo);
goGraduallyTowards(&val3avg, val3RevertTo);
goGraduallyTowards(&val4avg, val4RevertTo);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);

}
}

if (mode == 2)
{
digitalWrite(8, true); // IF mode Two, turn on light
}
else if (mode == 1)
{
digitalWrite(8, false);
setposition = 0;
}// waits for the servo to get there
}

3rd Milestone: Connect Arm With Bluetooth Controlled App

For my 3rd milestone, I created an app through MIT App Inventor which controls the arm using a Bluetooth module. MIT App Inventor has two aspects of it: design and code. In the design phase of the app, I made a display which shows 10 buttons, and a drop down, Bluetooth options, display. Once completing the design and making it look neat, I moved on to the coding aspect. MIT App Inventor allows its users to chose from an array of options, and use pre-defined code to carry out functions. In order to code my app to work effectively, I programmed the drop down list to have the elements of all available Bluetooth addresses, and for the Bluetooth of the device to connect to the selected address. Next, I programmed the buttons to when initially pressed down, send a one byte number through the Bluetooth module to the arduino, and then another one once it is release. On the arduino end, I added code so that when the arm is in mode 1 (manual mode) and the arduino receives any data, the device enters mode 3. In mode three, the arduino reads the numbers it receives and carries out certain commands based on the number it receives. I also added buttons which bring it back to mode 1, or into mode 2 (autonomous mode).

screenshot_20190722-215331

Design Mode

screenshot-2

Code Mode

screenshot-3
#include <Servo.h>

Servo myservo1; // create servo object to control a servo
Servo myservo2; // create servo object to control a servo
Servo myservo3; // create servo object to control a servo
Servo myservo4; // create servo object to control a servo

int potpin1 = 0; // analog pin used to connect the potentiometer
int potpin2= A1; // analog pin used to connect the potentiometer
int potpin3= A2; // analog pin used to connect the potentiometer
int potpin4= A3;// analog pin used to connect the potentiometer


int val1=0; // variable to read the value from the analog pin
int val1avg=0; // variable to read the value from the analog pin
int val1RevertTo; // variable that keeps value of potentiameter
int val2=0; // variable to read the value from the analog pin
int val2avg=0; // variable to read the value from the analog pin
int val2RevertTo; // variable that keeps value of potentiameter
int val3=0; // variable to read the value from the analog pin
int val3avg=0; // variable to read the value from the analog pin
int val3RevertTo ; // variable that keeps value of potentiameter
int val4=0; // variable to read the value from the analog pin
int val4avg=0;// variable to read the value from the analog pin
int val4RevertTo; // variable that keeps value of potentiameter
int timeslooped = 0; // variable to read the value from the analog pin

// For ultrasonic
const int trigPin = 13;
const int echoPin = 12;
// defines variables
long duration;
int distance;

int mode = 1; //Mode of either manual or autonomous
int setposition = 0;
int rotatingPosition = 1;
bool clockwise= true;
bool foundObject= false;
int endposition=0;


#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); // RX, TX
int data= "";
int blueServo1=90;
int blueServo2=90;
int blueServo3=45;
int blueServo4=90;


void setup() {
myservo1.attach(9); // attaches the servo1 on pin 9 to the servo object
myservo2.attach(10); // attaches the servo2 on pin 10 to the servo object
myservo3.attach(11); // attaches the servo3 on pin 11 to the servo object
myservo4.attach(3); // attaches the servo4 on pin 4 to the servo object

pinMode(2,INPUT); // attach button reader
pinMode(8, OUTPUT); // attach mode indicator LED

pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input


// Open serial communications and wait for port to open:
Serial.begin(57600);
pinMode(8,OUTPUT);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}


Serial.println("Goodnight moon!");

// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
mySerial.println("Hello, world?");
}


void loop() {

checkForButton(); // function that checks if the button is pressed and if it is, changes modes
if (mode == 3)
{
myservo1.write(blueServo1);
myservo2.write(blueServo2);
myservo3.write(blueServo3);
myservo4.write(blueServo4); 
if (mySerial.available()) {
data= mySerial.read();
// Serial.write(data);
Serial.print(data);
delay(100);
// sets the servo position according to the scaled value

}
if (data == 1 )
{
while (( abs(blueServo2 - val2RevertTo))>3 and ( abs(blueServo1 - val1RevertTo))>3)
{
goGraduallyTowards(&blueServo1,val1RevertTo);
goGraduallyTowards(&blueServo2,val2RevertTo);
goGraduallyTowards(&blueServo3, val3RevertTo);
goGraduallyTowards(&blueServo4,val4RevertTo);
myservo1.write(blueServo1); // sets the servo position according to the scaled value
myservo2.write(blueServo2);
myservo3.write(blueServo3);
myservo4.write(blueServo4);
delay(10);
}
mode=1;
}
if (data == 2 )
{
while (( abs(blueServo2 - val2RevertTo))>3 and ( abs(blueServo1 - val1RevertTo))>3)
{
goGraduallyTowards(&blueServo1,val1RevertTo);
goGraduallyTowards(&blueServo2,val2RevertTo);
goGraduallyTowards(&blueServo3, val3RevertTo);
goGraduallyTowards(&blueServo4,val4RevertTo);
myservo1.write(blueServo1); // sets the servo position according to the scaled value
myservo2.write(blueServo2);
myservo3.write(blueServo3);
myservo4.write(blueServo4);
delay(10);
}
mode=2;


}
if (data == 3 and blueServo1 < 180 )
{
blueServo1=blueServo1+1;
delay(20);


}
if (data == 4 and blueServo1 >0)
{
blueServo1=blueServo1-1;
delay(20);
}
if (data == 5 and blueServo2 < 180 )
{
blueServo2=blueServo2+1;
delay(20);

}
if (data == 6 and blueServo2 >60)
{

blueServo2=blueServo2-1;
delay(20);
}
if (data == 7 and blueServo3 <90 )
{

blueServo3=blueServo3+1;
delay(20);

}
if (data == 8 and blueServo3 >0)
{

blueServo3=blueServo3-1;
delay(20);
}
if (data == 9 and blueServo4 <180)
{

blueServo4=blueServo4+1;
delay(20);

}
if (data == 0 and blueServo4 >60)
{

blueServo4=blueServo4-1;
delay(20);
}

}

if (mode == 1) // if in manual mode
{
if (mySerial.available()) {
mode=3;
}
timeslooped=timeslooped + 1;
val1 = val1+analogRead(potpin1); // reads the value of the potentiometer (value between 0 and 1023) and makes the value, the sum of seven 
val2 = val2+analogRead(potpin2); // this is to make it jitter less because it is an average
val3 = val3+analogRead(potpin3);
val4= val4+analogRead(potpin4);

if (timeslooped>=7) //if seven values have been added
{
val1avg= val1/7; // take an average
val2avg=val2/7;
val3avg=val3/7;
val4avg=val4/7;



val1avg = map(val1avg, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180), using the average value
val2avg= map(val2avg,0,1023,60,180);
val3avg= map(val3avg,2,1023,0,90);
val4avg= map(val4avg,0,1023,60,180);


val1RevertTo= val1avg;
val2RevertTo= val2avg;
val3RevertTo= val3avg;
val4RevertTo= val4avg;

myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
// 
timeslooped=0; // reset loop
val1=0;
val2=0;
val3=0;
val4=0;
}
}
else if( mode == 2)
{

if (setposition<200) { // this variable ensures that all arms are in correct possition before starting to search
goGraduallyTowards(&val1avg,1); // function that gradually increments a value to another value
goGraduallyTowards(&val2avg,108);
goGraduallyTowards(&val3avg, 90);
goGraduallyTowards(&val4avg,60);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
Serial.println("STILL SETTING");
}
else if (setposition >= 200 and foundObject==false) // if position is in start, and object is not yet found
{

goAround(); // function that sweeps arm across and searches for object in proximity

}

else if (setposition >= 200 and foundObject==true)
{

while (distance >4 and distance < 20) // if object is found, make the arm go forward(and up to stay at level) until 3 cm away from object
{
Ultrasonic();
val4avg=val4avg+4;
val2avg=val2avg+3;
// val4avg=val4avg+5;
delay(200);
myservo2.write(val2avg);
myservo4.write(val4avg);
Serial.println(distance);
}
while ((distance <=4) or (distance > 20)) // once within 3 (or the reading reads incorrect value because it is too close) close arms 
{
if (val3avg>0){
val3avg--;
delay(30);
myservo3.write(val3avg);
}

else if (val3avg<70) //and (abs(val4avg-130)>5) and (abs(val2avg-90)>5) // once arms are closed, move object back and up
{
if (endposition<50)
{
val1 = analogRead(potpin1); // reads the value of the potentiometer (value between 0 and 1023) and makes the value, the sum of seven 
val2 = analogRead(potpin2); // this is to make it jitter less because it is an average
val3 = analogRead(potpin3);
val4= analogRead(potpin4); 

val1 = map(val1, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180), using the average value
val2= map(val2,0,1023,60,180);
val3= map(val3,2,1023,0,90);
val4= map(val4,0,1023,60,180);
goGraduallyTowards(&val1avg, val1);
goGraduallyTowards(&val2avg, val2);
goGraduallyTowards(&val3avg, val3);
goGraduallyTowards(&val4avg, val4); 
myservo4.write(val4avg); // 
myservo2.write(val2avg); // 
myservo1.write(val1avg); // 
myservo3.write(val3avg); // 
endposition=endposition+1;
Serial.println("STILL HERE");
Serial.println(endposition);
}
else if (endposition >= 50)
{ 
setposition = 0; // go back to mode one and reset variables
rotatingPosition = 1;
clockwise= true;
foundObject= false;
mode=1;
endposition=0;
Serial.println("YES");
Serial.println("MODE");
Serial.println(mode);
return(mode);

}
}
}


}



}

}

int goGraduallyTowards(int *x, int y)
{
Serial.println("GRADUAL");
if ( (abs(*x-y))<3)
{
setposition=setposition+1;

//
}
else if ( *x < y)
{
*x=*x+1;
Serial.println("value x up");
Serial.println(*x);
//delay(500);
}
else if ( *x > y)
{
*x=*x-1;
Serial.println(*x);
Serial.println("value x down");
// delay(500);
}

//return x;

}
//PROBLEM--- DOESNT RESET NUMBER OF INT X
//MODEL LIKE OTHER ONE


int goAround() 
{

while (( rotatingPosition <180 ) and (clockwise == true) )
{
Ultrasonic();
rotatingPosition=rotatingPosition+3;
delay(200);
Serial.println( distance);
myservo1.write(rotatingPosition);

if (distance < 20)
{
foundObject=true;
return(distance);

}


}
while (( rotatingPosition>=180) and (clockwise ==true))
{
clockwise = false;
rotatingPosition=178;
myservo1.write(rotatingPosition);

return(rotatingPosition);

}
while (( rotatingPosition>1) and (clockwise==false))
{
rotatingPosition= rotatingPosition-3;
delay(30);
Serial.println( rotatingPosition);

myservo1.write(rotatingPosition);


}

while (( rotatingPosition<=1)and (clockwise==false))
{
rotatingPosition=1;
clockwise=true;
myservo1.write(rotatingPosition);
return(rotatingPosition);

}

}
int Ultrasonic()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
Serial.println(distance);
}

int checkForButton()
{


if (digitalRead(2)== true) // IF SWITCH IS PRESSED
{
delay(500);

if (mode==1)
{
mode=2;
val1RevertTo= val1avg;
val2RevertTo= val2avg;
val3RevertTo= val3avg;
val4RevertTo= val4avg;
Serial.println("MAKING ");
}
else if (mode==2) /// if the mode is one, make it two. If two, make one
{

mode=1;
goGraduallyTowards(&val1avg,val1RevertTo);
goGraduallyTowards(&val2avg,val2RevertTo);
goGraduallyTowards(&val3avg, val3RevertTo);
goGraduallyTowards(&val4avg,val4RevertTo);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
Serial.println("MOVING BACK");

} 
}
if (digitalRead(2)== true) // IF SWITCH IS PRESSED
{
delay(500);
// Serial.println("READ"); //print read
if (mode==1)
{
mode=2;
val1RevertTo= val1avg;
val2RevertTo= val2avg;
val3RevertTo= val3avg;
val4RevertTo= val4avg;
}
else if (mode==2 and (abs(val1avg-val1RevertTo)<5) ) /// if the mode is one, make it two. If two, make one
{
mode=1;
goGraduallyTowards(&val1avg,val1RevertTo);
goGraduallyTowards(&val2avg,val2RevertTo);
goGraduallyTowards(&val3avg, val3RevertTo);
goGraduallyTowards(&val4avg,val4RevertTo);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);

} 
}

if (mode==2)
{
digitalWrite(8,true); // IF mode Two, turn on light
}
else if (mode==1)
{
digitalWrite(8,false);
setposition=0;
}// waits for the servo to get there
}

2nd Milestone: Code Arm To Work Autonomously

For my second milestone, I added an autonomous function to my 4 joint arm. In order to do this, I used an ultra-sonic sensor and mounted it on the top of the arm. When a user clicks the “change mode” button, the arm moves to a position where it is close to the ground, parallel to it, and at “3 O’ Clock”. In order to make this happen, I coded a function which gradually increments a value until it reaches the goal value. Once the arm reaches its starting position, the arm then rotates counter-clockwise, while the ultra-sonic sensor searches for an object within 20 cm. If the sensor detects an object. Ultra-sonic sensor has two “eyes,” one for sending waves and one for receiving them. The Arduino communicates to one of the eyes to send waves at a very high rate, and when a wave bounces off of an object and returns to the second eye, a pulse is given back to the arduino. The arduino measures the amount of time it took for the wave to come back, and determines a distance based on that. If the sensor detects an object, the forward and up motors are incremented forward, until the distance measured is less than 4 cm. At that point, the next sequence begins and the claws close, and then the object is lifted into the air. One set back I had when coding this process was in the “gradual move” function. This function takes in two parameters and increments the first value until it reaches the second. Several times, the value I wanted to increment was a global variable, which cannot be changed when it is a parameter of a function. In order to solve this, I learned about pointers. I learned how to reference a space in memory, and change its content. This will help me with engineering projects in the future.

Ultra-sonic sensor

Ultra-sonic sensor attached to arduino

#include <Servo.h>

Servo myservo1; // create servo object to control a servo
Servo myservo2; // create servo object to control a servo
Servo myservo3; // create servo object to control a servo
Servo myservo4; // create servo object to control a servo

int potpin1 = 0; // analog pin used to connect the potentiometer
int potpin2= A1; // analog pin used to connect the potentiometer
int potpin3= A2; // analog pin used to connect the potentiometer
int potpin4= A3;// analog pin used to connect the potentiometer

int val1=0; // variable to read the value from the analog pin
int val1avg=0; // variable to read the value from the analog pin
int val1RevertTo; // variable that keeps value of potentiameter
int val2=0; // variable to read the value from the analog pin
int val2avg=0; // variable to read the value from the analog pin
int val2RevertTo; // variable that keeps value of potentiameter
int val3=0; // variable to read the value from the analog pin
int val3avg=0; // variable to read the value from the analog pin
int val3RevertTo ; // variable that keeps value of potentiameter
int val4=0; // variable to read the value from the analog pin
int val4avg=0;// variable to read the value from the analog pin
int val4RevertTo; // variable that keeps value of potentiameter
int timeslooped = 0; // variable to read the value from the analog pin

// For ultrasonic
const int trigPin = 13;
const int echoPin = 12;
// defines variables
long duration;
int distance;

int mode = 1; //Mode of either manual or autonomous
int setposition = 0;
int rotatingPosition = 1;
bool clockwise= true;
bool foundObject= false;
int endposition;

void setup() {
myservo1.attach(9); // attaches the servo1 on pin 9 to the servo object
myservo2.attach(10); // attaches the servo2 on pin 10 to the servo object
myservo3.attach(11); // attaches the servo3 on pin 11 to the servo object
myservo4.attach(3); // attaches the servo4 on pin 4 to the servo object

pinMode(2,INPUT); // attach button reader
pinMode(8, OUTPUT); // attach mode indicator LED

pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600);
}

void loop() {

checkForButton(); // function that checks if the button is pressed and if it is, changes modes

if (mode == 1) // if in manual mode
{

timeslooped=timeslooped + 1;
val1 = val1+analogRead(potpin1); // reads the value of the potentiometer (value between 0 and 1023) and makes the value, the sum of seven
val2 = val2+analogRead(potpin2); // this is to make it jitter less because it is an average
val3 = val3+analogRead(potpin3);
val4= val4+analogRead(potpin4);

if (timeslooped>=7) //if seven values have been added
{
val1avg= val1/7; // take an average
val2avg=val2/7;
val3avg=val3/7;
val4avg=val4/7;

val1avg = map(val1avg, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180), using the average value
val2avg= map(val2avg,0,1023,60,180);
val3avg= map(val3avg,2,1023,0,90);
val4avg= map(val4avg,0,1023,60,180);

val1RevertTo= val1avg;
val2RevertTo= val2avg;
val3RevertTo= val3avg;
val4RevertTo= val4avg;

myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
//
timeslooped=0; // reset loop
val1=0;
val2=0;
val3=0;
val4=0;
}
}
else if( mode == 2)
{

if (setposition<200) { // this variable ensures that all arms are in correct possition before starting to search
goGraduallyTowards(&val1avg,1); // function that gradually increments a value to another value
goGraduallyTowards(&val2avg,108);
goGraduallyTowards(&val3avg, 90);
goGraduallyTowards(&val4avg,60);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
Serial.println("STILL SETTING");
}
else if (setposition >= 200 and foundObject==false) // if position is in start, and object is not yet found
{

goAround(); // function that sweeps arm across and searches for object in proximity

}

else if (setposition >= 200 and foundObject==true)
{

while (distance >4 and distance < 20) // if object is found, make the arm go forward(and up to stay at level) until 3 cm away from object
{
Ultrasonic();
val4avg=val4avg+4;
val2avg=val2avg+3;
// val4avg=val4avg+5;
delay(200);
myservo2.write(val2avg);
myservo4.write(val4avg);
Serial.println(distance);
}
while ((distance <=4) or (distance > 20)) // once within 3 (or the reading reads incorrect value because it is too close) close arms
{
if (val3avg>0){
val3avg--;
delay(30);
myservo3.write(val3avg);
}
else if (val3avg<70) //and (abs(val4avg-130)>5) and (abs(val2avg-90)>5)) // once arms are closed, move object back and up
{

goGraduallyTowards(&val4avg, 130);
goGraduallyTowards(&val2avg, 90);
myservo4.write(val4avg); //
myservo2.write(val2avg); //

if (digitalRead(2)== true) // IF SWITCH IS PRESSED
{
setposition = 0; // go back to mode one and reset variables
rotatingPosition = 1;
clockwise= true;
foundObject= false;
mode=1;

}
}

}

}

}

}

int goGraduallyTowards(int *x, int y)
{
Serial.println("GRADUAL");
if ( (abs(*x-y))<3)
{
setposition=setposition+1;
endposition= 1;
//
}
else if ( *x < y)
{
*x=*x+1;
Serial.println("value x up");
Serial.println(*x);
//delay(500);
}
else if ( *x > y)
{
*x=*x-1;
Serial.println(*x);
Serial.println("value x down");
// delay(500);
}

//return x;

}
//PROBLEM--- DOESNT RESET NUMBER OF INT X
//MODEL LIKE OTHER ONE

int goAround()
{

while (( rotatingPosition <180 ) and (clockwise == true) )
{
Ultrasonic();
rotatingPosition=rotatingPosition+3;
delay(200);
Serial.println( distance);
myservo1.write(rotatingPosition);

if (distance < 20)
{
foundObject=true;
return(distance);

}

}
while (( rotatingPosition>=180) and (clockwise ==true))
{
clockwise = false;
rotatingPosition=178;
myservo1.write(rotatingPosition);

return(rotatingPosition);

}
while (( rotatingPosition>1) and (clockwise==false))
{
rotatingPosition= rotatingPosition-3;
delay(30);
Serial.println( rotatingPosition);

myservo1.write(rotatingPosition);

}

while (( rotatingPosition<=1)and (clockwise==false))
{
rotatingPosition=1;
clockwise=true;
myservo1.write(rotatingPosition);
return(rotatingPosition);

}

}
int Ultrasonic()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
Serial.println(distance);
}

int checkForButton()
{

if (digitalRead(2)== true) // IF SWITCH IS PRESSED
{
delay(500);

if (mode==1)
{
mode=2;
val1RevertTo= val1avg;
val2RevertTo= val2avg;
val3RevertTo= val3avg;
val4RevertTo= val4avg;
Serial.println("MAKING ");
}
else if (mode==2) /// if the mode is one, make it two. If two, make one
{

mode=1;
goGraduallyTowards(&val1avg,val1RevertTo);
goGraduallyTowards(&val2avg,val2RevertTo);
goGraduallyTowards(&val3avg, val3RevertTo);
goGraduallyTowards(&val4avg,val4RevertTo);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);
Serial.println("MOVING BACK");

}
}
if (digitalRead(2)== true) // IF SWITCH IS PRESSED
{
delay(500);
// Serial.println("READ"); //print read
if (mode==1)
{
mode=2;
val1RevertTo= val1avg;
val2RevertTo= val2avg;
val3RevertTo= val3avg;
val4RevertTo= val4avg;
}
else if (mode==2 and (abs(val1avg-val1RevertTo)<5) ) /// if the mode is one, make it two. If two, make one
{
mode=1;
goGraduallyTowards(&val1avg,val1RevertTo);
goGraduallyTowards(&val2avg,val2RevertTo);
goGraduallyTowards(&val3avg, val3RevertTo);
goGraduallyTowards(&val4avg,val4RevertTo);
myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);

}
}

if (mode==2)
{
digitalWrite(8,true); // IF mode Two, turn on light
}
else if (mode==1)
{
digitalWrite(8,false);
setposition=0;
}// waits for the servo to get there
}

1st Milestone: Build structure and connect potentiometers

My name is Eytan and I am a rising senior at SAR High School. I chose to make a 4 joint robotic arm for my main project. I just completed my first milestone, finishing the structure of the arm, as well as making it controllable through 4 potentiometers and an arduino. A potentiometer is a three prong device that takes in power and ground, and lets out a certain amount of current. The way it does this is it acts as a variable resistor, allowing the user to choose how much current passes through. The current is connected to the arduino, and is read as a value between 0 and 1023. Next, the arduino converts this into a degree value (0-180) and communicates to the servo where to be. The robotic arm has 4 servos. There is a servo on the bottom that allows the arm base to move 180 degrees. The second servo allows the arm to move forwards and backwards. This allows it to reach out for the grab. A third servo controls vertical motion, and a last one allows for the claw to open and close. In my next milestones I hope to allow my robot to operate autonomously using ultra-sonic senors, as well as be controlled by an app.

Set Back

  1. The arm was shaking a lot and not staying still
  2. It glitched out often and would change positions rapidly and then come back rapidly

Solution

  1. I added code that instead of sending every value to the servo, the program added every seven values together and then sent the average of those numbers
  2. I also added code that if the command to the servo is 5 degrees more than a few milliseconds ago, it will cancel it as well

Diagram of potentiometer

Diagram of Potentiometer connection to Arduino

#include <Servo.h>

Servo myservo1; // create servo object to control a servo
Servo myservo2; // create servo object to control a servo
Servo myservo3; // create servo object to control a servo
Servo myservo4; // create servo object to control a servo

int potpin1 = 0; // analog pin used to connect the potentiometer
int potpin2= A1; // analog pin used to connect the potentiometer
int potpin3= A2; // analog pin used to connect the potentiometer
int potpin4= A3;// analog pin used to connect the potentiometer

int val1=0; // variable to read the value from the analog pin
int val1avg=0; // variable to read the value from the analog pin
int val2=0; // variable to read the value from the analog pin
int val2avg=0; // variable to read the value from the analog pin
int val3=0; // variable to read the value from the analog pin
int val3avg=0; // variable to read the value from the analog pin
int val4=0; // variable to read the value from the analog pin
int val4avg=0;// variable to read the value from the analog pin
int timeslooped = 0; // variable to read the value from the analog pin

void setup() {
myservo1.attach(9); // attaches the servo1 on pin 9 to the servo object
myservo2.attach(10); // attaches the servo2 on pin 10 to the servo object
myservo3.attach(11); // attaches the servo3 on pin 11 to the servo object
myservo4.attach(3); // attaches the servo4 on pin 4 to the servo object

Serial.begin(9600);
}

void loop() {
timeslooped=timeslooped + 1;
val1 = val1+analogRead(potpin1); // reads the value of the potentiometer (value between 0 and 1023) and makes the value, the sum of seven
val2 = val2+analogRead(potpin2); // this is to make it jitter less because it is an average
val3 = val3+analogRead(potpin3);
val4= val4+analogRead(potpin4);
Serial.println(val1);
if (timeslooped>=7) //if seven values have been added
{
val1avg= val1/7; // take an average
val2avg=val2/7;
val3avg=val3/7;
val4avg=val4/7;

val1avg = map(val1avg, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180), using the average value
val2avg= map(val2avg,0,1023,60,180);
val3avg= map(val3avg,2,1023,0,180);
val4avg= map(val4avg,0,1023,60,180);

myservo1.write(val1avg); // sets the servo position according to the scaled value
myservo2.write(val2avg);
myservo3.write(val3avg);
myservo4.write(val4avg);

timeslooped=0; // reset loop
val1=0;
val2=0;
val3=0;
val4=0;
}
}

Starter Project: Useless Machine

My name is Eytan, and I am a Rising Senior at SAR High School. I just completed my starter project, the useless machine.

In making this project, I soldered many components, including two resistors, two switches, and a three prong LED. The first Switch, a toggle switch, is connected to power and ground, and based on the position of the switch, lets current flow in one of two directions.

The implications of this are twofold. First it determines the state of the LED. The LED I used is a three pronged LED with a middle ground. LED’s are non-polar, diodes, and therefore current can only flow in one direction. The LED contains two bulbs, and when current runs through the right prong, the green LED is lit, and when current runs through the left prong, the red LED is lit. As I stated before, the first switch determines the direction of the flow of the current. When the switch is in the on position, the current runs through the green LED, and it lights up. However, when the switch is switched to the opposite direction, the current is diverted and goes through the red LED.

The second effect of the switch is the direction of the motor. The motor is polar and based on the direction of the current running through it will run in the opposite direction. When the switch is on, the motor pushes the arm up. When the switch is then pushed off, the direction of current switches and the motor is reversed, bringing the arm down.

The last crucial part of the circuit is the snap switch. The snap switch has a lever that when pressed, opens the circuit, stopping the flow of current. This allows the arm to stop being lowered, and for the LED to not have current flow through it when the arm is in the down position.

Video Presentation of Starter Project

Useless Machine at rest

Useless Machine activated

Circuit 

Diagram

Start typing and press Enter to search