Ultrasonic Smart Parking Assistant Using ESP8266/ESP32 and Blynk
Build a two-slot smart parking assistant using ESP8266 or ESP32, two ultrasonic sensors, an I2C LCD, and Blynk to show distance, parking status, and Safe/Warning/Stop zones.
- ESP8266
- ESP32
- Ultrasonic Sensor
- HC-SR04
- Smart Parking
- Parking Assistant
- I2C LCD
- Blynk
- IOT
- Distance Measurement
- Published
- Updated
- Reading time
- 3 min read
- Author
- Saroj Chaudhary
- Role
- IoT & Embedded Systems Engineer
This project creates a two-slot smart parking assistant using two ultrasonic sensors.
Each sensor measures the distance between a vehicle and the end of a parking slot. The ESP8266 or ESP32 classifies the distance into Safe, Warning, and Stop zones, shows the slot condition on a 16x2 I2C LCD, and sends the same information to Blynk.
The same project works with both ESP8266 and ESP32. The required library and GPIO differences are explained below.
Components Required
| Component | Quantity |
|---|---|
| ESP8266 NodeMCU or ESP32 Dev Board | 1 |
| HC-SR04 Ultrasonic Sensor | 2 |
| 16x2 I2C LCD | 1 |
| Breadboard | 1 |
| Jumper Wires | As required |
| Resistors for Echo voltage divider | 4 |
| USB / Suitable Power Supply | 1 |
Important: The HC-SR04 Echo pin can output around 5V. ESP8266 and ESP32 GPIO are 3.3V devices, so use a voltage divider on each Echo pin.
A simple divider can be:
HC-SR04 Echo
|
1kΩ
|
+-----> ESP GPIO
|
2kΩ
|
GND
How the Parking System Works
Two ultrasonic sensors monitor two separate parking slots.
Sensor 1 -> Slot 1
\
ESP8266 / ESP32
/
Sensor 2 -> Slot 2
|
+----+----+
| |
LCD Blynk
The controller checks the distance and decides whether each slot is:
EMPTY
PARKED - SAFE
PARKED - WARNING
PARKED - STOP
Parking Distance Zones
The example uses:
Distance > 100 cm -> EMPTY
26-100 cm -> PARKED / SAFE
11-25 cm -> PARKED / WARNING
0-10 cm -> PARKED / STOP
These values can be changed according to the dimensions of your parking model.
LCD Display
The LCD displays both slot conditions at the same time.
Example:
S1 42cm SAFE
S2 EMPTY
Another condition:
S1 08cm STOP
S2 18cm WARN
ESP8266 and ESP32 Connections
ESP8266 NodeMCU
| Device | ESP8266 Pin |
|---|---|
| LCD SDA | D2 / GPIO4 |
| LCD SCL | D1 / GPIO5 |
| Slot 1 Trig | D5 / GPIO14 |
| Slot 1 Echo | D6 / GPIO12 |
| Slot 2 Trig | D7 / GPIO13 |
| Slot 2 Echo | D0 / GPIO16 |
ESP32
| Device | ESP32 Pin |
|---|---|
| LCD SDA | GPIO21 |
| LCD SCL | GPIO22 |
| Slot 1 Trig | GPIO18 |
| Slot 1 Echo | GPIO19 |
| Slot 2 Trig | GPIO25 |
| Slot 2 Echo | GPIO26 |
Both ultrasonic sensors may share the same supply and ground, but each sensor must use its own Trig and Echo pins.
Required Libraries
Install these libraries from Arduino IDE Library Manager:
Blynk
LiquidCrystal_I2C
For ESP8266, the code uses:
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
For ESP32, the code uses:
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
The code below selects the correct libraries automatically.
Blynk Setup
Create these datastreams:
| Datastream | Virtual Pin | Type |
|---|---|---|
| Slot 1 Distance | V0 | Integer |
| Slot 1 Status | V1 | String |
| Slot 2 Distance | V2 | Integer |
| Slot 2 Status | V3 | String |
Example values:
Slot 1 Distance: 42 cm
Slot 1 Status: PARKED-SAFE
Slot 2 Distance: 150 cm
Slot 2 Status: EMPTY
Complete ESP8266/ESP32 Code
#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "YOUR_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "Smart Parking Assistant"
#define BLYNK_AUTH_TOKEN "YOUR_AUTH_TOKEN"
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
const int TRIG1 = D5;
const int ECHO1 = D6;
const int TRIG2 = D7;
const int ECHO2 = D0;
#elif defined(ESP32)
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
const int TRIG1 = 18;
const int ECHO1 = 19;
const int TRIG2 = 25;
const int ECHO2 = 26;
#else
#error "Select an ESP8266 or ESP32 board in Arduino IDE."
#endif
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
char ssid[] = "YOUR_WIFI_NAME";
char pass[] = "YOUR_WIFI_PASSWORD";
LiquidCrystal_I2C lcd(0x27, 16, 2);
BlynkTimer timer;
const int STOP_DISTANCE = 10;
const int WARNING_DISTANCE = 25;
const int OCCUPIED_DISTANCE = 100;
long readDistanceCM(int trigPin, int echoPin)
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
if (duration == 0)
return 999;
return duration * 0.0343 / 2;
}
String getParkingStatus(long distance)
{
if (distance > OCCUPIED_DISTANCE)
return "EMPTY";
if (distance <= STOP_DISTANCE)
return "PARKED-STOP";
if (distance <= WARNING_DISTANCE)
return "PARKED-WARN";
return "PARKED-SAFE";
}
String getLCDStatus(long distance)
{
if (distance > OCCUPIED_DISTANCE)
return "EMPTY";
if (distance <= STOP_DISTANCE)
return "STOP";
if (distance <= WARNING_DISTANCE)
return "WARN";
return "SAFE";
}
void printSlotToLCD(int row, int slotNumber, long distance, String status)
{
lcd.setCursor(0, row);
lcd.print(" ");
lcd.setCursor(0, row);
lcd.print("S");
lcd.print(slotNumber);
lcd.print(" ");
if (status == "EMPTY")
{
lcd.print("EMPTY");
}
else
{
if (distance < 10)
lcd.print("0");
lcd.print(distance);
lcd.print("cm ");
lcd.print(status);
}
}
void updateParking()
{
long distance1 = readDistanceCM(TRIG1, ECHO1);
// Small delay reduces interference between the two ultrasonic sensors.
delay(60);
long distance2 = readDistanceCM(TRIG2, ECHO2);
String slot1Status = getParkingStatus(distance1);
String slot2Status = getParkingStatus(distance2);
String slot1LCD = getLCDStatus(distance1);
String slot2LCD = getLCDStatus(distance2);
printSlotToLCD(0, 1, distance1, slot1LCD);
printSlotToLCD(1, 2, distance2, slot2LCD);
Serial.print("Slot 1: ");
Serial.print(distance1);
Serial.print(" cm | ");
Serial.println(slot1Status);
Serial.print("Slot 2: ");
Serial.print(distance2);
Serial.print(" cm | ");
Serial.println(slot2Status);
if (Blynk.connected())
{
Blynk.virtualWrite(V0, distance1);
Blynk.virtualWrite(V1, slot1Status);
Blynk.virtualWrite(V2, distance2);
Blynk.virtualWrite(V3, slot2Status);
}
}
void setup()
{
Serial.begin(115200);
pinMode(TRIG1, OUTPUT);
pinMode(ECHO1, INPUT);
pinMode(TRIG2, OUTPUT);
pinMode(ECHO2, INPUT);
#if defined(ESP8266)
Wire.begin(D2, D1);
#elif defined(ESP32)
Wire.begin(21, 22);
#endif
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Smart Parking");
lcd.setCursor(0, 1);
lcd.print("Starting...");
Blynk.begin(
BLYNK_AUTH_TOKEN,
ssid,
pass
);
timer.setInterval(1000L, updateParking);
delay(1000);
lcd.clear();
}
void loop()
{
Blynk.run();
timer.run();
}
Arduino IDE Board Selection
ESP8266
Select:
Tools
-> Board
-> ESP8266 Boards
-> NodeMCU 1.0 (ESP-12E Module)
The ESP8266 build automatically uses:
ESP8266WiFi.h
BlynkSimpleEsp8266.h
D5, D6, D7 and D0
ESP32
Select:
Tools
-> Board
-> ESP32 Arduino
-> ESP32 Dev Module
The ESP32 build automatically uses:
WiFi.h
BlynkSimpleEsp32.h
GPIO18, GPIO19, GPIO25 and GPIO26
Testing the Parking System
Empty Slot
If no vehicle is within 100 cm:
LCD:
S1 EMPTY
Blynk:
Slot 1 Status = EMPTY
Safe Zone
Distance = 55 cm
LCD:
S1 55cm SAFE
Blynk:
PARKED-SAFE
Warning Zone
Distance = 20 cm
LCD:
S1 20cm WARN
Blynk:
PARKED-WARN
Stop Zone
Distance = 8 cm
LCD:
S1 08cm STOP
Blynk:
PARKED-STOP
Test both Slot 1 and Slot 2 independently.
Adjusting the Parking Zones
Change:
const int STOP_DISTANCE = 10;
const int WARNING_DISTANCE = 25;
const int OCCUPIED_DISTANCE = 100;
according to your parking model.
Common Problems
Distance Shows 999
Check:
- Trig connection
- Echo connection
- sensor power
- common ground
- Echo voltage divider
Unstable Readings
Two ultrasonic sensors can interfere with each other if triggered at the same time.
This example reads them one after another with a short delay to reduce interference.
LCD Shows Nothing
Check:
- SDA and SCL wiring
- LCD power
- I2C address
Common LCD addresses include:
0x27
0x3F
Blynk Does Not Update
Check:
- Wi-Fi credentials
- Blynk Template ID
- Auth Token
- V0 to V3 datastream configuration
Final Result
The completed system monitors two parking slots.
Each slot shows:
Distance
PARKED or EMPTY
SAFE / WARNING / STOP
The same information is available locally on the LCD and remotely through Blynk.
For a real outdoor parking system, use weather-resistant sensors and a suitable enclosure instead of relying on an exposed HC-SR04 module.