ArduinoC++Builders

Parking assist: beep before you bump

Build the helper a car has at the back. A sensor measures how far away the wall is, lights warn you, and a beeping gets faster the closer you get. Then park without a bump.

QR code to this pageScan to open

What you learn

17 things on the Builders path: open to see them

On the learning path: Builders with the Arduino and C++: a sensor, a rule and an output make a system

Programming

  • Decide with if, else if and else, and a number to compare with
  • map: a distance becomes a time between beeps from story 3
  • The board talks: Serial Monitor
  • The HCSR04 library does the timing of the echoNo library: the US-016 gives a voltage, analogRead reads it
  • C++: a variable with a decimal point (float), a function with three inputs

Electronics

  • The ultrasonic sensor: a click and its echo become centimetresThe analog ultrasonic sensor: a voltage becomes centimetres
  • Digital and analog: the US-016 gives a voltage with many steps, read with analogRead
  • A buzzer: tone, noTone, and a gap that makes the beeping fast or slow from story 3

Thinking and making

  • Print the numbers first, then choose the rule, then add the lights and the sound
  • Is it the wiring, the sensor or the program? The Serial Monitor tells you

AI in the loop

  • Ask an AI to find a bug: your board, your parts, what happens, your code
  • Test the AI ideas one at a time; it cannot see your wires
  • Distance needs only a rule; a camera with AI knows what the thing is
  • You decide what distance is safe, and you answer for the warning
  • AI along the project: zones, a first draft, likely bugs, test cases

Systems

  • A system in three parts: the sensor measures, the if decides, lights and sound act
  • Four wires to the sensor, three LEDs and a buzzer: build from the diagram

1See it in action

On screen: a car backs towards a wall, the lights go from green to yellow to red and the buzzer beeps faster
Park like a real car story 4, on screen
An ultrasonic sensor, LEDs and a buzzer on a breadboard with an Arduino
The helper on the breadboard built in class

2Parts you need

Arduino UNO
Breadboard
Ultrasonic sensor (HC-SR04)
Analog ultrasonic sensor (US-016)
LEDs
220 Ω resistors
Buzzerfrom story 3

And jumper wires and a USB cable: your teacher hands them out. Story 2 needs the red and the green LED, story 4 adds the yellow one.

Another Arduino board?

Other boards work with the same pins. In the Arduino IDE choose Arduino Uno for the UNO R3, Arduino Uno WiFi Rev2 for the WiFi board, or Arduino Nano for a Nano (D2, D3, D4, D8, D11, D12, 5V and GND).

3Learn the basics

The parts of this project, each explained once for all projects. Open "More" to dig deeper.

the click → ← the echo

Ultrasonic distance sensor

One can sends a click, too high for us to hear. The other listens for the echo from the wall. A stopwatch measures how long the trip took. Sound needs about 29 µs for 1 cm, and the click went there and back, so:

distance in cm = time in µs ÷ 2 ÷ 29.1

More: see it slowly, our two sensors side by side, and how to read each

Our two sensors, side by side

HC-SR04
HC-SR04 times the echo
How
Trig makes the click; Echo stays HIGH as long as the trip takes
Pins
VCC · Trig · Echo · GND
Read it
a library, or pulseIn and the maths
Range
2 to 400 cm, about 3 mm steps
Nothing there
no echo: the library gives −1
Good for
most hobby projects: many examples online
US-016
US-016 an analog sensor
How
times the echo itself and gives a voltage: further = higher
Pins
VCC · Range · Out · GND
Read it
analogRead, no library
Range
2 to 300 cm (Range high or open, 3 mm a step), or up to 1 m (Range on GND, 1 mm a step)
Nothing there
the highest value: about 307 cm
Good for
simple code, and fine steps close up

Which would you choose? A parking assist that must see 3 m. A gate that only needs to know "a car is there". A ruler that measures a book on the table to the millimetre. A project that also uses every analog pin for knobs. Explain your choice to the person next to you.

Both see in a cone of about 15°. Soft things (a pillow, a jumper) and slanted surfaces send the sound away: then there is no echo, or a wrong one. Wait at least 60 ms between two clicks, or you may hear the old echo.

Reading the HC-SR04

#include <HCSR04.h>
UltraSonicDistanceSensor sensor(12, 11);    // Trig on 12, Echo on 11

void setup() { Serial.begin(9600); }
void loop() {
  Serial.println(sensor.measureDistanceCm());   // -1: nothing in range
  delay(200);
}

The HCSR04 library (by Martin Sosic, Library Manager) does the timing. Without it: Trig HIGH for 10 µs, then pulseIn(echoPin, HIGH) gives the time in µs, and time ÷ 2 ÷ 29.1 is the distance. Always treat −1 as "far away", not as "very close".

Reading the US-016

const int sensorPin = A0;               // OUT; Range on 5V (or open): up to 3 m

float measureDistance() {
  return analogRead(sensorPin) * 0.3;   // one step is 3 mm = 0.3 cm
}

void setup() { Serial.begin(9600); }
void loop() {
  Serial.println(measureDistance());
  delay(200);
}

The voltage on OUT goes from 0 V to 5 V for 0 to about 307 cm, and analogRead turns that into 0 to 1023: every step is 3 mm. With Range on GND the sensor measures up to about 1 m instead, 1 mm a step: then the number from analogRead is the distance in mm. The sensor checks Range only when it gets power. Check it with a tape measure: if every number is off by the same factor, change the 0.3 a little (calibrating).

Serial Monitor 52.31 cm41.08 cm30.55 cm 18.90 cm-1.00 cm 9600 baud

Serial Monitor

The Arduino has no screen, but it can talk through the USB cable. Serial.print sends a number or a word to the computer, and the Serial Monitor in the Arduino IDE (the magnifying glass, top right) shows it. Print first, decide later: when you see the numbers, you can choose a good rule.

Serial.begin(9600) in setup, Serial.println(value) wherever you want to see something. The monitor must be set to 9600 too.

More: print, println and reading the numbers
void setup() {
  Serial.begin(9600);                 // 9600 bits every second: the speed the monitor expects
}

void loop() {
  int value = analogRead(A0);
  Serial.print("A0 = ");               // print: stays on the same line
  Serial.println(value);               // println: ends the line
  delay(200);
}

Strange characters instead of numbers? The speed in the monitor is not 9600. Nothing at all? Choose the port of your board, and check that the program has Serial.begin. Print only every 100 ms or so: thousands of lines a second are too fast to read, and they slow the board down.

The Micro:bit shows numbers on its own LEDs with show number; the Arduino prints them here instead.

An Arduino UNO

Arduino libraries

A library is ready-made code for a part, written and shared by someone else. It does the hard work, like sending the 24 bits per LED of an LED strip, so your program stays short.

Install it once, include it at the top, make an object, call its functions.

More: the four steps
  1. Install: in the Arduino IDE, Tools, Manage Libraries; search the name, click Install.
  2. Include: the first line of the sketch brings it in: #include <Adafruit_NeoPixel.h>
  3. Make an object: one for each part: Adafruit_NeoPixel strip(10, 6, NEO_GRB + NEO_KHZ800);
  4. Call its functions on the object: strip.begin(); strip.show();

Every library comes with examples: File, Examples, then the library's name. Opening one is the fastest way to see what its functions do.

A small black round buzzer with a + mark and two legs

Buzzer

A buzzer is a tiny loudspeaker. Switch its pin on and off very fast, say 1000 times a second, and you hear a note. The Arduino does that for you with tone: a higher number, a higher note. noTone makes it quiet.

The leg under the + mark to a pin, the other to GND. tone(pin, 1000) sounds until noTone(pin).

More: beeps, notes and the two kinds of buzzer
const int buzzerPin = 8;

void setup() {
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  tone(buzzerPin, 1000);    // on, 1000 Hz
  delay(60);
  noTone(buzzerPin);        // off
  delay(400);               // the gap: shorter gap, faster beeping
}

A beep is a short tone and a gap. Change the gap and the beeping gets faster or slower; change the number in tone and the note gets higher or lower. The notes of a song are just numbers: 262 is a C, 294 a D, 330 an E, 392 a G, 440 an A.

Two kinds: a passive buzzer (ours) needs tone to make the swings; an active buzzer has the swings built in and sounds as soon as its pin is high, always at the same note. If yours beeps with a plain digitalWrite HIGH, it is an active one; tone works with both kinds.

4Wire it

The picture shows the wiring for your story. Start with the sensor alone; each story adds a little, and nothing you built has to change. The new parts have a dashed box.

The sensor sits next to the breadboard on four jumper wires: VCC to the + rail, GND to the − rail, Trig to pin 12 and Echo to pin 11.

The sensor sits next to the breadboard on four jumper wires: VCC and RANGE to the + rail (RANGE on 5V gives the 3 m range), GND to the − rail, and OUT to the analog pin A0.

Each LED sits behind a 220 Ω resistor, the long leg towards the resistor, the short leg in the − rail. The buzzer's + leg goes to pin 8.

Circuit diagram: the same wiring, drawn the way engineers do

Every line is a wire and every part has its own symbol. The parts new in this story are blue. How to read a circuit diagram

Circuit diagram for story 1 Circuit diagram for story 2 Circuit diagram for story 3 Circuit diagram for story 4 Circuit diagram for story 1 Circuit diagram for story 2 Circuit diagram for story 3 Circuit diagram for story 4

5Try it

The parking lab runs every story on screen: move the slider or let the car drive by itself, and watch which lines of the program run. Turn the sound on to hear the beeps.

Open the parking lab in a new tab

6Program it

You see the program for . Choose another story in the bar at the top of the page.

In the Arduino IDE, install the library once: Library Manager (the books icon on the left), search for HCSR04 and install the one by Martin Sosic. Then type the code, choose your board and port, and Upload. Go as far as you like: every story works on its own.

The US-016 needs no library: it gives a voltage, and analogRead reads it. The function measureDistance turns 0 to 1023 into cm (× 0.3 on the 3 m range); the rest of each program is the same as with the HC-SR04 (switch the sensor in the bar and compare). Type the code, choose your board and port, and Upload.

Story 1: See the distancemeasure, print

#include <HCSR04.h>

const int triggerPin = 12;
const int echoPin = 11;
UltraSonicDistanceSensor sensor(triggerPin, echoPin);

void setup() {
  Serial.begin(9600);                 // talk to the computer: open the Serial Monitor at 9600
}

void loop() {
  float distance = sensor.measureDistanceCm();   // -1 when nothing is in range
  Serial.print(distance);
  Serial.println(" cm");
  delay(200);
}
const int sensorPin = A0;           // US-016 OUT; RANGE on 5V: the 3 m range

float measureDistance() {            // the US-016 gives a voltage: on the 3 m range one step is 3 mm
  return analogRead(sensorPin) * 0.3;    // cm
}

void setup() {
  Serial.begin(9600);                 // talk to the computer: open the Serial Monitor at 9600
}

void loop() {
  float distance = measureDistance();   // always a number, in cm
  Serial.print(distance);
  Serial.println(" cm");
  delay(200);
}

Open the Serial Monitor (the magnifying glass, top right) and set it to 9600. Hold your hand in front of the sensor and move it: the numbers follow your hand. float is a number with a decimal point.

Check the US-016 with a tape measure: hold a book at 20, 50 and 100 cm. If the numbers are off by the same factor, change the 300 in measureDistance: that is calibrating a sensor.

Your turn: how close can your hand come before the numbers go strange? And how far away does the wall still count?

Story 2: Red when too closea rule with if

#include <HCSR04.h>

const int triggerPin = 12;
const int echoPin = 11;
const int redLedPin = 2;
const int greenLedPin = 4;
const int tooClose = 30;            // cm
UltraSonicDistanceSensor sensor(triggerPin, echoPin);

void setup() {
  Serial.begin(9600);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
}

void loop() {
  float distance = sensor.measureDistanceCm();
  Serial.println(distance);
  if (distance > 0 && distance < tooClose) {     // -1 means: nothing in range, so that counts as far
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
  } else {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
  }
  delay(100);
}
const int sensorPin = A0;           // US-016 OUT; RANGE on 5V: the 3 m range
const int redLedPin = 2;
const int greenLedPin = 4;
const int tooClose = 30;            // cm

float measureDistance() {            // the US-016 gives a voltage: on the 3 m range one step is 3 mm
  return analogRead(sensorPin) * 0.3;    // cm
}

void setup() {
  Serial.begin(9600);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
}

void loop() {
  float distance = measureDistance();
  Serial.println(distance);
  if (distance > 0 && distance < tooClose) {     // the US-016 never gives -1; the check does no harm
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
  } else {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
  }
  delay(100);
}

The sensor measures, the if decides, the LEDs show it. && means and: both must be true. The first part keeps −1 out, because −1 is smaller than 30 and would look like "very close".The US-016 never gives −1; the first part keeps the program the same for both sensors.

Your turn: change tooClose until the red comes on exactly where you want it.

Story 3: Beep faster, closertone, map

#include <HCSR04.h>

const int triggerPin = 12;
const int echoPin = 11;
const int redLedPin = 2;
const int greenLedPin = 4;
const int buzzerPin = 8;
const int tooClose = 30;            // cm: from here the beeping starts
UltraSonicDistanceSensor sensor(triggerPin, echoPin);

void setup() {
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  float distance = sensor.measureDistanceCm();
  if (distance > 0 && distance < tooClose) {
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
    int gap = map((int) distance, 0, tooClose, 50, 500);   // closer: a shorter gap between the beeps
    tone(buzzerPin, 1000);          // a beep of 1000 Hz ...
    delay(60);
    noTone(buzzerPin);              // ... for 60 ms
    delay(gap);
  } else {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
    delay(100);
  }
}
const int sensorPin = A0;           // US-016 OUT; RANGE on 5V: the 3 m range
const int redLedPin = 2;
const int greenLedPin = 4;
const int buzzerPin = 8;
const int tooClose = 30;            // cm: from here the beeping starts

float measureDistance() {            // the US-016 gives a voltage: on the 3 m range one step is 3 mm
  return analogRead(sensorPin) * 0.3;    // cm
}

void setup() {
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  float distance = measureDistance();
  if (distance > 0 && distance < tooClose) {
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
    int gap = map((int) distance, 0, tooClose, 50, 500);   // closer: a shorter gap between the beeps
    tone(buzzerPin, 1000);          // a beep of 1000 Hz ...
    delay(60);
    noTone(buzzerPin);              // ... for 60 ms
    delay(gap);
  } else {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
    delay(100);
  }
}

A beep is a short tone and a gap. map turns the distance into the gap: 30 cm gives 500 ms between beeps, 0 cm gives 50 ms. The closer, the faster, just like in a real car.

Your turn: make the note higher when it is closer too: a second map for the number in tone.

Story 4: Park like a real carzones with else if

#include <HCSR04.h>

const int triggerPin = 12;
const int echoPin = 11;
const int redLedPin = 2;
const int yellowLedPin = 3;
const int greenLedPin = 4;
const int buzzerPin = 8;
const int slowDown = 40;            // cm: yellow
const int tooClose = 20;            // cm: red and beeping
const int stopHere = 8;             // cm: red and a steady tone
UltraSonicDistanceSensor sensor(triggerPin, echoPin);

void setup() {
  pinMode(redLedPin, OUTPUT);
  pinMode(yellowLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
}

void lights(bool red, bool yellow, bool green) {
  digitalWrite(redLedPin, red);
  digitalWrite(yellowLedPin, yellow);
  digitalWrite(greenLedPin, green);
}

void loop() {
  float distance = sensor.measureDistanceCm();
  if (distance < 0 || distance >= slowDown) {    // far away, or nothing in range
    lights(false, false, true);
    noTone(buzzerPin);
    delay(100);
  } else if (distance >= tooClose) {             // getting close: slow down
    lights(false, true, false);
    noTone(buzzerPin);
    delay(100);
  } else if (distance >= stopHere) {             // close: beep, faster and faster
    lights(true, false, false);
    int gap = map((int) distance, stopHere, tooClose, 60, 400);
    tone(buzzerPin, 1000);
    delay(60);
    noTone(buzzerPin);
    delay(gap);
  } else {                                       // stop!
    lights(true, false, false);
    tone(buzzerPin, 1500);
    delay(100);
  }
}
const int sensorPin = A0;           // US-016 OUT; RANGE on 5V: the 3 m range
const int redLedPin = 2;
const int yellowLedPin = 3;
const int greenLedPin = 4;
const int buzzerPin = 8;
const int slowDown = 40;            // cm: yellow
const int tooClose = 20;            // cm: red and beeping
const int stopHere = 8;             // cm: red and a steady tone

float measureDistance() {            // the US-016 gives a voltage: on the 3 m range one step is 3 mm
  return analogRead(sensorPin) * 0.3;    // cm
}

void setup() {
  pinMode(redLedPin, OUTPUT);
  pinMode(yellowLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
}

void lights(bool red, bool yellow, bool green) {
  digitalWrite(redLedPin, red);
  digitalWrite(yellowLedPin, yellow);
  digitalWrite(greenLedPin, green);
}

void loop() {
  float distance = measureDistance();
  if (distance < 0 || distance >= slowDown) {    // far away, or nothing in range
    lights(false, false, true);
    noTone(buzzerPin);
    delay(100);
  } else if (distance >= tooClose) {             // getting close: slow down
    lights(false, true, false);
    noTone(buzzerPin);
    delay(100);
  } else if (distance >= stopHere) {             // close: beep, faster and faster
    lights(true, false, false);
    int gap = map((int) distance, stopHere, tooClose, 60, 400);
    tone(buzzerPin, 1000);
    delay(60);
    noTone(buzzerPin);
    delay(gap);
  } else {                                       // stop!
    lights(true, false, false);
    tone(buzzerPin, 1500);
    delay(100);
  }
}

Four zones, one after the other: else if only runs when everything above it was false, so the checks can go from far to near. || means or. The function lights sets all three LEDs in one line.

Your turn: park a toy car. Which numbers for the zones feel right for a real garage?

Really stuck? Try first: you learn the most by building it yourself. If it still does not work, your teacher can give you a code for a ready-made program of your story.

Type the code in the lock at the top right of the page.

7Challenges

Four challenges: both sensors side by side, measure without the library, park exactly in a green zone, and a sensor at the front and the back

Challenges

  • Side by side: wire both sensors at once and print both distances on one line. Which one is closer to the tape measure? Which one jumps less? Which one sees a pillow?
  • Without the library: make the click and time the echo yourself: Trig high for 10 µs, then pulseIn(echoPin, HIGH), and the speed of sound does the rest.
  • Park it exactly: a green zone from 15 to 20 cm: one long beep when you are in it, and red when you went too far.

Explore further

  • Front and back: two sensors, two helpers; the nearer one decides.
  • Show the number: the distance on the Serial Monitor as a bar of # signs, or on a Micro:bit's LEDs by radio.
  • Steady average: the numbers jump a little; take the average of the last 5 measurements.
  • Lift the gate: a servo lifts a barrier when a car comes closer than 15 cm, and lowers it three seconds after the car has passed.

Example solution for Side by side, and hints for the others. Try first; if you get stuck, or want to study it at home, ask your teacher for the code.

Type the code in the lock at the top right of the page.

8Team up with AI

  1. Meet AIExplorers: see it, try it, judge it
  2. Engineer with AIBuilders: use it at every step, train a model
  3. Build with AICreators: AI drafts the code and runs inside your machine

Engineer with AI: use it at the right step of the project, give it the facts it needs, and test every idea on the real thing. Some jobs need a trained model, some only a rule: you choose. How to team up with AI

AI in the real world

Parking help in real cars

Cars have ultrasonic sensors in the bumper, like yours. Many new cars also have cameras with trained AI: they find the parking lines and can tell a person or a bike from a wall.

What only you can do

You are the engineer

  • Safety first. You decide at what distance the warning starts, so that people and cars are safe.
  • Test with real things. A wall, a soft pillow, a hand, a thin chair leg: the sensor sees them differently, only a test shows it.
  • A warning must not fail. You answer for what your device does, also when AI wrote part of the code.

AI along the way

Where AI helps in this project, and your part

StepAI canYou
PlanSuggest distance zones: far, careful, stopMeasure what is safe for your car and choose the numbers
ProgramWrite a first draft of a function, for example in the Arduino Cloud Editor's AI assistantRead every line and ask about what you do not understand
DebugGive the most likely reasons for a bugTest them one at a time, print the distance
TestList test cases: very close, nothing in range, a soft pillowRun every case with the real sensor

Ask the AI

Find my bug

I use an Arduino UNO with an HC-SR04 ultrasonic sensor (Trig on pin 12, Echo on pin 11) and a buzzer on pin 8.
It should beep faster when something comes closer, but it always beeps at the same speed.
Here is my code: (paste it)
Give me the 2 most likely reasons and how I can test each one.

Then check:

  • Test one reason at a time, not both at once.
  • Print the distance in the Serial Monitor: is the number right?
  • The AI cannot see your wires: check them yourself.

Ask the AI

Find my bug

I use an Arduino UNO with a US-016 ultrasonic sensor (OUT on A0) and a buzzer on pin 8.
It should beep faster when something comes closer, but it always beeps at the same speed.
Here is my code: (paste it)
Give me the 2 most likely reasons and how I can test each one.

Then check:

  • Test one reason at a time, not both at once.
  • Print the distance in the Serial Monitor: is the number right?
  • The AI cannot see your wires: check them yourself.

Spot the AI mistake

My beeps sound bad. How can I make them clearer?

Put delay(1000) after each beep, so every beep has a full second of quiet around it.

An example answer, written for practice.

  1. What is wrong with this idea?

Spot the AI mistake

What does my HC-SR04 give when nothing is in front of it?

It gives 0. So when the distance is 0, there is nothing in front of the sensor.

An example answer, written for practice.

  1. Is the AI right for our library?

Spot the AI mistake

How do I get the distance from my US-016?

Use analogRead(A0). The number it gives is the distance in cm.

An example answer, written for practice.

  1. Is the AI right?

Rule or trained model

  1. Your sensor measures how far. What would a camera with AI add?

Wise and fair

Four rules for every AI tool

  • Private: never type or upload names, addresses or photos of people.
  • Real: AI can sound sure and be wrong. Test it on the real thing.
  • Honest: say what AI did and what you did.
  • Yours: you put it on the board, so you answer for it.

9How others did it

Other kids solved the same task their own way: shorter, longer, with a smart trick, or not working yet. Open one to see it, find the bug or make it better. Made it your own way? Show your teacher.

Two ifs instead of if and else

✓ It worksProgramStory 2A different wayExample
void loop() {
  float distance = sensor.measureDistanceCm();
  if (distance > 0 && distance < tooClose) {
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
  }
  if (distance >= tooClose) {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
  }
  delay(100);
}

What they did: One if for "too close", a second if for "far enough", no else.

Look closer: It works. But look at −1, nothing in range: the first if says no (−1 is not above 0), the second says no too (−1 is not 30 or more), so no LED is on at all. With else, one of the two always runs.

Your turn: Point the sensor at the ceiling. Which light is on in this version, and which in ours?

Beeps slower when closer

✗ Not working yetProgramStory 3Example
void loop() {
  float distance = sensor.measureDistanceCm();
  if (distance > 0 && distance < tooClose) {
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
    int gap = map((int) distance, 0, tooClose, 500, 50);
    tone(buzzerPin, 1000);
    delay(60);
    noTone(buzzerPin);
    delay(gap);
  } else {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
    delay(100);
  }
}

What they did: Everything beeps, but the beeping gets slower the closer the hand comes, and fast when it is far away.

Look closer: map(distance, 0, 30, 500, 50): the last two numbers are the wrong way round, so 0 cm gives a gap of 500 ms and 30 cm a gap of 50 ms.

Your turn: Which two numbers do you swap? Try it in the lab first.

What went wrong?

map takes "from this range" then "to this range", both from low to high: map(distance, 0, 30, 50, 500). Swap the last two numbers and the beeping turns round.

10Check what you learned

Before you leave. Your teacher picks some of these for you: answer out loud, draw on paper, or work with the person next to you. Some cards change with your story: now .

Answer it

Tap an answer: you see at once if it is right, and why

  1. How does the ultrasonic sensor measure the distance?

  2. The sensor has two round cans. Why two?

  3. The library gives −1. What does that mean?

  4. What does Serial.begin(9600) do?

  5. Sound travels about 34 cm in one millisecond. The echo comes back after 2 ms. How far away is the wall, in cm?

  6. Why wait 200 ms between two measurements?

  7. Our parking assist measures, decides and acts. Which part decides?

  8. You want the warning from further away. Which part do you change?

  9. tone(buzzerPin, 1000): what is the 1000?

  10. The buzzer keeps sounding. Which line stops it?

  11. gap = map(distance, 0, 30, 50, 500). Nearer the wall, the gap gets …

  12. if (distance < 10) … else if (distance < 30) … else … The distance is 5. Which part runs?

  13. True or false: a real parking sensor in a car works the same way: measure, decide, beep.

  14. The US-016 gives a voltage on its OUT pin. How does the Arduino read it?

  15. Which of our two ultrasonic sensors needs the board to time the echo?

  16. The US-016 says 60 cm when the book is at 50 cm. What do you change?

  17. The echo comes back after 1164 µs. How far away is the wall, in cm? (time ÷ 2 ÷ 29.1)

  18. A sensor must see a car coming from 3.5 m away. Which one can do it?

  19. You want to measure a book on the table to the millimetre, at most 50 cm away. Which sensor setting is best?

Predict, then try

Choose what will happen, then try it in the lab or on your board

  1. Move your hand slowly towards the sensor. What do the numbers in the Serial Monitor do?

  2. Change tooClose from 30 to 60. What changes?

  3. Replace the map line with gap = 500. What happens?

  4. Point the sensor at the open room, nothing within 4 m. Which light is on?

Draw it

For

Draw the flow chart of your program on paper: a box for each step, a diamond for each question, arrows for the order. Then point at each box and tell your teacher what the lights and the buzzer do at that moment.

How to draw a flow chart

Flow charts

A flow chart shows what a program does, one step after the other. It works for every board and every language: the blocks change, the idea stays.

  • Rounded box: where it starts
  • Box: one thing to do
  • Diamond: a question with two answers, yes and no
  • Arrow: what comes next; an arrow back up repeats

One box for each step, a diamond for each question, and follow the arrows with your finger.

More: how to draw your own

Draw on paper with a pencil. Read your program from the top and draw one box for each block or line. "Forever" and "loop" are an arrow back up. "If", "while" and "on button pressed" are questions: a diamond with yes and no. Then point at the boxes with your finger and say out loud what the board does. If your finger gets stuck, the program would get stuck too.

I can …

Tick what is true for you today. Your ticks stay on this computer.

Find the bug

A mistake we often see in class. What does the board do? Why? How do you fix it?

"The Serial Monitor shows −1.00 cm all the time, whatever I hold in front of the sensor. The sensor is wired as in Wire it."

#include <HCSR04.h>

const int triggerPin = 12;
const int echoPin = 11;
UltraSonicDistanceSensor sensor(echoPin, triggerPin);

void setup() {
  Serial.begin(9600);
}

void loop() {
  float distance = sensor.measureDistanceCm();
  Serial.print(distance);
  Serial.println(" cm");
  delay(200);
}
Need a hint?

Compare the two pin numbers in the program with the two wires Trig and Echo.

  • What is wrong?

"Red is on when nothing is near, and it turns green when I put my hand in front of the sensor."

void loop() {
  float distance = sensor.measureDistanceCm();
  if (distance > 0 && distance > tooClose) {
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
  } else {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
  }
  delay(100);
}
Need a hint?

Read the if out loud: "if the distance is ... than 30".

  • Which check is right for "too close"?

"When nothing is in front of the sensor, it beeps like crazy and red is on. With a wall at 50 cm it is fine."

void loop() {
  float distance = sensor.measureDistanceCm();
  if (distance < tooClose) {
    digitalWrite(redLedPin, HIGH);
    digitalWrite(greenLedPin, LOW);
    int gap = map((int) distance, 0, tooClose, 50, 500);
    tone(buzzerPin, 1000);
    delay(60);
    noTone(buzzerPin);
    delay(gap);
  } else {
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, HIGH);
    delay(100);
  }
}
Need a hint?

What number does the library give when nothing is in range? Is that number smaller than 30?

  • Why does it beep with nothing in front?

"The first time something comes close it beeps, fine. But when I take it away, the buzzer keeps sounding, even with green on."

void loop() {
  float distance = sensor.measureDistanceCm();
  if (distance < 0 || distance >= slowDown) {
    lights(false, false, true);
    delay(100);
  } else if (distance >= tooClose) {
    lights(false, true, false);
    delay(100);
  } else if (distance >= stopHere) {
    lights(true, false, false);
    tone(buzzerPin, 1000);
    delay(60);
    noTone(buzzerPin);
    delay(map((int) distance, stopHere, tooClose, 60, 400));
  } else {
    lights(true, false, false);
    tone(buzzerPin, 1500);
    delay(100);
  }
}
Need a hint?

Follow the program when the distance is big: which line switches the buzzer off?

  • What is missing?

"The Serial Monitor only shows 0 or 1, whatever is in front of the US-016. Far away it says 1, very close it says 0."

const int sensorPin = A0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int reading = digitalRead(sensorPin);
  Serial.println(reading);
  delay(200);
}
Need a hint?

The US-016 gives a voltage that can be anything from 0 V to 5 V. Which read gives you all the steps in between?

  • Which line reads the US-016 right?

Ask one question

Each of you asks one question about today

Ask your teacher or the class one question about today. Anything counts: a part, a block, a word on this page, something that went wrong, or where this is used in real life. There are no wrong questions, only questions nobody asked.

Start with: Why does …?   What happens if …?   How does a real … do it?   What does … mean?   Could I use this to …?

Answers for the teacher. A model flow chart for each story. The questions and bugs above show their own answers.

Type the code in the lock at the top right of the page.

Poster to print (PDF)