The Eyes Have It!

He's got his eyes on you!

He’s got his eyes on you!

This is part 5 of my robot series.

As promised, my little robot is back, and this time he’s got his eyes on you. He formerly had to rely only on bumping into things to navigate. To remedy this we had to give him a way of knowing something was in his way before he bumped into it. Although there are a lot of different distance sensors that robots can use to avoid playing bumper cars, I selected an ultrasonic range finder called “Ping” by Parallax. It works on the same principle that dolphins and bats use to navigate – make a high pitched sound, and count the time it takes for an echo to come back to you. And more importantly, it looks really cool – come on, don’t those new eyes give him personality?

Since I didn’t want any of his rapidly expanding spaghetti junction of wires interfering with his new vision, I decided to relocate his controller board further back on his top deck, and cut a new hole to re-route some of the wiring. Hence the minor surgery mentioned in my last post.

Mounting the eyes turned out to be easier than expected, but the bigger question: What should he do with his new-found sense, was trickier. The reason for this is that the eyes don’t work on their own, nor do they work continuously. The controller board has to send a signal to the eyes to send out the ultrasonic sound, then listen for the echo and calculate the distance. This give you a single value (essentially “there is something in front of me at a distance of 50 inches” for example) This process has to be repeated anytime you want to update this information. The simplest way of integrating this, is to set up a rangefinder function – for example hit a button on the remote, and he updates the distance. However, since knowing he’s about to bump into something is a pretty critical function, I decided that it would be a good idea to build it into his main program.

His main program is really just a continuous loop with four parts:

  1. See if the left whisker was hit, then do something
  2. See if the right whisker was hit, then do something
  3. See if a signal was received from the remote control, and do something
  4. Go back to the beginning and do it all again

I could have just added a block in there (point 3 1/2) to use the range-finder. However, since the program zooms through this loop very fast, but our robot doesn’t move that fast, I decided that he might not need to use it everytime it goes through the loop. Just every so often. I set up a counter function to count the number of times it goes through the main loop, and by trial and error, decided that every 500 times it goes through the cycle, it will use the range-finder once. This is still faster than once a second. The upside to this is that it doesn’t overload his processor doing stuff more frequently than needed.

Now he has a value that he can use to do something useful. Or something cool. If you’ve learned anything from my site by now it’s that I like flashing lights, so let’s give him another one of those. We already have the red and green navigation lights, so let’s use yellow. My idea was to flash the yellow LED slowly when something was far away, and quickly when something was close. To do this, I added a few new counters to turn the light on and off every so many times the controller goes through the main loop. It works like the parking distance beeper in some cars. Except with flashing light instead of beeping. True, he already has a speaker, so I could have just used beeps, however I decided against it for two reasons: (1) It would have robbed me of an excuse to add another flashing light, and (2) I didn’t want to drive my spouse crazy with the constant beeping. Here is the new code:

// NEW this is to uses the rangefinder within main program function
main_loop_count++; //New count main loops
if (main_loop_count == 500) { // NEW every so often use the rangefinder
main_loop_count = 0;
pinMode(pingPin, OUTPUT);          // Set pin to OUTPUT
digitalWrite(pingPin, LOW);        // Ensure pin is low
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);       // Start ranging
delayMicroseconds(5);              // with 5 microsecond burst
digitalWrite(pingPin, LOW);        // End ranging
pinMode(pingPin, INPUT);           // Set pin to INPUT
duration = pulseIn(pingPin, HIGH); // Read echo pulse
inches = duration / 74 / 1;        // Convert to inches 
//Serial.println("inches");            // Display result
//Serial.println(inches);            // Display result
delay(100);                     // NEW 
}
// NEW based on values, adjust
if (inches < 80 && inches > 50) { // turn on light flashing
flash_speed_on = 250;
flash_speed_off = 500;
flash_speed_count++;
}
if (inches <= 50 && inches > 25) { // turn on light flashing faster
flash_speed_on = 100;
flash_speed_off = 250;
flash_speed_count++;
}
if (inches <= 25) { // turn on light flashing really fast
flash_speed_on = 50;
flash_speed_off = 100;
flash_speed_count++;
}
if (inches <= 25 && fwd_speed == 2) { // and slow down
slow_forward();
}
if (inches > 100) { //NEW basically reinitialize everything if nothing in his way
flash_speed_on = 0;
flash_speed_off = 0;
flash_speed_count = 1;
digitalWrite(ledPinY, LOW);  //NEW turn off yellow LED
}
if (inches > 50 && fwd_speed == 1){ //NEW nothing close so go back to full speed
forward();
}
if (flash_speed_count == flash_speed_on) {
digitalWrite(ledPinY, HIGH);  //NEW turn on yellow LED
flash_speed_on = 0;
}
if (flash_speed_count >= flash_speed_off) {
digitalWrite(ledPinY, LOW);  //NEW turn off yellow LED
flash_speed_off = 0;
flash_speed_count = 1;
}

 

As a final touch, I decided in addition to flashing lights, when he got really close to something, he would slow down.

Here are the static and motion tests of the his “eyes”

That’s it for now; thanks for dropping by!

Leave a Reply

Your email address will not be published. Required fields are marked *

CommentLuv badge

This site uses Akismet to reduce spam. Learn how your comment data is processed.