Parking sensor on an Arduino Uno
An ultrasonic ranger and a buzzer that beeps faster as the wall gets closer. Drag the slider to move the wall. The whole build, an Arduino Uno and 4 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
IntermediateRuns in your browser. Free, and no account needed.
Step by step, with the wiring and the common mistakes: Arduino Ultrasonic Sensor (HC-SR04) Tutorial
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Parking sensor: an ultrasonic ranger and a buzzer that beeps faster as
// whatever is in front of it gets closer.
//
// pin 7 TRIG on the HC-SR04
// pin 6 ECHO on the HC-SR04 (VCC -> 5 V, GND -> GND)
// pin 9 the buzzer, the other leg to GND
// pin 8 the red LED, through 220 ohm to GND
//
// Drag the slider on the ranger to move the wall.
//
// # What the ranger actually does
//
// Ten microseconds of TRIG, and the module holds ECHO high for as long as the
// sound takes to come back. Sound is 343 metres a second, which is 0.343 mm a
// microsecond, and it makes the trip twice, so the distance is the echo in
// microseconds times 343 over 2000. `mokxi_hcsr04.h` does that sum in integers
// and returns 0 for no echo at all.
//
// # The beep
//
// The gap between beeps is the distance, near enough: at two metres it beeps
// about once a second, at twenty centimetres about ten times, and inside the
// stop line it holds one long note and lights the LED. That is what a real
// parking sensor does, and it is a thing you hear rather than read.
//
// # Why it waits sixty milliseconds
//
// The echo of the last ping is still going round the room. The datasheet asks
// for 60 ms between measurements and the sketch takes it; the loop has nothing
// better to do anyway.
#include "mokxi_hcsr04.h"
#include "mokxi_tone.h"
const uint8_t TRIG = 7;
const uint8_t ECHO = 6;
const uint8_t BUZZER = 9;
const uint8_t LED = 8;
Sonar sonar(TRIG, ECHO);
// Millimetres. Inside STOP it is one long note; past WATCH it says nothing.
const uint16_t STOP = 150;
const uint16_t WATCH = 2000;
uint32_t nextBeep = 0;
/** Milliseconds between beeps at a distance: closer is faster. */
static uint16_t gapFor(uint16_t mm) {
if (mm <= STOP) {
return 0;
}
// Linear from 90 ms at the stop line to 900 ms at the edge of interest,
// which sounds right even though the ear is not linear.
uint32_t span = (uint32_t)(WATCH - STOP);
uint32_t over = (uint32_t)(mm - STOP);
return (uint16_t)(90ul + (810ul * over) / span);
}
/** One line per change of about a centimetre, so the monitor stays readable. */
static void say(uint16_t mm, uint16_t gap) {
static int lastCm = -1;
int cm = (int)(mm / 10u);
if (cm == lastCm) {
return;
}
lastCm = cm;
if (mm == 0u) {
Serial.println("nothing in range");
return;
}
Serial.print(cm);
Serial.print(" cm");
if (gap == 0u) {
Serial.println(" STOP");
} else {
Serial.print(" beep every ");
Serial.print(gap);
Serial.println(" ms");
}
}
void setup() {
sonar.begin();
pinMode(LED, OUTPUT);
mokxiNoTone(BUZZER);
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: parking sensor");
Serial.println("drag the slider on the ranger to move the wall");
}
void loop() {
uint16_t mm = sonar.read();
if (mm == 0u || mm > WATCH) {
// Nothing worth telling the driver about.
digitalWrite(LED, LOW);
mokxiNoTone(BUZZER);
say(0, 0);
delay(60);
return;
}
if (mm <= STOP) {
digitalWrite(LED, HIGH);
mokxiTone(BUZZER, NOTE_A4, 60);
say(mm, 0);
delay(60);
return;
}
digitalWrite(LED, LOW);
uint16_t gap = gapFor(mm);
if ((int32_t)(millis() - nextBeep) >= 0) {
mokxiTone(BUZZER, NOTE_C5, 40);
nextBeep = millis() + gap;
}
say(mm, gap);
delay(60);
}
Parts list
6 parts, plus the jumper wires. Every one is in the editor's parts bin.
- 1 × Arduino Uno R3
- 1 × Full-size breadboard
- 1 × Ultrasonic ranger
- 1 × Buzzer
- 1 × Resistor, 220 Ω
- 1 × LED, red
How it is wired
7 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Arduino Uno R3 pin 9; Buzzer pin 1
- Arduino Uno R3 pin 8; Resistor, 220 Ω pin 1
- Arduino Uno R3 pin 7; Ultrasonic ranger pin TRIG
- Arduino Uno R3 pin 6; Ultrasonic ranger pin ECHO
- Arduino Uno R3 pin 5V; Ultrasonic ranger pin VCC
- Ground: Arduino Uno R3 pin GND; Ultrasonic ranger pin GND; Buzzer pin 2; LED, red pin C
- Resistor, 220 Ω pin 2; LED, red pin A
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.