Ingredients
Special parts
Optional parts
Maybe you know how bats “see” with sound: emitting high-pitched clicks and listening for how those sounds bounce off things. It’s called “echolocation” because the bats literally locate things using echoes. We can make an Arduino do the same thing!
Detecting objects around us is key to navigating our world, and can be important for smart objects, too. Is the cat nearby? Am I about to bump into a wall?
To give our Arduino “eyes,” we’ll use a Ping sensor, which, just like a bat, emits high-pitched sounds and listens for them to return. By timing how long it takes the sound to make that super-quick round-trip journey, we can sense when an object is near the sensor and measure how far away it is.
As an added bonus, the Ping sensor looks like two little eyes—which can be great if you are building a robot.
The key part here is, of course, the Ping sensor. A quick Internet search will lead you to one, or you can find links at http://keefe.cc/invisible-ruler.
The pins on the Ping sensor are set up in a very common pattern for sensor parts:
5V
for 5 volts of power.GND
on the Ping.SIG
for “signal.”
Wiring up this project is pretty straightforward:
GND
pin fitting into breadboard Row 1 and the Ping’s SIG
pin fitting into breadboard Row 3.GND
pin. Be sure the Ping and the jumper wire are on the same side of the canal down the middle of the breadboard.GND
pins.5V
pin. Again, be sure to stay on the same side of the center canal.5V
pin.SIG
pin. Same rule about the canal.That’s it!
Pick your favorite way to get the code:
Once you get your bundle . . .
family-projects-sketches-master
folder, and double-click it to open it.invisible_ruler
folder.Reading this book on your computer? Here are the copy-paste instructions:
No matter how you got the code into your Arduino software, be sure to save your work, using File → Save.
Upload the code to your Arduino by clicking the arrow button at the top of the blue window or using Sketch → Upload.
Next, open up the Serial Monitor (Tools → Serial Monitor) and place your hand in front of the sensor. The numbers should change as you get closer to or farther from the sensor.
The measurements won’t be exact, but they’re accurate enough to trigger an action if something comes near!
If you’re seeing nothing or gibberish in the Serial Monitor, be sure the menus at the bottom of that window are set to “9600 baud” and “CR no LF.”
Be sure you don’t have the power wires reversed: GND
on the Ping should connect to GND
on the Arduino.
The Arduino sends out a “HIGH” signal to the Ping, which transmits a super-high frequency sound. The code then waits to see how long it takes to pick up the return signal in microseconds, which are millionths of a second! We know that sound takes 74 microseconds to travel an inch (29 microseconds for a centimeter), so we can turn the time gap into the distance the sound covered while we were waiting. Half of that round trip is the distance to the object!
There’s a little command in this code that’s the key to everything: pulseIn(pingPin, HIGH)
. This command sits and waits for an input pin to detect something, and lets you know how long it waited. So written as below, duration becomes the number of microseconds the Arduino was waiting:
duration = pulseIn(pingPin, HIGH);
The crazy (to me) part is that just a couple of lines earlier, we sent a quick “chirp” to the ultrasonic emitter. So pulseIn
is measuring how long it takes to hear the echo off something just a few inches away.
That value, stored in duration
, is then used to calculate the distance to that object.
Until now, the separate blocks of code in our sketches have started with void
—as in void setup()
and void loop()
and void douseCandle()
. In this project, though, there are some sections, or functions, that begin with long
instead.
Here’s why. We’re sending the function a number and expecting something back in return. For example, if the main program sends the function the number 5,800, like so . . .
cm = microsecondsToCentimeters(5800);
. . . the 5800 gets delivered to the microsecondsToCentimeters
function . . .
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance traveled.
return microseconds / 29 / 2;
}
. . . which welcomes that 5,800 as the variable microseconds
, divides it by 29 (the / means divide), and divides it further by 2. The result of that math (5,800 / 29 / 2) is 100
, so 100
gets returned to the main program. So in this case, the variable cm
at the very beginning of our example is now equal to 100
.
We need to tell the Arduino what kind of value is coming back. That’s where long
comes in. This particular program could be dealing with some big-time numbers, even more than a billion. The long
designation tells the Arduino to save some extra space for that number in its little brain. Numbers designated as long
numbers can be between 2,147,483,647 and -2,147,483,648. By comparison, an int
number can only get as big as 32,767 (or down to -32,768).
When nothing is expected back from a function, we use the word void
instead, as you’ve been doing up until now.
You can tell your Arduino to act on the distance measurement by using some “if-then” code. If an object comes within 3 inches, then do something (light an LED, ring an alarm, back away).
Let’s do that. When something is near, we’ll light up an LED. Go ahead and add the optional LED to the Arduino, putting the long leg in Pin 13
and the short leg in GND
.
Then add these lines right above the delay(100);
line, like this:
if (inches < 3) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
delay(100);
The LED should light up whenever your hand is near the sensor!