Community project

ESP32 Parking Distance Alert

ESP32
Photo of ESP32 Parking Distance Alert
Generated with AI

EJEZ3D

Published August 31, 2026

This project builds a parking distance alert system using an ESP32 microcontroller and ultrasonic sensor to warn drivers as they approach an obstacle. The system displays real-time distance on an OLED screen and provides visual and audio feedback through color-coded LEDs and a buzzer that accelerates as the obstacle gets closer.

The guide includes a complete wiring diagram, parts list, and ready-to-upload firmware. Assembly takes about 30 minutes and involves connecting the HC-SR04P distance sensor, mounting the OLED display, wiring the three indicator LEDs with current-limiting resistors, and adding the piezo buzzer. Testing against a wall verifies all distance thresholds and alert outputs are working correctly.

Wiring diagram

Wiring diagram for ESP32 Parking Distance Alert

Gather all the parts

QtyComponent
1

HC-SR04P Ultrasonic Distance Sensor

3.3V-compatible ultrasonic distance sensor for measuring the gap to an object.

1

0.96 inch SSD1306 OLED Display

Small I2C display for the live distance reading and warning state.

1

Green LED

Clear-zone indicator. Use a current-limiting resistor in series.

1

Yellow LED

Caution-zone indicator. Use a current-limiting resistor in series.

1

Red LED

Stop-zone indicator. Use a current-limiting resistor in series.

1

Passive Piezo Buzzer

Audible warning that beeps faster in the stop zone.

1

220 Ω resistor

Current limiting or transistor-base resistor required by the wiring.

Assemble it in 4 steps

1. Wire the distance sensor

Connect the HC-SR04P VCC and GND to the ESP32 3V3 and GND rails, then connect TRIG to GPIO27 and ECHO to GPIO26.

  • Use the HC-SR04P 3.3V-compatible module, not a 5V-only HC-SR04, unless you add proper level shifting.
  • Do not connect a 5V echo signal directly to an ESP32 GPIO.

2. Add the display

Connect the SSD1306 OLED to the same 3V3 and GND rails, with SDA on GPIO21 and SCL on GPIO22.

  • If the OLED stays blank, check whether your module uses address 0x3C or 0x3D.

3. Add the warning outputs

Connect the green LED to GPIO14, yellow LED to GPIO12, red LED to GPIO13, and the passive buzzer signal pin to GPIO25. Each LED should use a current-limiting resistor.

  • Place the LEDs left to right as green, yellow, red so the warning pattern reads naturally.
  • Do not drive bare LEDs directly from GPIO without resistors.

4. Upload and test against a wall

Upload the sketch, aim the sensor at a flat surface, and move it from about one metre away to the stop zone. The OLED, LEDs, and buzzer should change together.

  • Cardboard, foam board, or a book makes a better test target than a thin chair leg.
  • This is a learning aid, not a safety-rated vehicle parking system.

Review all connections

1. Connections between "hc-sr04p-ultrasonic-sensor_0" and "ESP32"

Functionhc-sr04p-ultrasonic-sensor_0ESP32
powerVCC3V3
groundGNDGND
digitalTRIGGPIO 27
digitalECHOGPIO 26

2. Connections between "ssd1306-oled_0" and "ESP32"

Functionssd1306-oled_0ESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 21
i2cSCLGPIO 22

3. Connections between "green-led_0" and "ESP32"

Functiongreen-led_0ESP32
digitalANODEGPIO 14
groundCATHODEGND

4. Connections between "yellow-led_0" and "ESP32"

Functionyellow-led_0ESP32
digitalANODEGPIO 12
groundCATHODEGND

5. Connections between "red-led_0" and "ESP32"

Functionred-led_0ESP32
digitalANODEGPIO 13
groundCATHODEGND

6. Connections between "passive-buzzer_0" and "ESP32"

Functionpassive-buzzer_0ESP32
digitalSIGGPIO 25
groundGNDGND

7. Connections between "esp32-ultrasonic-parking-sensor-220-ohm-resistor-1" and "ESP32"

Functionesp32-ultrasonic-parking-sensor-220-ohm-resistor-1ESP32
current-limitgreen-led:ANODEGPIO 14
current-limitgreen-led:ANODEEXT
current-limityellow-led:ANODEGPIO 12
current-limityellow-led:ANODEEXT
current-limitred-led:ANODEGPIO 13
current-limitred-led:ANODEEXT

Deploy the firmware

schematik_esp32.inoOpen in Schematik
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define TRIG_PIN 27
#define ECHO_PIN 26
#define GREEN_LED_PIN 14
#define YELLOW_LED_PIN 12
#define RED_LED_PIN 13
#define BUZZER_PIN 25
#define SDA_PIN 21
#define SCL_PIN 22
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

const int SAFE_DISTANCE_CM = 70;
const int CAUTION_DISTANCE_CM = 35;
const int STOP_DISTANCE_CM = 18;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
float smoothedDistance = 100;
unsigned long lastBeepMs = 0;
bool buzzerOn = false;

float readDistanceCm() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  if (duration == 0) return smoothedDistance;
  return duration / 58.0;
}

void setOutputs(float distanceCm) {
  bool safe = distanceCm > SAFE_DISTANCE_CM;
  bool caution = distanceCm <= SAFE_DISTANCE_CM && distanceCm > CAUTION_DISTANCE_CM;
  bool warning = distanceCm <= CAUTION_DISTANCE_CM;

  digitalWrite(GREEN_LED_PIN, safe ? HIGH : LOW);
  digitalWrite(YELLOW_LED_PIN, caution ? HIGH : LOW);
  digitalWrite(RED_LED_PIN, warning ? HIGH : LOW);

  if (!warning) {
    noTone(BUZZER_PIN);
    buzzerOn = false;
    return;
  }

  int interval = distanceCm <= STOP_DISTANCE_CM ? 120 : 320;
  if (millis() - lastBeepMs > interval) {
    lastBeepMs = millis();
    buzzerOn = !buzzerOn;
    if (buzzerOn) tone(BUZZER_PIN, distanceCm <= STOP_DISTANCE_CM ? 1800 : 1200);
    else noTone(BUZZER_PIN);
  }
}

void drawDisplay(float distanceCm) {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println("Parking sensor");
  display.setTextSize(2);
  display.setCursor(0, 18);
  display.print(distanceCm, 0);
  display.println(" cm");
  display.setTextSize(1);
  display.setCursor(0, 48);
  if (distanceCm <= STOP_DISTANCE_CM) display.println("STOP");
  else if (distanceCm <= CAUTION_DISTANCE_CM) display.println("Slow down");
  else if (distanceCm <= SAFE_DISTANCE_CM) display.println("Getting close");
  else display.println("Clear");
  display.display();
}

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(YELLOW_LED_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);

  Wire.begin(SDA_PIN, SCL_PIN);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display();
}

void loop() {
  float reading = readDistanceCm();
  smoothedDistance = (smoothedDistance * 0.75) + (reading * 0.25);
  setOutputs(smoothedDistance);
  drawDisplay(smoothedDistance);
  delay(80);
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik