/*
* 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();
}
Comments
Post a Comment