One-sentence summary
Using an ultrasonic sensor to measure distance, we will build the logic behind a car's parking sensor with Arduino: a buzzer that beeps faster as an obstacle gets closer.
Why does it matter?
Most of us have heard a car's rear parking sensor: the beeps get closer together as you approach a wall, and when you are really close it almost beeps without stopping. This is not complicated magic. It is the combination of two simple ideas: measuring a distance and making a decision based on that distance.
In this project we join those two ideas with our own hands. The ultrasonic sensor answers the question, “How many centimetres away is the obstacle?” Our code looks at that answer and decides how often the buzzer should beep.
This lesson is also a turning point: instead of small programs that do a single task, we are now building a complete project. We will choose the parts, wire the circuit, split the code into functions, test it and fix a bug that shows up. This is how real engineering work flows.
How it works: The ultrasonic sensor
Measuring distance with a sound wave
The HC-SR04 ultrasonic sensor works just like a bat. It sends out a sound wave too high for our ears to hear, the wave bounces off an obstacle and comes back, and the sensor measures how long the round trip took.
The speed of sound in air is about 340 metres per second. If we know the round-trip time, we can calculate the distance. Dividing the time by 58 gives the distance in centimetres (this number is used because the wave travels the path twice).
The sensor has four legs:
- VCC: 5 volt power.
- GND: Ground (the negative side).
- Trig: The trigger leg that tells the sensor “send a sound wave now.”
- Echo: The leg that signals back when the wave returns.
Everyday example: The bat and its echo
In a dark cave, a bat “sees” the wall in front of it by making a sound and listening for when the echo returns. Our sensor uses the same echo idea. Another example is the sonar on ships: it sends sound into the water and listens for the echo to measure how deep the sea is.
Parts and wiring
Parts you need
- 1 Arduino Uno (with its USB cable)
- 1 HC-SR04 ultrasonic sensor
- 1 active buzzer
- 1 breadboard
- A few jumper wires
Wiring plan
Think of the connections as a short list:
- Sensor VCC → Arduino 5V
- Sensor GND → Arduino GND
- Sensor Trig → Arduino pin 9
- Sensor Echo → Arduino pin 10
- Buzzer positive (+) leg → Arduino pin 8
- Buzzer negative (−) leg → Arduino GND
Everything runs on low voltage from USB or a battery pack; there is no mains electricity. When you make the first connection, it is a good habit to unplug the Arduino's USB cable from the computer.
Splitting the code into functions
In the previous lesson we saw that splitting code into functions makes it easier to read and fix. In this project we build two functions: one measures the distance, and the other runs the buzzer based on that distance.
The distance function
long measureDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH); // send a sound wave
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH); // time for the echo
long distance = duration / 58; // convert to cm
return distance;
}
The pulseIn function measures how long the Echo leg stays HIGH, in microseconds. Dividing that time by 58 gives us the distance in centimetres.
The function that controls the buzzer
We change the waiting time based on distance thresholds. If the obstacle is close, the wait is short and the beeps come more often.
void giveWarning(long distance) {
int waitTime;
if (distance < 10) waitTime = 100; // very close
else if (distance < 20) waitTime = 300;
else if (distance < 40) waitTime = 600;
else {
noTone(buzzerPin); // far away: silent
return;
}
tone(buzzerPin, 1000); // beep at 1000 Hz
delay(100);
noTone(buzzerPin);
delay(waitTime); // wait based on the threshold
}
Setup and main loop
const int trigPin = 9;
const int echoPin = 10;
const int buzzerPin = 8;
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzzerPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
long distance = measureDistance();
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
giveWarning(distance);
}
When you open the Serial Monitor (9600 baud) you will see the measured distance streaming in centimetres. This helps you tune the thresholds to your own room.
Mini practice
Build the circuit, combine the three functions in a single file and upload it to the Arduino. Then try these test scenarios in order:
- Hold your hand 50 cm away from the sensor. You should see a large number in the Serial Monitor and the buzzer should stay silent.
- Move your hand slowly closer. When it drops below 40 cm, slow beeps should start.
- When it drops below 20 cm, the beeps should come more often.
- When it drops below 10 cm, the beeps should get quite fast.
- Watching the numbers in the Serial Monitor, change the thresholds (10, 20, 40) to whatever you prefer.
A small upgrade to try: below 10 cm, change the tone frequency from 1000 to 1500 Hz so the very-close warning sounds sharper.
Project strengthening plan
A working demonstration is not enough for Project: Smart Parking Sensor. A strong project also makes its aim, user, limits, test conditions and failed attempts visible. Use the context of a controlled counter that reduces button bounce in software to produce a wiring diagram, compilable Arduino code, a serial-monitor record and test results. Although the lesson aims to “Build a parking sensor that beeps faster as an object gets closer, using an ultrasonic sensor and buzzer”, do not present an unmeasured result as a confirmed success.
1. Project summary and scope
Write three sentences: What problem are you solving, who is affected by it, and what will the first version deliberately not do? Stating what is outside the scope does not weaken a project; it makes the project finishable. Describe the connection between How it works: The ultrasonic sensor and Everyday example: The bat and its echo as the main assumption, then name the test that can confirm or reject it.
2. Acceptance criteria
- Is the board’s 5 V or 3.3 V operating limit correct?
- Do pin numbers match in code and wiring?
- Are serial-monitor readings in the expected range?
- Is a motor or servo drawing excessive current directly from the board?
- Does the system return to a safe state when power is removed?
Do not leave an acceptance criterion for “Project: Smart Parking Sensor” as a vague statement such as “it works”. Choose an observable measure such as time, distance, correct trials, screen width or user steps. When direct measurement is difficult, record whether the same behaviour appears in three consecutive trials.
3. Test matrix
| Test | Condition | Expected | Actual result | Next decision |
|---|---|---|---|---|
| Normal | Standard input and complete setup | The core task is completed | Fill in during the test | Keep it or make a small improvement |
| Boundary | Lowest or highest accepted value | The system remains stable | Fill in during the test | Review the threshold or rule |
| Error | Missing, wrong or unexpected input | A safe and clear response | Fill in during the test | Add error handling |
| Repeat | At least three trials under the same condition | Similar results | Fill in during the test | Investigate the source of inconsistency |
4. Version log
For every version of “Project: Smart Parking Sensor”, record the date, the one main decision changed, the reason and the test result. A first version that fails is evidence about which assumption involving How it works: The ultrasonic sensor or Everyday example: The bat and its echo should be reconsidered. Remove personal information and private background details from images.
5. Presentation and self-review
Prepare a two-minute explanation of “Project: Smart Parking Sensor”: the problem, the solution approach, the most important result for a controlled counter that reduces button bounce in software, and the next step. Instead of saying the project is complete, state which part has been verified and which part still needs development.
Common mistakes
Swapping the Trig and Echo pins
Trig must be OUTPUT and Echo must be INPUT. If you write them the wrong way round in pinMode, the sensor gives no readings at all. Check that your code triggers Trig and listens on Echo.
Getting stuck because of delay: a bug and its fix
In our first try, the buzzer beeped lazily even when the obstacle was very close. The problem was this: at a far distance the giveWarning function exited with return, but we had forgotten to write noTone, so the buzzer kept playing the previous sound.
// Wrong: the sound was not stopped when far away
else {
return;
}
The fix was to turn off the sound before return:
// Right: silence first, then exit
else {
noTone(buzzerPin);
return;
}
A single missing line can change the behaviour completely. The full code above uses the corrected version.
Pointing the sensor at a soft surface
An ultrasonic wave does not reflect well off soft surfaces like cloth or foam, so the readings can jump around. When testing, use a hard, flat surface such as a book or a wall.
Safety note
- The whole circuit runs on low voltage from USB or a battery pack; never connect it to mains electricity.
- There is no motor in this project, but if you add one later, remember: motors need a motor driver and a separate power source, and are never driven straight from an Arduino pin.
- The buzzer sound can be sharp; do not hold it very close to your ear.
- Unplug the USB cable while building and taking apart the circuit, and run it for the first time with an adult.
- Keep the wires and sensor away from liquids.
Lesson summary
- The ultrasonic sensor finds distance by measuring the round-trip time of a sound wave; dividing that time by 58 gives centimetres.
- Trig is the output pin and Echo is the input pin;
pulseInreads the echo time. - By changing the waiting time according to distance thresholds, we make the buzzer beep faster or slower.
- Splitting the code into
measureDistanceandgiveWarningfunctions makes it easier to read and fix. - The Serial Monitor is our most valuable test tool for seeing real readings and tuning the thresholds.
Check questions
- What physical event does the HC-SR04 sensor use to measure distance?
- Which of the Trig and Echo pins is the output (OUTPUT) and which is the input (INPUT)?
- Why do we divide the time from
pulseInby 58? - Why does the buzzer beep more often as the obstacle gets closer? Which part of the code makes this happen?
- Which line inside
giveWarningis needed so the buzzer goes silent at a far distance?
Answers
- It uses a sound wave (ultrasonic) bouncing off an obstacle and coming back, that is, an echo. The distance is calculated from the round-trip time.
- Trig is the output (OUTPUT) because we send a signal to it; Echo is the input (INPUT) because we read a signal from it.
- The sound wave travels both there and back, so the total path is doubled; dividing by 58 accounts for that round trip and converts the time into centimetres.
- As the distance gets smaller, the
ifblocks choose a shorterwaitTime; becausedelay(waitTime)gets shorter, the gap between beeps shrinks and the sounds come more often. - The
noTone(buzzerPin);line is needed; it turns off the sound beforereturnso the buzzer does not keep playing the previous sound.
Source and verification note
For “Project: Smart Parking Sensor”, verification focuses on whether the relationship between How it works: The ultrasonic sensor and Everyday example: The bat and its echo remains consistent across examples. Pin, voltage and current limits can differ between Arduino-compatible boards. Compiling code does not guarantee a safe circuit; loads such as motors and servos require a suitable driver and external power where appropriate.
Next lesson
Project: The Logic of a Line-Following Robot