Car Convoy

by balk211 in Circuits > Arduino

1481 Views, 6 Favorites, 0 Comments

Car Convoy

20180114_214526.jpg

This is an instructable on how to make a Car Convoy that can be controlled by a phone.

Materials:

- 2 Arduino's

- Computer

- Cardboard

- Hot Glue Gun

- Blade and Ruler

- 4 360 Degree Servos

- 4 Extra Wheels

- 2 Red LED's

- 2 Green LED's

- 2 Yellow LED's

- 6 220 Ω Resistors

- 1 Ultrasonic Sensor

- 2 Portable Chargers

- 2 A-B Cable

- String

- Wires

Create the Box

20180109_002208.jpg
20180109_002214.jpg

Use the blade and ruler to cut the cardboard into a box that has a flap that can open at the top.The flap should be able to close fully and make a completely closed box. The structure should be glued securely and should be strong.

Cut Holes for Servos

20180109_003418.jpg
20180109_004211.jpg
20180109_004231.jpg

Use a blade to cut out two holes that will fit the two servos. The holes for the servos should be near the back of the box.

Attach Servos

20180109_002803.jpg
20180109_005806.jpg
20180109_005808.jpg

Insert the two servos into the holes cut in the previous step. Use a hot glue gun to glue the servos in its place, so it cannot be moved.

Attach 2 Front Wheels

20180109_230914.jpg

Poke two Holes through the Cardboard that your front wheels can go through. Be sure to measure the Holes to ensure that the height of both wheels is equal. Put the axle of both wheels through the cardboard. Then use a hot glue gun to ensure that it does not move.

Create Battery Holder

20180109_230917.jpg

To Create a slot for the battery pack you must first measure the length of your box. Cut two slits of cardboard that are of equal length and can fit in your box vertically. Make the space between the cardboard slits the width of the battery pack. Then you can use the hot glue gun to glue the slits permanently to the box.

Insert Battery

20180109_230941.jpg

Place your battery inside along with the power cord. The power cord must be placed with the battery to prevent spacing problems while creating the rest of the car.

Create Holder for Arduino and Circuit Board

20180109_005257.jpg
20180109_011147.jpg
20180109_011221.jpg

Now we must create the board that will hold the circuit and arduino board. this platform will be placed above the battery pack, covering it. Cut out a cardboard piece that has the same measurements as the inside of the box. Then place holes on either side of the board. Place a string through the hole and then hot glue gun it to make sure it does not come out. Do this to the other side as well. These two pieces of string will crate the holders that will be used to easily remove the circuit and arduino board out of the box.

Paint the Car

20180113_155526.jpg
20180113_155534.jpg

Now you can close the box and begin painting the car. Be creative and try to make a unique design that is special to you.

Add LED's and Ultrasonic Sensor

20180113_155606.jpg
20180113_155601.jpg

We can now begin to insert the LED's and the ultrasonic sensor (only second car). In both cars cut out three holes, one at the top and two at the bottom. The top LED will display the leader car. The bottom two LED's will display whether the Bluetooth has connected or not. Insert the LED's through the holes and hot glue gun them to the cardboard.

Poke A hole through the front of the second car. That is wide enough for the four ultrasonic sensor pins. Insert the sensor through the hole.

Add Lock to Flap

20180113_155640.jpg
20180113_155620.jpg
20180113_155648.jpg

The last part in creating your car is to create the flap that will be used to lock the lid of the box. There are many ways to do this and this is simply one of the ways.

Take a wire or a string-like piece. Connect a small flat cardboard piece to the wire and glue it together. Then glue the wire onto the box. Poke a hole through the outside of the box that will allow the small flat cardboard piece to fit through. Simply put this piece through the box then through the flap.

Create Circuit

Circuit Diagram.jpg
20180113_160655.jpg
20180113_160705.jpg

Now that we have created the cars and we can now create the circuit. Use the circuit diagram above to help you create circuit/wiring of the parts. The second car will not require the ultrasonic sensor.

Create Program

Arduino.jpg

//CODE FOR CAR 1

/************************************************

/instantiate servo

#include

Servo RServo;//create servo object to control right servo

Servo LServo;//create servo object to control left servo

/************************************************

************************************************

/variables for car movements

int RServoPin = 13; //left wheel

int LServoPin = 12; //right wheel

int RServoSpeed = 90; //right wheel speed

int LServoSpeed = 90; //left wheel speed

int speed = 0; //speed set by bluetooth

//variables for car positions

int carPosition = 0; // 1 = Arrow, 2 = Vertical Line, 3 = Horizontal Line

int prevCarPosition = 2;

int carLeader = 1; // 1 = car 1, 2 = car 2, 3 = car 3

int prevCarLeader = 0;

int flag = 0; // count for loop checks

int flag2 = 1;

int lastAction = 0;

/************************************************

/variables for timing

long startTime = 0;

long endTime = 0;

long waitTime = 0;

long currentTime = 0;

/************************************************/

char data = 'S';

// Data is used for inputs from bluetooth /

/ S = stop

// F = forward

// L = left

// R = right

// G = forward/left

// I = forward/right

// B = backward

// H = backward/left

// J = backward/right

//variables for ultrasonic sensor

int trigPin = 10;

int echoPin = 11;

long duration;

int distance = 0;

/************************************************/

void setup() {

//servo attach and setup

RServo.attach(RServoPin);//attachs the servo on pin 13 to servo object

RServo.write(RServoSpeed);//back to stop

LServo.attach(LServoPin);//attachs the servo on pin 12 to servo object

LServo.write(LServoSpeed);//back to stop

// Default connection rate for BT module

Serial.begin(9600);

delay(1500);

pinMode(6, OUTPUT); // set pin to input

digitalWrite(6, HIGH); // turn on pullup resistors

pinMode(5, OUTPUT);

pinMode(7, OUTPUT);

/************************************************

/lineup cars

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

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

}

/************************************************/

void loop() {

//Checks to see if car is leader or not

if (carLeader == 1) //this car is leader

{

LeaderMovement(); //calls normal bluetooth check with no timing

Speed(); //checks to see if speed was adjusted

CarPosition();

Leader(); // check to see if leader has changed and changes leaders

digitalWrite(5, HIGH);

}

else if (carLeader == 2) //other car is leader

{

FollowerMovement(); //calls second bluetooth check with timing

Speed();

CarPosition(); //checks to see if car positions were changed

Leader();

digitalWrite(5, LOW);

}

if(Serial.available() > 0)

{

data = Serial.read(); //debug variable

Serial.println(data); //debug input

digitalWrite(6, LOW);

digitalWrite(7, HIGH);

}

if (data == 'V')

{

while(distance != 14)

{

digitalWrite(trigPin, LOW);

delayMicroseconds(2);

digitalWrite(trigPin, HIGH);

delayMicroseconds(10);

digitalWrite(trigPin, LOW);

duration = pulseIn(echoPin, HIGH);

distance= duration*0.034/2;

//Prints the distance on the Serial Monitor

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

//Serial.println(distance);

if (distance > 14)

{

RServo.write(85);

LServo.write(95);

}

else if (distance < 14)

{

RServo.write(95);

LServo.write(85);

}

}

data = 'S';

}

}

/************************************************/

void LeaderMovement()

{

//check to see bluetooth for input and move car according to input//

switch(data)

{

case 'S':

if (lastAction == 0)

{

RServo.write(90);

LServo.write(90);

}

else if (carPosition == 2 && lastAction == 1) //leader turned left

{

RServo.write(80);

LServo.write(100);

delay (1800);

}

else if (carPosition == 2 && lastAction == 2) //leader turned right

{

RServo.write(80);

LServo.write(100);

delay (1800);

}

lastAction = 0;

break;

case 'F':

RServo.write(RServoSpeed);

LServo.write(LServoSpeed);

break;

case 'L':

if (carPosition == 1)

{

RServo.write(85);

LServo.write(93);

}

if (carPosition == 2)

{

RServo.write(RServoSpeed);

LServo.write(90);

lastAction = 1;

}

else if (carPosition == 3)

{

RServo.write(87);

LServo.write(90);

}

else

{

RServo.write(RServoSpeed);

LServo.write(90);

}

break;

case 'R':

if (carPosition == 1)

{

RServo.write(86);

LServo.write(97);

}

if (carPosition == 2)

{

RServo.write(90);

LServo.write(LServoSpeed);

lastAction = 2;

}

else if (carPosition == 3)

{

RServo.write(86);

LServo.write(96);

}

else

{

RServo.write(90);

LServo.write(LServoSpeed);

}

break;

case 'G':

RServo.write(RServoSpeed);

LServo.write(LServoSpeed - (2 * (speed - 1)));

break;

case 'I':

RServo.write(RServoSpeed + (2 * (speed - 1)));

LServo.write(LServoSpeed);

break;

case 'B':

RServo.write(RServoSpeed + (speed * 4));

LServo.write(LServoSpeed - (speed * 4));

break;

case 'H':

RServo.write(RServoSpeed + (speed * 4));

LServo.write(LServoSpeed + (2 * (speed - 1)) - (speed * 4));

break;

case 'J':

RServo.write(RServoSpeed - (2 * (speed - 1)) + (speed * 4));

LServo.write(LServoSpeed - (speed * 4));

break;

default:

RServo.write(90);

LServo.write(90);

break;

}

}

void Speed()

{

switch(data)

{

case '0':

speed = 0;

RServoSpeed = 90;

LServoSpeed = 90;

break;

case '1':

speed = 1;

RServoSpeed = 88;

LServoSpeed = 92;

break;

case '2':

speed = 2;

RServoSpeed = 86;

LServoSpeed = 94;

break;

case '3':

speed = 3;

RServoSpeed = 84;

LServoSpeed = 96;

break;

case '4':

speed = 4;

RServoSpeed = 82;

LServoSpeed = 98;

break;

case '5':

speed = 5;

RServoSpeed = 80;

LServoSpeed = 100;

break;

}

}

void FollowerMovement()

{

//check to see bluetooth for input and move car according to input//

switch(data)

{

case 'S': //stop

if (lastAction == 0)

{

RServo.write(90);

LServo.write(90);

}

else if (carPosition == 2 && lastAction == 1) //leader turned left

{

RServo.write(80);

LServo.write(100);

delay (1800);

RServo.write(RServoSpeed);

LServo.write(90);

delay (waitTime);

}

else if (carPosition == 2 && lastAction == 2) //leader turned right

{

RServo.write(80);

LServo.write(100);

delay (1800);

RServo.write(90);

LServo.write(LServoSpeed);

delay (waitTime);

}

//reset variables below

flag = 0;

flag2 = 1;

lastAction = 0;

break;

case 'F': //forward

RServo.write(RServoSpeed);

LServo.write(LServoSpeed);

break;

case 'L': //left

lastAction = 1;

if (carPosition == 2 && flag2 == 1) //*vertical line*

{

startTime = millis();

flag2 = 0;

flag = 1;

}

else if (flag == 1)

{

waitTime = (millis() - startTime);

}

if (carPosition == 3)

{

RServo.write(83);

LServo.write(94);

}

if (carPosition == 1)

{

RServo.write(85);

LServo.write(94);

}

break;

case 'R': //right

lastAction = 2;

if (carPosition == 2 && flag2 == 1) //*vertical line*

{

startTime = millis();

flag2 = 0;

flag = 1; //turn is done

}

else if (flag == 1)

{

waitTime = (millis() - startTime);

//waitTime = (waitTime/15) + waitTime;

}

if (carPosition == 3)

{

RServo.write(90);

LServo.write(92);

}

if (carPosition == 1)

{

RServo.write(89);

LServo.write(93);

}

break;

case 'G': //forward left

/*if (carPosition == 2 && flag == 0) //*vertical line*

{

RServo.write(80);

LServo.write(100);

delay(500);

flag = 1;

}

else if (flag == 1)

{

RServo.write(80);

LServo.write(96);

}*/

RServo.write(RServoSpeed);

LServo.write(LServoSpeed - (2 * (speed - 1)));

break;

case 'I': // forward right

/*if(carPosition == 2 && flag == 0) //*vertical line*

{

RServo.write(80);

LServo.write(100);

delay(500);

flag = 1;

}

else if (flag == 1)

{

RServo.write(84);

LServo.write(100);

}*/

RServo.write(RServoSpeed + (2 * (speed - 1)));

LServo.write(LServoSpeed);

break;

case 'B':

RServo.write(RServoSpeed + (speed * 4));

LServo.write(LServoSpeed - (speed * 4));

break;

case 'H':

RServo.write(RServoSpeed + (speed * 4));

LServo.write(LServoSpeed + (2 * (speed - 1)) - (speed * 4));

break;

case 'J':

RServo.write(RServoSpeed - (2 * (speed - 1)) + (speed * 4));

LServo.write(LServoSpeed - (speed * 4));

break;

}

}

/*************************************************************/

void CarPosition()

{

switch (data)

{

case 'X':

prevCarPosition = carPosition;

carPosition = 1;

ChangeCarPosition();

break;

case 'Y':

prevCarPosition = carPosition;

carPosition = 2;

ChangeCarPosition();

break;

case 'Z':

prevCarPosition = carPosition;

carPosition = 3;

ChangeCarPosition();

break;

}

}

void ChangeCarPosition()

{

if(carLeader == 2)

{

if (prevCarPosition == 1 && carPosition == 2)//

{

RServo.write(100);

LServo.write(90);

delay(1500);

RServo.write(100);

LServo.write(80);

delay(500);

RServo.write(90);

LServo.write(80);

delay(1500);

Stop();

}

else if (prevCarPosition == 1 && carPosition == 3)//

{

RServo.write(80);

LServo.write(100);

delay(1100);

Stop();

}

else if (prevCarPosition == 2 && carPosition == 1)//

{

RServo.write(90);

LServo.write(100);

delay(1500);

RServo.write(80);

LServo.write(100);

delay(500);

RServo.write(80);

LServo.write(90);

delay(1550);

Stop();

}

else if (prevCarPosition == 2 && carPosition == 3)//

{

RServo.write(90);

LServo.write(100);

delay(1500);

RServo.write(80);

LServo.write(100);

delay(500);

RServo.write(80);

LServo.write(90);

delay(1500);

RServo.write(80);

LServo.write(100);

delay(1100);

Stop();

}

else if (prevCarPosition == 3 && carPosition == 1)//

{

RServo.write(100);

LServo.write(80);

delay(1100);

Stop();

}

else if (prevCarPosition == 3 && carPosition == 2)//

{

RServo.write(100);

LServo.write(80);

delay(1000);

RServo.write(100);

LServo.write(90);

delay(1500);

RServo.write(100);

LServo.write(80);

delay(500);

RServo.write(90);

LServo.write(80);

delay(1500);

Stop();

}

}

}

void Leader()

{

switch (data)

{

case 'A':

prevCarLeader = carLeader;

carLeader = 1;

ChangeLeader();

break;

case 'C':

prevCarLeader = carLeader;

carLeader = 2;

ChangeLeader();

break;

}

}

void ChangeLeader()

{

if(carLeader == 2)

{

if ((prevCarLeader == 1 && carLeader == 2) || (prevCarLeader == 2 && carLeader == 1))

{

if (carPosition == 1)

{

RServo.write(80);

LServo.write(100);

delay(200);

RServo.write(90);

LServo.write(100);

delay(1300);

RServo.write(80);

LServo.write(100);

delay(1900);

RServo.write(80);

LServo.write(90);

delay(1300);

RServo.write(100);

LServo.write(80);

delay(3050);

Stop();

}

else if (carPosition == 2)

{

RServo.write(90);

LServo.write(100);

delay(1400);

RServo.write(80);

LServo.write(100);

delay(600);

RServo.write(90);

LServo.write(100);

delay(1400);

RServo.write(80);

LServo.write(100);

delay(3600);

RServo.write(90);

LServo.write(100);

delay(1400);

RServo.write(80);

LServo.write(100);

delay(500);

RServo.write(90);

LServo.write(100);

delay(1350);

Stop();

}

else if (carPosition == 3)

{

RServo.write(80);

LServo.write(100);

delay(1000);

RServo.write(90);

LServo.write(100);

delay(1200);

RServo.write(80);

LServo.write(100);

delay(2200);

RServo.write(80);

LServo.write(90);

delay(1300);

RServo.write(100);

LServo.write(80);

delay(2000);

Stop();

}

}

}

}

void Stop()

{

RServo.write(90);

LServo.write(90);

}

Create App

Screenshot_20180114-225522.png
Screenshot_20180114-211939.png
App Screen 1.jpg
App Screen 2.jpg
App Screen 1B.jpg
App Screen 2B.jpg
App Screen 3B.jpg
App Screen 4B.jpg

We are now on the final, but hardest step. We must create an app that can be used to control the cars by sending data through the Bluetooth. You can use the very simple MIT App Inventor (android user only). Use may use the above pics to create the style of the app. The pictures above also contain the code that will be required.

Follow the instructions above to create the app by yourself, or use the link below to open it.

ai2.appinventor.mit.edu/?galleryId=5614395115438080

Repeat Steps 1-12

Repeat these steps to create the second car.

Enjoy

Car Convoy Set Up
Car Convoy Vertical Line
Car Convoy Horizontal Line
Car Convoy Triangle
Car Convoy Positions/Leader Change
Car Convoy Single Car