LCD Ultrasonic Parking Sensor using Wokwi Simulator

The LCD Ultrasonic Parking Sensor using Wokwi Simulator is a beginner-friendly Arduino project that measures the distance between a vehicle and an obstacle, displaying real-time distance data on a 16x2 LCD screen. This project simulates a car reverse parking assistance system using an ultrasonic sensor and Arduino UNO.


Designed in the Wokwi online simulator, this project helps students and robotics enthusiasts understand distance measurement, sensor interfacing, and LCD display integration without physical hardware.

 Components Used (Wokwi Simulation)

  • Arduino UNO

  • HC-SR04 Ultrasonic Sensor

  • 16x2 LCD Display (I2C or Parallel)

  • Jumper wires

Diagram.json:
{
  "version": 1,
  "author": "LCD Ultrasonic Parking Sensor",
  "editor": "wokwi",
  "parts": [
    {
      "type": "wokwi-arduino-uno",
      "id": "uno",
      "top": 0,
      "left": 0,
      "attrs": {}
    },
    {
      "type": "wokwi-lcd1602",
      "id": "lcd1",
      "top": -200,
      "left": 100,
      "attrs": {
        "pins": "i2c"
      }
    },
    {
      "type": "wokwi-hc-sr04",
      "id": "ultrasonic1",
      "top": -100,
      "left": -150,
      "attrs": {
        "distance": "50"
      }
    },
    {
      "type": "wokwi-led",
      "id": "green_led",
      "top": 100,
      "left": 250,
      "attrs": {
        "color": "green"
      }
    },
    {
      "type": "wokwi-led",
      "id": "yellow_led",
      "top": 100,
      "left": 300,
      "attrs": {
        "color": "yellow"
      }
    },
    {
      "type": "wokwi-led",
      "id": "red_led",
      "top": 100,
      "left": 350,
      "attrs": {
        "color": "red"
      }
    },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": 120,
      "left": 250,
      "attrs": {
        "value": "220"
      }
    },
    {
      "type": "wokwi-resistor",
      "id": "r2",
      "top": 120,
      "left": 300,
      "attrs": {
        "value": "220"
      }
    },
    {
      "type": "wokwi-resistor",
      "id": "r3",
      "top": 120,
      "left": 350,
      "attrs": {
        "value": "220"
      }
    },
    {
      "type": "wokwi-buzzer",
      "id": "buzzer1",
      "top": 50,
      "left": 400,
      "attrs": {
        "volume": "0.8"
      }
    }
  ],
  "connections": [
    [
      "lcd1:VCC",
      "uno:5V",
      "red",
      [
        "v0"
      ]
    ],
    [
      "lcd1:GND",
      "uno:GND.1",
      "black",
      [
        "v0"
      ]
    ],
    [
      "lcd1:SDA",
      "uno:A4",
      "blue",
      [
        "v0"
      ]
    ],
    [
      "lcd1:SCL",
      "uno:A5",
      "green",
      [
        "v0"
      ]
    ],
    [
      "ultrasonic1:VCC",
      "uno:5V",
      "red",
      [
        "v0"
      ]
    ],
    [
      "ultrasonic1:GND",
      "uno:GND.1",
      "black",
      [
        "v0"
      ]
    ],
    [
      "ultrasonic1:TRIG",
      "uno:9",
      "orange",
      [
        "v0"
      ]
    ],
    [
      "ultrasonic1:ECHO",
      "uno:8",
      "yellow",
      [
        "v0"
      ]
    ],
    [
      "uno:A0",
      "r1:1",
      "green",
      [
        "v0"
      ]
    ],
    [
      "r1:2",
      "green_led:A",
      "green",
      [
        "v0"
      ]
    ],
    [
      "green_led:C",
      "uno:GND.2",
      "black",
      [
        "v0"
      ]
    ],
    [
      "uno:A1",
      "r2:1",
      "yellow",
      [
        "v0"
      ]
    ],
    [
      "r2:2",
      "yellow_led:A",
      "yellow",
      [
        "v0"
      ]
    ],
    [
      "yellow_led:C",
      "uno:GND.2",
      "black",
      [
        "v0"
      ]
    ],
    [
      "uno:A2",
      "r3:1",
      "red",
      [
        "v0"
      ]
    ],
    [
      "r3:2",
      "red_led:A",
      "red",
      [
        "v0"
      ]
    ],
    [
      "red_led:C",
      "uno:GND.2",
      "black",
      [
        "v0"
      ]
    ],
    [
      "uno:10",
      "buzzer1:1",
      "purple",
      [
        "v0"
      ]
    ],
    [
      "buzzer1:2",
      "uno:GND.3",
      "black",
      [
        "v0"
      ]
    ]
  ],
  "dependencies": {}
}


 How It Works



The HC-SR04 ultrasonic sensor sends ultrasonic sound waves and measures the time taken for the echo to return. Using this time, the Arduino calculates the distance to the nearest object.

  • If the object is far away → Safe distance displayed

  • If the object is close → Warning message shown on LCD

  • If the object is very near → Alert message for parking stop

The distance is continuously updated and shown on the LCD screen in centimeters.

Code:

/*
 * LCD Ultrasonic Parking Sensor with Arduino Uno
 * This project demonstrates a parking assistance system using:
 * - HC-SR04 Ultrasonic Sensor for distance measurement
 * - 16x2 I2C LCD Display for visual feedback
 * - Buzzer for audio alerts
 * - LED indicators for distance warnings
 *
 * Features:
 * - Real-time distance measurement (2cm - 400cm)
 * - Visual distance display on LCD
 * - Progressive distance warnings
 * - Audio beeping (faster as obstacle gets closer)
 * - Color-coded LED indicators (Green/Yellow/Red)
 * - Bar graph display on LCD
 */

#include <LiquidCrystal_I2C.h>

// I2C LCD Address (usually 0x27 or 0x3F)
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

// Ultrasonic Sensor Pins
#define TRIG_PIN 9
#define ECHO_PIN 8

// LED Pins
#define GREEN_LED  A0  // Safe distance (> 100cm)
#define YELLOW_LED A1  // Warning distance (50-100cm)
#define RED_LED    A2  // Danger distance (< 50cm)

// Buzzer Pin
#define BUZZER_PIN 10

// Distance thresholds (in cm)
#define SAFE_DISTANCE     100  // Green LED
#define WARNING_DISTANCE   50  // Yellow LED
#define DANGER_DISTANCE    20  // Red LED, fast beeping
#define CRITICAL_DISTANCE  10  // Continuous beeping

// Create I2C LCD object
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

// Custom characters for bar graph
byte bar1[8] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10};
byte bar2[8] = {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18};
byte bar3[8] = {0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C};
byte bar4[8] = {0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E};
byte bar5[8] = {0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};

// Variables
float distance = 0;
unsigned long lastBeepTime = 0;
int beepInterval = 1000;
bool buzzerState = false;

void setup() {
  // Initialize Serial for debugging
  Serial.begin(9600);
 
  // Initialize I2C LCD
  lcd.init();
  lcd.backlight();
 
  // Create custom characters for bar graph
  lcd.createChar(0, bar1);
  lcd.createChar(1, bar2);
  lcd.createChar(2, bar3);
  lcd.createChar(3, bar4);
  lcd.createChar(4, bar5);
 
  // Configure ultrasonic sensor pins
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
 
  // Configure LED pins
  pinMode(GREEN_LED, OUTPUT);
  pinMode(YELLOW_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);
 
  // Configure buzzer pin
  pinMode(BUZZER_PIN, OUTPUT);
 
  // Turn off all LEDs initially
  digitalWrite(GREEN_LED, LOW);
  digitalWrite(YELLOW_LED, LOW);
  digitalWrite(RED_LED, LOW);
  digitalWrite(BUZZER_PIN, LOW);
 
  // Display welcome message
  displayWelcome();
 
  Serial.println(F("Parking Sensor Initialized"));
  Serial.println(F("========================"));
}

void loop() {
  // Measure distance
  distance = getDistance();
 
  // Display on LCD
  displayDistance(distance);
 
  // Control LEDs based on distance
  controlLEDs(distance);
 
  // Control buzzer based on distance
  controlBuzzer(distance);
 
  // Debug output to Serial
  Serial.print(F("Distance: "));
  Serial.print(distance);
  Serial.println(F(" cm"));
 
  // Small delay for stability
  delay(100);
}

// Function to display welcome message
void displayWelcome() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Parking Sensor");
  lcd.setCursor(0, 1);
  lcd.print("Initializing...");
  delay(2000);
  lcd.clear();
}

// Function to measure distance using ultrasonic sensor
float getDistance() {
  // Clear the trigger pin
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
 
  // Send 10us pulse to trigger
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
 
  // Read the echo pin
  long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
 
  // Calculate distance in cm
  // Speed of sound = 343 m/s = 0.0343 cm/us
  // Distance = (duration / 2) * 0.0343
  float dist = duration * 0.0343 / 2.0;
 
  // Return 0 if out of range or invalid
  if (dist == 0 || dist > 400) {
    return 0;
  }
 
  return dist;
}

// Function to display distance on LCD
void displayDistance(float dist) {
  lcd.setCursor(0, 0);
 
  if (dist == 0) {
    lcd.print("Distance: ---   ");
    lcd.setCursor(0, 1);
    lcd.print("Out of Range    ");
  } else if (dist < CRITICAL_DISTANCE) {
    lcd.print("Distance:");
    lcd.print(dist, 1);
    lcd.print("cm ");
    lcd.setCursor(0, 1);
    lcd.print("STOP! TOO CLOSE!");
  } else if (dist < DANGER_DISTANCE) {
    lcd.print("Distance:");
    lcd.print(dist, 1);
    lcd.print("cm ");
    lcd.setCursor(0, 1);
    lcd.print("DANGER!         ");
  } else if (dist < WARNING_DISTANCE) {
    lcd.print("Distance:");
    lcd.print(dist, 1);
    lcd.print("cm ");
    lcd.setCursor(0, 1);
    lcd.print("WARNING: Slow!  ");
  } else if (dist < SAFE_DISTANCE) {
    lcd.print("Distance:");
    lcd.print(dist, 1);
    lcd.print("cm ");
    lcd.setCursor(0, 1);
    lcd.print("Caution         ");
  } else {
    lcd.print("Distance:");
    lcd.print(dist, 1);
    lcd.print("cm ");
    lcd.setCursor(0, 1);
    lcd.print("Safe ");
   
    // Display bar graph for safe distance
    displayBarGraph(dist);
  }
}

// Function to display bar graph on LCD
void displayBarGraph(float dist) {
  // Map distance to bar length (0-10 characters)
  int barLength = map(dist, 100, 400, 0, 10);
  barLength = constrain(barLength, 0, 10);
 
  lcd.setCursor(5, 1);
 
  for (int i = 0; i < 10; i++) {
    if (i < barLength) {
      lcd.write(byte(4)); // Full bar
    } else {
      lcd.print(" ");
    }
  }
}

// Function to control LEDs based on distance
void controlLEDs(float dist) {
  if (dist == 0) {
    // Out of range - all LEDs off
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(YELLOW_LED, LOW);
    digitalWrite(RED_LED, LOW);
  } else if (dist < DANGER_DISTANCE) {
    // Danger zone - Red LED flashing
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(YELLOW_LED, LOW);
    digitalWrite(RED_LED, (millis() / 200) % 2); // Flash every 200ms
  } else if (dist < WARNING_DISTANCE) {
    // Warning zone - Yellow LED on
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(YELLOW_LED, HIGH);
    digitalWrite(RED_LED, LOW);
  } else if (dist < SAFE_DISTANCE) {
    // Caution zone - Yellow LED slow blink
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(YELLOW_LED, (millis() / 500) % 2); // Blink every 500ms
    digitalWrite(RED_LED, LOW);
  } else {
    // Safe zone - Green LED on
    digitalWrite(GREEN_LED, HIGH);
    digitalWrite(YELLOW_LED, LOW);
    digitalWrite(RED_LED, LOW);
  }
}

// Function to control buzzer based on distance
void controlBuzzer(float dist) {
  unsigned long currentTime = millis();
 
  if (dist == 0 || dist >= SAFE_DISTANCE) {
    // No beeping when safe or out of range
    digitalWrite(BUZZER_PIN, LOW);
    buzzerState = false;
    return;
  }
 
  // Calculate beep interval based on distance
  if (dist < CRITICAL_DISTANCE) {
    // Critical: Continuous beep
    digitalWrite(BUZZER_PIN, HIGH);
    return;
  } else if (dist < DANGER_DISTANCE) {
    // Danger: Fast beeping (200ms interval)
    beepInterval = 200;
  } else if (dist < WARNING_DISTANCE) {
    // Warning: Medium beeping (500ms interval)
    beepInterval = 500;
  } else {
    // Caution: Slow beeping (1000ms interval)
    beepInterval = 1000;
  }
 
  // Toggle buzzer at calculated interval
  if (currentTime - lastBeepTime >= beepInterval) {
    buzzerState = !buzzerState;
    digitalWrite(BUZZER_PIN, buzzerState);
    lastBeepTime = currentTime;
  }
}

// Function to display detailed statistics (optional - call from loop if needed)
void displayStats() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Min: 2cm");
  lcd.setCursor(0, 1);
  lcd.print("Max: 400cm");
  delay(2000);
  lcd.clear();
}


 Key Features

  • Real-time distance monitoring

  • LCD display output

  • Parking warning system simulation

  • Adjustable obstacle distance in Wokwi

  • Beginner-friendly Arduino project


 Learning Outcomes

  • Understanding ultrasonic sensor working principle

  • Distance calculation using Arduino

  • LCD interfacing with Arduino

  • Practical IoT and automation basics

  • Simulation-based hardware learning

 

Comments