Finish Line

1) My second project is to create a finish line for a toy car

all-about-auto-racing-2-650x400

initially, I’ve setup the countdown program with LED, Piezo element and a button to activate the countdown.


2) resource: http://playground.arduino.cc/Code/Stopwatch

using millis to install a timer. activate when the countdown complete and stop when the button is pressed again.

Screenshot 2015-03-20 02.16.05a

the result shows 2.643s


3) resource: http://4tronix.co.uk/arduino/Ultra-Sonic.php

install HC-SR04 ultrasonic distance sensor to detect distance

and a condition was set to the measurement that if the value is invalid (unrealistically high) it will automatically remeasure.

Screenshot 2015-03-20 02.28.13a

there was an invalid measurement (3287cm) at first then it automatically remeasure the distance (6cm)

3.229 is the time measured by the timer.


4) applying speed equation into the code to calculate the speed of the vehicle.

speed = distance / time

Speed = (cm/100) / ((elapsedTime/1000L) + (fractional/1000));

Screenshot 2015-03-20 02.33.42a

first trial – distance: 6 cm

  time: 2.54s

  speed: 0.02 m/s

second trial – distance: 6 cm

 time: 2.26s

 speed: 0.03 m/s


5) resource: http://pcomp.resourcestore.net/photo-resistor/

install a Light sensor and a laser diode as a light-gate

using the light-gate as a trigger to stop the timer.

Screenshot 2015-03-20 02.39.54a


8) resourc: http://www.dreamdealer.nl/tutorials/connecting_a_1602a_lcd_display_and_a_light_sensor_to_arduino_uno.html

install and setup the 1602 LCD screen to display the countdown, time measured and speed calculated


9) correcting the speed equation due to acceleration is involved in the scenario.

changing the speed equation from

Speed = (cm/100) / ((elapsedTime/1000L) + (fractional/1000));

to

speed


10) using motion equation and rearrangement to calculate acceleration of the vehicle

accel


11) research the creation of characters for the LCD screen

resource: http://www.engineersgarage.com/microcontroller/8051projects/create-custom-characters-LCD-AT89C51-circuit

understanding the layout and binary coding for creating character

resource: http://www.arduino.cc/en/Reference/LiquidCrystalCreateChar

assigning the characters and displaying them on the LCD display

Picture4

byte car1[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B01110,
 B00011,
 B00001,
};
byte car2[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00111,
 B01100,
 B11100,
};
byte car3[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B11000,
 B01100,
 B00111,
};
byte car4[8] = {
 B00111,
 B01111,
 B01011,
 B01010,
 B01110,
 B01110,
 B00110,
 B00000,
};
byte car5[8] = {
 B00100,
 B11111,
 B00000,
 B01110,
 B11111,
 B11011,
 B11111,
 B01110,
};
byte car6[8] = {
 B00001,
 B11111,
 B11111,
 B01110,
 B01110,
 B01110,
 B01110,
 B00000,
};
byte car7[8] = {
 B11111,
 B11111,
 B00000,
 B01110,
 B11111,
 B11011,
 B11111,
 B01110,
};
byte car8[8] = {
 B00000,
 B11100,
 B11110,
 B01011,
 B01111,
 B01001,
 B01111,
 B00000,
};

due to technical limitation only 8 characters can be assigned.


12) use display scroll to move the car as an animation feature

resource: http://www.arduino.cc/en/Reference/LiquidCrystalScrollDisplayLeft

for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
lcd.scrollDisplayRight();
}

*due to lighting difficult the animation cannot be filmed therefore I created an animation that is identical to what is display on the LCD screen*

installing the animation in the void setup as a start-up screen, the animation will run automatically when the power is on.


13) add a servo to the unit as a lock to hold the vehicle in place and let the vehicle go when the countdown is complete

resource: http://pcomp.resourcestore.net/servo-sweep/

 for(pos = 90; pos>=1; pos-=1)
 {
 myservo.write(pos);
 delay(5);
 }

14) the flow chart shows the routine of the “finish line”

Picture1

Dynamic design – allow distance between the “start” and “finish” to vary by the user.

image3

finish line3_bb

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);

byte car1[8] = {   //create character
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B01110,
  B00011,
  B00001,
};

byte car2[8] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00111,
  B01100,
  B11100,
};

byte car3[8] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B11000,
  B01100,
  B00111,
};

byte car4[8] = {
  B00111,
  B01111,
  B01011,
  B01010,
  B01110,
  B01110,
  B00110,
  B00000,
};

byte car5[8] = {
  B00100,
  B11111,
  B00000,
  B01110,
  B11111,
  B11011,
  B11111,
  B01110,
};

byte car6[8] = {
  B00001,
  B11111,
  B11111,
  B01110,
  B01110,
  B01110,
  B01110,
  B00000,
};

byte car7[8] = {
  B11111,
  B11111,
  B00000,
  B01110,
  B11111,
  B11011,
  B11111,
  B01110,
};

byte car8[8] = {
  B00000,
  B11100,
  B11110,
  B01011,
  B01111,
  B01001,
  B01111,
  B00000,
};

int speaker = 13;

#include <Servo.h>
Servo myservo;
int pos = 0;

int led = 5;
int brightness = 0;
int fadeAmount = 15;

int button = 4;
int buttonValue = 0;
int count = 0;
int lightPin = 0;

long interval = 100;
long previousMillis = 0;
long startTime ;              // start time for stop watch
long elapsedTime ;          // elapsed time for stop watch

int pingPin = 3; //output 10us pulse to this pin
int inPin = 2; //measure return pulse width from this pin
long duration, cm;
int cmdec;
int cmconv = 59; // ratio between pulse width and cm
String s1;
String s2;
String s3;
String s4;

void setup() {
  myservo.attach(6);

  lcd.begin(16, 2);
  lcd.createChar(0, car1);  //assign characters
  lcd.createChar(1, car2);
  lcd.createChar(2, car3);
  lcd.createChar(3, car4);
  lcd.createChar(4, car5);
  lcd.createChar(5, car6);
  lcd.createChar(6, car7);
  lcd.createChar(7, car8);

lcd.setCursor(0,0);
lcd.write(byte(0));
lcd.setCursor(1,0);
lcd.write(byte(1));
lcd.setCursor(2,0);
lcd.write(byte(2));
lcd.setCursor(0,1);
lcd.write(byte(3));
lcd.setCursor(1,1);
lcd.write(byte(4));
lcd.setCursor(2,1);
lcd.write(byte(5));
lcd.setCursor(3,1);
lcd.write(byte(6));
lcd.setCursor(4,1);
lcd.write(byte(7));

for (int positionCounter = 0; positionCounter < 11; positionCounter++) {
    // scroll one position Right:
    lcd.scrollDisplayRight();
    delay(300);
    }
 
 Serial.begin(9600);
  pinMode(speaker, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(pingPin, OUTPUT);
  pinMode(inPin, INPUT);
  }

long microsecondsToCentimeters(long microseconds){
  return microseconds / cmconv;
}

void loop() {
 buttonValue = digitalRead(button);
 delay(10);
 int lightLevel = analogRead(lightPin);
 lightLevel = map(lightLevel, 300, 600, 0, 255);
 lightLevel = constrain(lightLevel, 0, 255);
 Serial.println(lightLevel);

  if(buttonValue==HIGH){
 lcd.clear();
    delay(500);
    count = count +1;
  }
 
if(lightLevel >= 255 && count ==2){
//car passed through light gate
  lcd.clear();
  count = 3;
}
 
 if (count == 1){  
    delay(1000);
 
    lcd.print("3");  //countdown
    countdown();
 
    lcd.print("2");
    countdown();
 
    lcd.print("1");
    countdown();

    digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(pingPin, LOW);
  duration = pulseIn(inPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  s1 = String(cm) +" cm";
  Serial.println(s1);

    if (cm > 300)  //if value is greater than 300cm, re-measure the distance
    count = 1;
    else if (cm <= 300){
 
    start();
    startTime = millis();  //start stopwatch
 
    for(pos = 90; pos>=1; pos-=1)
  {
    myservo.write(pos);  //release the car
    delay(5);
  }
    count = 2;
    } 
 }

  if (count == 3){
   digitalWrite(led, LOW);
  float elapsedTime =   millis() - startTime;
//stops timer
  s2 = String(elapsedTime/ 1000) + "s";
//Calculate  time
 lcd.print(".");  //play animation
 delay(500);
 lcd.print(".");
 delay(500);
 lcd.print(".");
 delay(500);
 lcd.clear();
 
   float m = (float)cm/100; 
 float Speed = (2*m) / (elapsedTime/1000);
//calculate speed
  s3 = String(Speed) + "m/s";
 
 float Acceleration = Speed / (elapsedTime/1000);
//calculate acceleration
  s4 = String(Acceleration) + "m/s^2";
 
  Serial.println(m)
  lcd.setCursor(0,0);
  delay(500);
  lcd.print("Dist:");
  lcd.setCursor(7,0);
  lcd.print(m);  //display distance
  lcd.print("m");
 
   Serial.println(s2);
    lcd.setCursor(0,1);
    lcd.print("Time:");
 
    lcd.setCursor(7,1);
    lcd.print(s2);  //display time
 
      count =4;
 }
 
  if(count == 5){
    Serial.println(s4);
    lcd.setCursor(0,0);
    lcd.print("Accel:");
    lcd.setCursor(7,0);
    lcd.print(s4);  //display acceleration
 
    Serial.println(s3);     
  lcd.setCursor(0,1);
    lcd.print("Speed:");  //display speed
  lcd.setCursor(7,1);
  lcd.print(s3);
 
  count =6;
  }
 
  if(count == 7){
    for(pos = 0; pos < 90; pos += 1)
  {                               
    myservo.write(pos);  //reset servo
    delay(5);
  }
    count = 1;
  }
}

void countdown(){  //countdown tone
  tone (speaker,300);
  bright(); 
  delay(500);
  noTone(speaker);
  dim();
  lcd.clear();
  delay(500);
}

void start(){
  tone (speaker,500);
  lcd.print("START");
  bright();
  delay(500);
  noTone(speaker);
  }
 
void bright(){  //illuminate led
  for (int i=0; i < 17; i++){
  analogWrite(led, brightness);
  brightness = brightness + fadeAmount;
  delay(30);
  }
}

void dim(){  //fade away led
  for (int i=0; i < 17; i++){
  analogWrite(led, brightness);
  brightness = brightness - fadeAmount;
  delay(30);
  }
}


Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s