Gesture-controlled RC car with Robot Arm

The gesture controlled rc car with robot arm is a two part project. One part is the glove worn to detect gestures to control the car and arm. The second part is the rc car and robot arm which receives commands from the glove to move.

Name

Ilan

Area of Interest

Electrical Engineering

School

Poly Prep Country Day School

Grade

Incoming Sophomore

Reflection

Whenever I am asked what I want to be when I grow up I always reply “an engineer.” When I would say this everyone would always follow up with what kind of engineer I wanted to be. I never had a real answer to this question because I never had the resources to try or even know what some of these sectors of engineering were. Through Bluestamp, however, I now know what these terms mean and can proudly respond that I want to be an electrical engineer.

Bill of Materials

2x Arduino Uno – https://store.arduino.cc/usa/arduino-uno-rev3 – $22.00

Dual Motor Driver – https://www.elegoo.com – $16.99

Robot Arm Gripper – https://www.sunfounder.com/rollpaw.html – $19.99

2x XBEE Shield – https://www.sparkfun.com/products/12847 – $14.95

2x XBEE Explorer – https://www.sparkfun.com/products/11697 – $24.95

2x XBEE – https://www.amazon.com/XBee – $26.95

Servo – https://hobbyking.com – $6.90

Lithium Ion Battery – https://www.amazon.com – $16.99

2x 12V DC Motor – http://www.dx.com – $6.47

Switch – https://www.sparkfun.com/products/14330 – $1.50

2x Button – https://www.sparkfun.com/products/9190 – $0.50

4x Flex Sensors – https://www.sparkfun.com/products/8606 – $12.95

Portable Charger – https://www.anker.com – $19.99

Wheels – https://www.pololu.com/product/1433 – $9.25

Mounting Hub – https://www.pololu.com/product/1081 – $6.95

Lithium Battery Charger – https://www.amazon.com – $21.75

Final Milestone

Car, Arm and Gun Schematic

screen-shot-2018-08-02-at-2.12.44-pm
Code with Rubber Band Gun

For Glove:

// Router!
int flexSensorPin1 = A0;
int flexSensorPin2 = A1;
int flexSensorPin3 = A2;
int flexSensorPin4 = A3;
int ledPin = 13;
int button = 8;
int button_read = 0;
int fireButton = 7;
int fireButton_read = 0;
int b = 0;
int k = 0;
char s_str1[2];
char s_str2[2];
char s_str3[2];
char s_str4[2];
char command = ‘e’;
String str1, str2, str3, str4;

void setup() {
pinMode(button, INPUT); // The button is going to control if we are going to control either the robot arm or the motors.
pinMode(fireButton, INPUT);
Serial.begin(9600);
}

void loop() {

if (digitalRead(button) == LOW) // check if button was pressed
{
b++;
b = b % 2;
delay(250);
if (b == 0) {
command = ‘s’;
digitalWrite(ledPin, HIGH); // indicator on the hand to know if the motors is going to be controlled or the robot arm
}
else {
command = ‘e’;
digitalWrite(ledPin, LOW);
}
}

// Read the values
int flexS1 = analogRead(flexSensorPin1);
int flexS2 = analogRead(flexSensorPin2);
int flexS3 = analogRead(flexSensorPin3);
int flexS4 = analogRead(flexSensorPin4);

// Numbers below is individual for each of the flex sensors
if (flexS1 < 500) flexS1 = 500;
else if (flexS1 > 600) flexS1 = 600;
if (flexS2 < 390) flexS2 = 390;
else if (flexS2 > 450) flexS2 = 450;
if (flexS3 < 520) flexS3 = 520;
else if (flexS3 > 650) flexS3 = 650;
if (flexS4 < 460) flexS4 = 460;
else if (flexS4 > 660) flexS4 = 660;

// Mapping all the sensor values down between 0-9. (0 = full bent, 9 = unbent)
int flex_1_0to100 = map(flexS1, 600, 500, 9, 0);
int flex_2_0to100 = map(flexS2, 450, 390, 9, 0);
int flex_3_0to100 = map(flexS3, 650, 520, 9, 0);
int flex_4_0to100 = map(flexS4, 640, 460, 9, 0);

// Converting all strings to a single char
str1 = String(flex_1_0to100);
str1.toCharArray(s_str1, 2);

str2 = String(flex_2_0to100);
str2.toCharArray(s_str2, 2);

str3 = String(flex_3_0to100);
str3.toCharArray(s_str3, 2);

str4 = String(flex_4_0to100);
str4.toCharArray(s_str4, 2);

if (command == ‘e’) {
// Send all values to coordinator
Serial.print(“e”); // Indicates the start of the message (e=motors, s=robot arm)
Serial.print(s_str4); // middle
Serial.print(s_str2); // Index-finger
Serial.print(s_str3); // ring-finger
Serial.print(s_str1); // Thumb
if (digitalRead(fireButton) == HIGH) {
Serial.print(“f”);
}
else {
Serial.print(“a”);
}
delay(50);
}
else if (command == ‘s’) {
//Send all values to coordinator
Serial.print(“s”); // Indicates the start of the message (e=motors, s=robot arm)
Serial.print(s_str4); // Thumb
Serial.print(s_str2); // Index finger
Serial.print(s_str3); // Middle finger
Serial.print(s_str1); // Pinky
if (digitalRead(fireButton) == HIGH) {
Serial.print(“f”);
}
else {
Serial.print(“a”);
}
delay(50);
}
}

For Car:

// Coordinator!
#include <Servo.h>
// connect motor controller pins to Arduino digital pins
// motor one
int enA = 9;
int rightMotor1 = 10;
int rightMotor2 = 8;
// motor two
int enB = 5;
int leftMotor1 = 7;
int leftMotor2 = 6;
int claw_ang=90;
int tilt_ang=180;
int fire_ang=180;
Servo claw;
Servo tilt;
Servo fire;

void setup()
{

claw.attach(11);
tilt.attach(3);
fire.attach(2);
pinMode(rightMotor1, OUTPUT);
pinMode(rightMotor2, OUTPUT);
pinMode(leftMotor1, OUTPUT);
pinMode(leftMotor2, OUTPUT);
Serial.begin(9600);
tilt.write(179);
analogWrite (enA,255);
analogWrite (enB,255);

}

void loop()
{

if (Serial.available() >=6 ) {
char incomingByte1 = Serial.read();
char incomingByte2 = Serial.read();
char incomingByte3 = Serial.read();
char incomingByte4 = Serial.read();
char incomingByte5 = Serial.read();
char incomingByte6 = Serial.read();
Serial.println(incomingByte6);
if (incomingByte6==”a’) {
fire_ang-=5;
Serial.println(“Fire”);
fire.write(fire_ang);
}
if(incomingByte1==’e’){ // if the first byte is an ‘e’ then we going to control the motors
int val_1 = incomingByte2-‘0’;
int val_2 = incomingByte3-‘0’;
int val_3 = incomingByte4-‘0’;
// int val_4 = incomingByte5-‘0′;

// For debugging
Serial.println(“Motor mode”);

Serial.println(val_1);
Serial.println(val_2);
Serial.println(val_3);
// Serial.println(val_4);
Serial.println();

//Drive forwards
if(val_2>5 && val_3<5 && val_1==0 ){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, HIGH);
digitalWrite(leftMotor2, HIGH);
digitalWrite(leftMotor1, LOW);
Serial.println(“Forward”);
}
//Drive backwards
else if(val_2<5 && val_3<5 && val_1==0){
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(leftMotor1, HIGH);
Serial.println(“Backwards”);
}
//Drive right
else if(val_2>5 && val_3>5 && val_1==0){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(leftMotor1, LOW);
Serial.println(“Right”);
}
//Drive left
else if(val_2>5 && val_3<5 && val_1>0){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
digitalWrite(leftMotor2, HIGH);
digitalWrite(leftMotor1, LOW);
Serial.println(“Left”);
}

else if (val_2>5 && val_3>5 && val_1>0){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(leftMotor1, LOW);
}

}

else if (incomingByte1==’s’){ // if the first byte is ‘s’ then we will control the robot arm
int val_1 = incomingByte2-‘0’; // val_1 corresponds to the thumb
int val_2 = incomingByte3-‘0’; // val_2 corresponds to index finger
int val_3 = incomingByte4-‘0’; // val_3 corresponds to the middle finger
// int val_4 = incomingByte5-‘0’; // val_4 corresponds to the pinky

//For debugging
Serial.println(“Robot arm mode”);
Serial.println(val_1);
Serial.println(val_2);
Serial.println(val_3);
Serial.println();

// Close claw

if( val_2>5 && val_3>5 && val_1<5){
claw_ang-=5;
Serial.println(“Close”);
}
// Open claw
else if (val_2<5 && val_3<5 && val_1<5){
claw_ang+=5;
Serial.println(“Open”);
}
// Tilt forward
else if (val_2>5 && val_3<5 && val_1<5){
tilt_ang+=10;
Serial.println(“Down”);
}
//Tilt backward
else if (val_2<5 && val_3>5 && val_1>5){
tilt_ang-=10;
Serial.println(“Up”);
}

}
if (claw_ang>180){
claw_ang=180;
}

if (claw_ang<30){
claw_ang=30;
}
if (tilt_ang<130){
tilt_ang=130;
}
if(tilt_ang>180){
tilt_ang=180;
}

// For debugging
/* Serial.println(“Claw angle:”);
Serial.println(claw_ang);
Serial.println();
Serial.println(“Tilt angle:”);
Serial.println(tilt_ang);
delay(500);
Serial.println();
*/

claw.write(claw_ang);
tilt.write(tilt_ang);

delay(10);

if (fire_ang==0){
fire_ang=180;
}
}

delay(10);
}

For my final milestone I made a rubber band gun, the gun can shoot 5 rubber bands before being reloaded and can be fired while the car is moving. I first 3D printed a part to connect to a servo and hold the rubber bands. I connected this part to the servo so it can spin and release the rubber bands. I then glued the  servo to a piece of wood and attached it to the chassis. I then used a screw and the longest screw spacer I could find as the pin to stretch the rubber bands to. I then attached a button to the glove which when pressed sends a message to the car telling the servo to spin. Finally, I filed a divot in the screw spacer to stabilize to rubber bands and ensure they fire correctly.

Third Milestone

For my third milestone I finished my base project. For this I had to complete my code for my arm. To do this I used a very similar system of if statements that I used for my car. The code had two problems in the beginning mainly stemming from the fact that the example code I referred to, in order to create my code had its servos facing the opposite direction as mine. This resulted in the code doing exactly the opposite of what I had intended. Another problem I had was that my claw wouldn’t close all the way. This was because of a minimum for the servo that I set, this was an easy fix of just changing the value of the minimum. The thing I had to do to finish my project was coding the button to switch whether I was controlling the car or arm. I did this by making it so when the button is pressed on the glove it sends a different signal to the car making it control either the car or the arm.

Car and Arm Code

// Coordinator!
#include <Servo.h>
// connect motor controller pins to Arduino digital pins
// motor one
int enA = 9;
int rightMotor1 = 10;
int rightMotor2 = 8;
// motor two
int enB = 5;
int leftMotor1 = 7;
int leftMotor2 = 6;
int claw_ang=90;
int tilt_ang=180;
Servo claw;
Servo tilt;

void setup()
{

claw.attach(11);
tilt.attach(3);
pinMode(rightMotor1, OUTPUT);
pinMode(rightMotor2, OUTPUT);
pinMode(leftMotor1, OUTPUT);
pinMode(leftMotor2, OUTPUT);
Serial.begin(9600);
tilt.write(179);
analogWrite (enA,255);
analogWrite (enB,255);

}

void loop()
{

if (Serial.available() >=5 ) {
char incomingByte1 = Serial.read();
char incomingByte2 = Serial.read();
char incomingByte3 = Serial.read();
char incomingByte4 = Serial.read();
char incomingByte5 = Serial.read();

if(incomingByte1==’e’){ // if the first byte is an ‘e’ then we going to control the motors
int val_1 = incomingByte2-‘0’;
int val_2 = incomingByte3-‘0’;
int val_3 = incomingByte4-‘0’;
// int val_4 = incomingByte5-‘0′;

// For debugging
Serial.println(“Motor mode”);

Serial.println(val_1);
Serial.println(val_2);
Serial.println(val_3);
// Serial.println(val_4);
Serial.println();

//Drive forwards
if(val_2>5 && val_3<5 && val_1==0 ){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, HIGH);
digitalWrite(leftMotor2, HIGH);
digitalWrite(leftMotor1, LOW);
Serial.println(“Forward”);
}
//Drive backwards
else if(val_2<5 && val_3<5 && val_1==0){
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(leftMotor1, HIGH);
Serial.println(“Backwards”);
}
//Drive right
else if(val_2>5 && val_3>5 && val_1==0){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(leftMotor1, LOW);
Serial.println(“Right”);
}
//Drive left
else if(val_2>5 && val_3<5 && val_1>0){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
digitalWrite(leftMotor2, HIGH);
digitalWrite(leftMotor1, LOW);
Serial.println(“Left”);
}

else if (val_2>5 && val_3>5 && val_1>0){
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(leftMotor1, LOW);
}

}

else if (incomingByte1==’s’){ // if the first byte is ‘s’ then we will control the robot arm
int val_1 = incomingByte2-‘0’; // val_1 corresponds to the thumb
int val_2 = incomingByte3-‘0’; // val_2 corresponds to index finger
int val_3 = incomingByte4-‘0’; // val_3 corresponds to the middle finger
// int val_4 = incomingByte5-‘0’; // val_4 corresponds to the pinky

//For debugging
Serial.println(“Robot arm mode”);
Serial.println(val_1);
Serial.println(val_2);
Serial.println(val_3);
Serial.println();

// Close claw

if( val_2>5 && val_3>5 && val_1<5){
claw_ang-=5;
Serial.println(“Close”);
}
// Open claw
else if (val_2<5 && val_3<5 && val_1<5){
claw_ang+=5;
Serial.println(“Open”);
}
// Tilt forward
else if (val_2>5 && val_3<5 && val_1<5){
tilt_ang+=10;
Serial.println(“Down”);
}
//Tilt backward
else if (val_2<5 && val_3>5 && val_1>5){
tilt_ang-=10;
Serial.println(“Up”);
}

}
if (claw_ang>180){
claw_ang=180;
}

if (claw_ang<30){
claw_ang=30;
}
if (tilt_ang<130){
tilt_ang=130;
}
if(tilt_ang>180){
tilt_ang=180;
}

// For debugging
/* Serial.println(“Claw angle:”);
Serial.println(claw_ang);
Serial.println();
Serial.println(“Tilt angle:”);
Serial.println(tilt_ang);
delay(500);
Serial.println();
*/

claw.write(claw_ang);
tilt.write(tilt_ang);
delay(10);

}

delay(10);
}

Second Milestone

For my second milestone I built the car and arm as well as coded the car. First I connected the motors to the motor driver which allows the motors to move in both directions and have the correct amount of current to flow to the motors. I then connected both servos to the motor driver and arduino. This gives them power, ground and allows you to code them through the arduino. The XBEE shield on top of the arduino connects the XBEE to the arduino allowing the car and glove to communicate. Finally I connected the lithium battery to the motor driver through a switch so I can turn it off and on. The code has two parts the glove code and the car code. On the glove the arduino reads the values of the flex sensors and send it to the car through the XBEE’s. The arduino on the car then assigns those values to being the flex sensors being bent or unbent. I then assigned certain flex sensors being bent to different directions that the car can move. My code says that if I point with my index fingers it goes forward, if all fingers are bent it goes backwards, middle finger bent is to turn right and index and middle bent is to turn left. One problem I encountered while building this was that the gripper and the tilt pan were not compatible so they did not connect. To solve this I made a block of wood that could connect both pieces but also switched to a stronger servo because the one that came with the tilt pan was not strong enough.

First Milestone

Glove Circuit

screen-shot-2018-08-01-at-3.56.30-pm
Glove Code

// Router!
int flexSensorPin1 = A0;
int flexSensorPin2 = A1;
int flexSensorPin3 = A2;
int flexSensorPin4 = A3;
int ledPin=13;
int button=8;
int button_read=0;
int b=0;
int k=0;
char s_str1[2];
char s_str2[2];
char s_str3[2];
char s_str4[2];
char command=’e’;
String str1,str2,str3,str4;

void setup(){
pinMode(button,INPUT); // The button is going to control if we are going to control either the robot arm or the motors.
Serial.begin(9600);
}

void loop(){

if (digitalRead(button) == LOW) // check if button was pressed
{
b++;
b=b%2;
delay(250);
if (b==0){
command=’s’;
digitalWrite(ledPin,HIGH); // indicator on the hand to know if the motors is going to be controlled or the robot arm
}
else {
command=’e’;
digitalWrite(ledPin,LOW);
}
}

// Read the values
int flexS1 = analogRead(flexSensorPin1);
int flexS2 = analogRead(flexSensorPin2);
int flexS3 = analogRead(flexSensorPin3);
int flexS4 = analogRead(flexSensorPin4);

// Numbers below is individual for each of the flex sensors
if (flexS1 < 500) flexS1 = 500;
else if (flexS1 > 600) flexS1 = 600;
if (flexS2 < 390) flexS2 = 390;
else if (flexS2 > 450) flexS2 = 450;
if (flexS3 < 520) flexS3 = 520;
else if (flexS3 > 650) flexS3 = 650;
if (flexS4 < 460) flexS4 = 460;
else if (flexS4 > 660) flexS4 = 660;

// Mapping all the sensor values down between 0-9. (0 = full bent, 9 = unbent)
int flex_1_0to100 = map(flexS1, 600, 500, 9, 0);
int flex_2_0to100 = map(flexS2, 450, 390, 9, 0);
int flex_3_0to100 = map(flexS3, 650, 520, 9, 0);
int flex_4_0to100 = map(flexS4, 640, 460, 9, 0);

// Converting all strings to a single char
str1=String(flex_1_0to100);
str1.toCharArray(s_str1,2);

str2=String(flex_2_0to100);
str2.toCharArray(s_str2,2);

str3=String(flex_3_0to100);
str3.toCharArray(s_str3,2);

str4=String(flex_4_0to100);
str4.toCharArray(s_str4,2);

if (command==’e’){
// Send all values to coordinator
Serial.print(“e”); // Indicates the start of the message (e=motors, s=robot arm)
Serial.print(s_str4);
Serial.print(s_str2);
Serial.print(s_str3);
Serial.print(s_str1);
delay(50);
}
else if (command==’s’){
//Send all values to coordinator
Serial.print(“s”); // Indicates the start of the message (e=motors, s=robot arm)
Serial.print(s_str4);
Serial.print(s_str2);
Serial.print(s_str3);
Serial.print(s_str1);
delay(50);
}
}

For my first milestone, I made the glove. This glove has two parts, the flex sensors and the arduino with Xbee shield. The arduino is where the code is uploaded and is how the glove and computer can communicate. The Xbee shield which is connected to the arduino connects a small device called the Xbee to the arduino. The Xbee is a radio communication device that will end up allowing the glove to communicate with the other Xbee which will control the RC car and arm. There is a button which will control whether I am controlling the car or the arm. These wires connect the flex sensors to the arduino and the power source. The flex sensors, as the name suggests, sense if they are bent or unbent. This is because the flex sensors are resistors which, when bent, resist more. Right now I only have code to read the values of the flex sensors when they are bent and unbent. One challenge I faced was trying to keep the wiring organized in order bridge the right wires together. I accomplished this by taking my time and double checking everytime I bridged two wires together to ensure I was doing it correctly. My next step is to work on the other arduino connecting it to the motors for the RC car and the servos for the arm.
Coding & Robotics Camp for Kids Palo Alto

Starter Project

For my starter I made the MintyBoost USB charger. This can charge any device charged with a USB cable.The main thing this device does is converts the three volts that the batteries output to the five volts needed to charge a phone. This is mainly done with the boost converter chip which takes the energy input and raises the voltage while lowering the current which it then outputs. There is also a power inductor which stores energy using a magnetic field. There are also things like resistors and capacitors which control the voltages to make the output as precise as possible so it is high enough to charge a device such as an iPhone while not letting the voltage be too high where it fries any components in the device that is being charged. Another important component is the diode which ensures that the energy only flows from the batteries to the USB port rather than the other way around.  My biggest problem I encountered while creating this project was ensuring the solder did not bridge to anything especially in the sections where the pads were close together. My favorite part of this project was the precision needed to solder everything, this is because I like to do very tedious work.

Leave a Comment

Start typing and press Enter to search

Bluestamp Engineering