Making Furniture Interactive

October 27, 2007

Servo car


For the motorized portion of the assignment, I decided, heck with creativity, I just want to build a self-controlled car. I used a battery to power the arduino, a Parallax Ping Ultrasonic Range Finder, a servo (HS311), and a battery+motor little plastic car without steering that I had lying around. My final product was held together with:

  • Masking tape
  • 3M tabs
  • a bent wire hanger
  • cable ties
  • electrical tape
  • gravity

Good times. The wiring was straightforward – it turns out that neither the servo nor the range finder need external powering (I did the TIP120 thing with my cabinet project, though), and are run off the arduino output pins. After significant coding distress I looked for and obtained a servo library (I posted a link to it) to separate the servo timing from the range finder timing.

With this project I gained a new appreciation for stereo vision. With one stationary servo, the most I could do was wall-following for walls with gradual changes. The code keeps the car attempting to maintain a fixed distance from the wall.

// debug
int ledPin = 3;

// ultrasonic range finder
int signalPin = 4;                // sensor signal pin connected to wiring pin 0
int elapsedtime = 0;
int last_elapsedtime = 0;

// servo
int servoPin = 9;     // Control pin for servo motor
int minPulse = 800;   // Minimum servo position (microseconds)
int maxPulse = 1800;  // Maximum servo position (microseconds)
int angle = 90;        // Amount to pulse the servo
int last_angle = 90;
ServoTimer1 st;

void setup() {
  pinMode(ledPin, OUTPUT);

void loop() {
  elapsedtime = 0;
  pinMode(signalPin, OUTPUT);     // set signalPin as OUTPUT

  // Send 0-1-0 pulse to activate the sensor
  digitalWrite(signalPin, LOW);
  digitalWrite(signalPin, HIGH);
  digitalWrite(signalPin, LOW);  

  // Listen to pulse
  pinMode(signalPin, INPUT);      // set signalPin as INPUT
  elapsedtime = pulseIn(signalPin, HIGH);  // get the length of the pusle while it is HIGH

  // the goal here will be to keep it at a steady 800
  // map 400 to 2000     to     170 to 10
  int med = 2000;
  if (elapsedtime < med)
      if (elapsedtime  med)
      if (elapsedtime > 2 * med)
        angle = 20;
        angle = 60;
  if (elapsedtime == med)
      angle = 90;

  if (abs(angle - last_angle) > 1) {
    last_angle = angle;

  // debug led
  if (elapsedtime == med)
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin, LOW);

  // print value through Serial
  Serial.print("angle ");
  Serial.print("    ");
  Serial.println(elapsedtime, DEC);


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

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

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

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s

Create a free website or blog at

%d bloggers like this: