Report - ISU Public Homepage Server

Document Sample
Report - ISU Public Homepage Server Powered By Docstoc
					Arduino Powered Robot


  EE 186, Section A
    April 28, 2010




  Daniel O’Connell
    Ben Magstadt
Goals

        The objective in mind that we started this project with was to learn how an Arduino worked.
We began doing this by using simple applications and then decided to advance our control into an
RC car. We planned to strip the car down to its simple motors and use the Arduino to control them
without any outside interference from us. We ordered an infrared sensor to help control the car by
being able to sense where the car was in relation to the wall in front of it, so it could maneuver
obstacles. This was our starting plan, but we planned on having to add some other features as we got
going and saw more applications of the Arduino that we could use.

Arduino

        We ended up choosing to purchase an Arduino Duemilanove to control the car. This board
had 14 digital in/out pins which we felt would be a good amount to control all of the things that we
wanted to. Six of those pins also provided PWM output. After looking up what that was, we
discovered that it was a way of simulating different output voltages by pulsing a wave of standard
voltage. This feature of the Arduino would be very helpful in later controlling the car in different
speeds. The board also contained six analog input pins, which we needed to be able to read the
voltage from the infrared sensor.

        We started out learning how this Arduino worked by trying simple programs out. The first
one we tried was to just continually make an LED turn on and off. These were very simple programs
and schematics, so we increased our level to more complicated levels. We ended up finding
examples to show how the analog inputs and PWM outputs worked. We generally tried to learn the
code from examples that we could find and then went to Arduino’s website when we had a problem
we couldn’t easily find a solution to. One of the functions that the Arduino had that helped
troubleshoot any problems we had, was the ‘println()’. We could print any data that was running
through the Arduino straight to my laptop so we could see where our code was going wrong.

Here is an example of one of the earlier codes that we found to help learn the coding:

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin = 13;       // the number of the LED pin

// variables will change:
int buttonState = 0;                // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:

                                                                                            2|Page
    if (buttonState == HIGH) {
      // turn LED on:
      digitalWrite(ledPin, HIGH);
    }
    else {
      // turn LED off:
      digitalWrite(ledPin, LOW);
    }
}

       When we made the circuit along with the Arduino, we could read when a pin went high
because of the pushbutton and turn on an LED. This was a very simple circuit still, but it showed us
good examples of the code use.

RC Car

        When we stripped down the RC car down, we found that it was very simple. It contained a
board that we took out; we wanted to design all of the circuits for ourselves. All that remained then
was a power supply of six volts and two motors. These motors both ran two directions based on
which way the current went thru it. These motors proved to show us two difficulties. The first
problem was that we could not power them straight from the Arduino. The Arduino could not drive
enough current thru them to run them properly. The second problem was that we had to figure out a
way to be able to run current thru the motor in both directions so that we could control
forward/reverse and right/left. Both of these problems we fixed by using transistors.

Transistors

        We started experimenting with a cheap PNP transistor that we had to try and amplify the
current we got to the motor. We tried to use the Arduino as an input voltage and then use the six volt
battery of the car as the collector voltage. We looked at many different schematics such as the one
below to try and make it work, but continuously failed with the PNP.




        We then went to the part store and were recommended to get a Darlington Transistor. This
was a NPN transistor that was basically one transistor in another. It could handle more power, which
was assumed to be our problem. Here are pictures of how the transistor works inside and the circuit
that we used to make the motors finally run.




                                                                                            3|Page
Forward/Backward-Left/Right

        The last main challenge with the motor was to get it to go forward and reverse. After some
thinking, we figured out how to do it using four transistors. We arranged them how we it shows on
the diagram on the left. Some people compared it to the diagram on the right which is an H bridge.
We felt it was a much better learning experience, however, to construct the circuit by ourselves.




Infrared Sensor

        Now that we could control the motors of the car, we had to make sure that it could avoid
obstacles. For this we bought a Sharp Infrared Sensor. This worked by powering the component as
shown, and then it would send an analog signal back to our Arduino. The signal it sent back varied
with distance in a non-linear way. We had to experiment reading in the signals using this code:

int potent = 0;

int potentValue = 0;

void setup(){
  pinMode(potent, INPUT);
  Serial.begin(9600);
}

void loop(){

                                                                                          4|Page
    potentValue = analogRead(potent);
    Serial.println(potentValue);
    delay(1000);
}

       This showed us that as the object got closer to an object the signal got higher and vice-versa.
From this data we chose 300 as a good stopping value from an object.




Hall-Effect Sensor

        We later found some problem with having consistent turning. We found a solution to this
problem in a hall effect sensor. This basically can detect when there is a magnetic field nearby it,
and then will shut off the current in the circuit. This we can then detect using the Arduino. So we
then glued two magnets to the wheel of the car and put the Hall Effect sensor near enough to detect
them. We could now judge how many rotations the car has gone. This was a much more effective
way to judge movement than by time.




                                                                                            5|Page
Final Project

        After we had each individual part working the last step was to put it all together and start
working on some non trivial code. We choose a breadboard to layout the circuits as a semi
permanent solution. Once we laid out the circuitry on the board and hooked everything to the
Arduino and started testing. First we did some simple tests with it to have it move backwards for a
second and forwards for a second. We used this test to choose a speed that would move the robot
and that we were comfortable with. We set the speed by using PWM pins (Pulse-Width Modulation)
which basically turns the motor on and off different amount of times which in turn controls the
speed. You can set the PWM pins to values between 0 (never on) and 255 (always on). We chose
values between 75 and 110 work best for our application.

         Our next big challenge was to get the robot to turn 90 degrees left or right. We wanted
consistent results that wouldn’t be affected by battery power or different surfaces. Using a timed
based solution wouldn’t work because when the battery is worn down it travels at a slower speed.
This is the main reason we introduced the Hall Effect sensor solution. Using the sensor we can tell
the robot to go forward a certain number of rotations which should give consistent results regardless
of the speed it is traveling at. We added two magnets opposite each other on the wheel to give
greater accuracy.

         We had to do a lot of testing to get the correct amount of rotations for turning. We wanted
the robot to not move much from its original position to lower the risk of coming in contact with
something it couldn’t see. After an hour or so of testing we got it to turn fairly consistently 90
degrees while only moving slightly from its original position. After 4 turns it is off about 20 degrees
from where it should be. Without more precise (expensive) sensing equipment it would be very
difficult to get much more accurate than that.

        Next we wanted to incorporate the IR sensor into our programming. We decide to have our
robot wander in a straight line and when it reaches and object turns right. This works fairly well at
avoiding collisions in most situations. While testing we did have a few times where collisions did
happen. We added a cardboard bumper to the front of the vehicle to soften the blow just in case.
One cause of a collision during testing was that the wire coming from the IR sensor came off so the
robot was basically driving blind. We think that we have eliminated most causes of collision from
the code. During turns the robot is basically blind because the sensor is only on the front so
collisions while turning are still possible.




                                                                                             6|Page
Costs

Parts                                              Price
Arduino                                            ~$45
RC Car                                             ~$10
IR Sensor                                          ~$20
TIP121/TIP122 (8 total)                            Free from the parts store
330/490ohm Resistors (9 total)                     Free from the parts store
Various Wires                                      Included with Arduino
Hall effect Sensor                                 ~$5
Magnets (2000 Gauss)                               ~$3
Breadboard                                         Included with Arduino
Total                                              ~$85


        The actual cost for this project is actually much less than what the numbers say. The RC car
we already had and probably would’ve just been thrown away. The Arduino will probably be used
again for another project or for a learning tool. The IR Sensor will be kept and probably used for
another project or just for fun. This brings the total cost down to around 10 dollar that may not be
used again. Even the remaining components such as the Hall Effect sensor and magnets will be kept
and may even be used again for another project.




                                                                                          7|Page
Final Schematic




                  8|Page
Final Code

//Declarations
int forwardMotor = 3;
int forwardGround = 4;
int backwardMotor = 6;
int backwardGround = 7;
int rightMotor = 9;
int rightGround = 8;
int leftMotor = 11;
int leftGround = 12;
int irSensor = 0;
int wheelTurn = 1;
int output = 0;

int a;
int sensorValue = 0;

//Sets pin modes
void setup() {
  pinMode(forwardMotor, OUTPUT);
  pinMode(forwardGround, OUTPUT);
  pinMode(backwardMotor, OUTPUT);
  pinMode(backwardGround, OUTPUT);
  pinMode(rightMotor, OUTPUT);
  pinMode(rightGround, OUTPUT);
  pinMode(leftMotor, OUTPUT);
  pinMode(leftGround, OUTPUT);
  pinMode(wheelTurn, INPUT);
  pinMode(output, OUTPUT);
  Serial.begin(9600);
}

//Where all the code goes to control the robot.
void loop() {
 forever();
}

//Go Forever avoiding objects
void forever(){
   while(getSensor() < 230){
    forwardOn(true);
  }
  forwardOn(false);
  delay(1000);
  turnRight();
  delay(1000);
}

//Go Turn Around Go
void turnAroundGo(){
  while(getSensor() < 230){
    forwardOn(true);
  }
  forwardOn(false);
  delay(1000);
  turnRight();
  delay(1000);


                                                  9|Page
    turnRight();
    delay(1000);

}
//Sets the motor to forward. When boolean on is false turns off the motor.
void forwardOn(boolean on){
  if (on){
    analogWrite(forwardMotor, 75);
    digitalWrite(forwardGround, HIGH);
  }
  else {
    analogWrite(forwardMotor, 0);
    digitalWrite(forwardGround, LOW);
    delay(100);
  }
}

//Sets the motor to backward. When boolean on is false turns off the motor.
void backwardOn(boolean on){
  if (on){
    analogWrite(backwardMotor, 90);
    digitalWrite(backwardGround, HIGH);
  } else {
    analogWrite(backwardMotor, 0);
    digitalWrite(backwardGround, LOW);
    delay(100);
  }

}

//Turns the steering motor on to the right. The values may have to be ajusted.
void turnWheelRight(){
  digitalWrite(rightMotor, HIGH);
  digitalWrite(rightGround, HIGH);
  delay(100);
}

//Turns the steering motor on to the left. The values may have to be ajusted.
void turnWheelLeft(){
  digitalWrite(leftMotor, HIGH);
  digitalWrite(leftGround, HIGH);
  delay(100);
}

//Stops the turning either way the motor is turning.
void stopTurn(){
  analogWrite(rightMotor, 0);
  digitalWrite(rightGround, LOW);
  analogWrite(leftMotor, 0);
  digitalWrite(leftGround, LOW);
  delay(100);
}

//Backs up until it finds the magnet
void findMagnet(){
  digitalWrite(output, HIGH);
  while(analogRead(wheelTurn) > 100){
    analogWrite(backwardMotor, 90);
    digitalWrite(backwardGround, HIGH);
  }

                                                                        10 | P a g e
    backwardOn(false);
    digitalWrite(output,LOW);
}

//Turns ninety degrees right
void turnRight(){
  for(int i = 0; i < 2; i++){
    findMagnet();
    turnWheelRight();
    analogWrite(forwardMotor, 110);
    digitalWrite(forwardGround, HIGH);
    goRotations(3);
    forwardOn(false);
    stopTurn();
    findMagnet();
    turnWheelLeft();
    analogWrite(backwardMotor, 120);
    digitalWrite(backwardGround, HIGH);
    goRotations(3);
    backwardOn(false);
    stopTurn();
    delay(100);
  }
}

//Turns ninety degrees left
void turnLeft(){
    for(int i = 0; i < 2; i++){
    findMagnet();
    turnWheelLeft();
    analogWrite(forwardMotor, 110);
    digitalWrite(forwardGround, HIGH);
    goRotations(3);
    forwardOn(false);
    stopTurn();
    findMagnet();
    turnWheelRight();
    analogWrite(backwardMotor, 120);
    digitalWrite(backwardGround, HIGH);
    goRotations(3);
    backwardOn(false);
    stopTurn();
    delay(100);
  }
}


//Returns the value gotten for the input pin. 300 is a good value to stop.
int getSensor(){
  sensorValue = analogRead(irSensor);
  return sensorValue;
}

//Delays the current functions until the fixed amount of wheel rotations
void goRotations(int rotations){
  digitalWrite(output, HIGH);
  int a = 0;
  int time = millis();
  while(a < rotations + 1){
    if(analogRead(wheelTurn) < 150){

                                                                           11 | P a g e
       a++; time = millis();
       if(a < rotations){
         delay(500);
       }
     }
     if(millis() - time > 1500){
       a = rotations + 1;
       backwardOn(true);
       delay(1000);
       backwardOn(false);
     }
     }
    digitalWrite(output, LOW);
}

//Accelerates in a positive direction to topSpeed in time amount of seconds linear
ly.
void accelerate(int time, int topSpeed){
  digitalWrite(forwardGround, HIGH);
  for(int i = 1; i <= time; i++){
    analogWrite(forwardMotor, topSpeed / time * i);
    delay(1);
  }
}

//Accelerates in a negitive direction to topSpeed in time amount of seconds linear
ly.
void accelerateBack(int time, int topSpeed){
  digitalWrite(backwardGround, HIGH);
  for(int i = 1; i <= time; i++){
    analogWrite(backwardMotor, topSpeed / time * i);
    delay(1);
  }
}

//Deccelerates from a positive direction to 0 from currentSpeed in time amount of
seconds linearly.
void deccelerate(int time, int currentSpeed){
  for(int i = time; i > 0; i--){
    analogWrite(forwardMotor, currentSpeed / time * i);
    delay(1);
  }
  digitalWrite(forwardGround, LOW);
}

//Deccelerates from a negitive direction to 0 from currentSpeed in time amount of
seconds linearly.
void deccelerateBack(int time, int currentSpeed){
  for(int i = time; i > 0; i--){
    analogWrite(backwardMotor, currentSpeed / time * i);
    delay(1);
  }
  digitalWrite(backwardGround, LOW);
}




                                                                        12 | P a g e
Pictures

This is when we first got the Arduino. We used LEDs to build simple circuits to learn how to use the
Arduino and how to write simple code.




                                                                                        13 | P a g e
This is a picture of when we first got forwards and backwards working on the robot.




                                                                                14 | P a g e
Here is close to our finished circuitry on the breadboard. We doubled the amount of transistors to get
turning to work. As you can also see our circuitry is less scattered than before.




                                                                                          15 | P a g e
Here is a picture of how we have the hall effect sensor and magnet set up to detect distance traveled.




                                                                                           16 | P a g e
Here is a picture of our final design from the front side view.




                                                                  17 | P a g e