RGB LED Features:
- Smooth color transitions from red → yellow → green → blue based on distance
- Blinking red alert for objects closer than threshold
- Color-coded distance ranges with adjustable thresholds
- White LED when out of range
Buzzer Features:
- Continuous beep for very close objects (critical range)
- Rapid beeps for close objects
- Medium-speed beeps for medium distance
- Slow beeps for far objects
- Silent for very far distances
- Audio on/off control via Serial commands
Combined Operation:
Both systems work simultaneously:
- Close object = Blinking red LED + continuous high-pitched beep
- Medium distance = Yellow/orange LED + medium beeps
- Far distance = Green/blue LED + slow beeps
- Very far = Blue LED + silent
Quick Commands:
- Type
audio offto disable buzzer (LED still works) - Type
audio onto re-enable buzzer - Type
highfor maximum sensitivity - Type
settingsto see current configuration
The system is designed to give you both visual and audio feedback simultaneously, making it perfect for applications where you need multiple types of alerts (like parking sensors, proximity alarms, etc.).
Would you like me to modify any specific aspect of how the RGB LED and buzzer work together?
/*
* Complete Adjustable Sensitivity Ultrasonic Range Finder
* with RGB LED Visual Feedback and Audio Buzzer
*
* Features:
* - Adjustable distance thresholds
* - Noise filtering with configurable samples
* - Smoothing filter for stable readings
* - Change threshold to prevent jitter
* - Multiple sensitivity presets
* - Real-time sensitivity adjustment via Serial commands
*/
// Pin definitions
const int trigPin = 9;
const int echoPin = 10;
const int redPin = 3;
const int greenPin = 5;
const int bluePin = 6;
const int buzzerPin = 8;
// === SENSITIVITY SETTINGS ===
// Distance thresholds (in cm)
float CLOSE_THRESHOLD = 5.0; // Distance for red blinking alert
float MEDIUM_THRESHOLD = 25.0; // Red to yellow transition
float FAR_THRESHOLD = 50.0; // Yellow to green transition
float MAX_THRESHOLD = 75.0; // Green to blue transition
float MAX_RANGE = 100.0; // Maximum effective range
// Filter settings
int FILTER_SAMPLES = 5; // Number of readings to average (1-10)
float CHANGE_THRESHOLD = 1.5; // Minimum change to respond (cm)
float SMOOTHING_FACTOR = 0.3; // Response speed (0.1=smooth, 0.9=responsive)
// Audio settings
bool AUDIO_ENABLED = true; // Enable/disable buzzer
int CLOSE_BEEP_FREQ = 2000; // Frequency for close objects
int FAR_BEEP_FREQ = 500; // Frequency for far objects
// System variables
float lastDistance = 0;
float lastReportedDistance = 0;
unsigned long lastReadingTime = 0;
int readingDelay = 50; // Delay between readings (ms)
void setup() {
Serial.begin(9600);
// Initialize pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
// Initial LED test
testLED();
// Print initial settings
printSettings();
printCommands();
}
void loop() {
// Check for serial commands
if (Serial.available()) {
processSerialCommand();
}
// Take reading at specified interval
if (millis() - lastReadingTime >= readingDelay) {
float distance = getFilteredDistance();
// Always update visual and audio feedback
if (distance != -1) {
setVisualFeedback(distance);
setAudioFeedback(distance);
// Only print if change is significant
if (abs(distance - lastReportedDistance) > CHANGE_THRESHOLD) {
lastReportedDistance = distance;
// Print distance with sensitivity info
Serial.print("Distance: ");
Serial.print(distance, 1);
Serial.print(" cm | Range: ");
Serial.println(getDistanceRange(distance));
}
} else {
// Out of range
setColor(255, 255, 255); // White for out of range
noTone(buzzerPin);
Serial.println("Out of range");
}
lastReadingTime = millis();
}
}
// === DISTANCE MEASUREMENT ===
float getRawDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000); // 30ms timeout
if (duration == 0) {
return -1; // No echo received
}
float distance = duration * 0.01715; // Convert to cm
// Validate reading
if (distance < 2 || distance > 400) {
return -1; // Invalid reading
}
return distance;
}
float getFilteredDistance() {
float readings[10]; // Max 10 samples
int validReadings = 0;
// Take multiple readings
for (int i = 0; i < FILTER_SAMPLES; i++) {
float reading = getRawDistance();
if (reading != -1) {
readings[validReadings] = reading;
validReadings++;
}
if (i < FILTER_SAMPLES - 1) delay(10); // Small delay between readings
}
if (validReadings == 0) {
return -1; // No valid readings
}
// Calculate median for better noise rejection
float median = calculateMedian(readings, validReadings);
// Apply smoothing filter
if (lastDistance == 0) {
lastDistance = median; // Initialize on first reading
} else {
lastDistance = (SMOOTHING_FACTOR * median) + ((1 - SMOOTHING_FACTOR) * lastDistance);
}
return lastDistance;
}
float calculateMedian(float arr[], int size) {
// Simple bubble sort
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
float temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
// Return median
if (size % 2 == 0) {
return (arr[size/2 - 1] + arr[size/2]) / 2.0;
} else {
return arr[size/2];
}
}
// === VISUAL FEEDBACK ===
void setColor(int red, int green, int blue) {
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
void setVisualFeedback(float distance) {
// Simple red to blue gradient based on distance
distance = constrain(distance, 5, MAX_RANGE); // Start from 5cm minimum
// Map distance to red-blue spectrum
int redValue = map(distance, 5, MAX_RANGE, 255, 0); // Close = bright red
int blueValue = map(distance, 5, MAX_RANGE, 0, 255); // Far = bright blue
setColor(redValue, 0, blueValue);
// Debug output
Serial.print("LED - Distance: ");
Serial.print(distance);
Serial.print(" Red: ");
Serial.print(redValue);
Serial.print(" Blue: ");
Serial.println(blueValue);
}
// === AUDIO FEEDBACK ===
void setAudioFeedback(float distance) {
if (!AUDIO_ENABLED) {
noTone(buzzerPin);
return;
}
static unsigned long lastBeepTime = 0;
static bool beepState = false;
unsigned long currentTime = millis();
// Don't beep if too far
if (distance > MAX_RANGE) {
noTone(buzzerPin);
return;
}
// Calculate beep interval based on distance (closer = faster beeps)
int beepInterval;
if (distance < 10) {
beepInterval = 150; // Very fast beeps for very close
} else if (distance < 25) {
beepInterval = 300; // Fast beeps for close
} else if (distance < 50) {
beepInterval = 600; // Medium beeps
} else {
beepInterval = 1000; // Slow beeps for far
}
// Toggle beep on/off at calculated interval
if (currentTime - lastBeepTime >= beepInterval) {
if (beepState) {
// Turn off beep
noTone(buzzerPin);
beepState = false;
Serial.print("Beep OFF - Interval: ");
Serial.println(beepInterval);
} else {
// Turn on beep
int frequency = map(constrain(distance, 5, MAX_RANGE), 5, MAX_RANGE, 2000, 500);
tone(buzzerPin, frequency);
beepState = true;
Serial.print("Beep ON - Freq: ");
Serial.print(frequency);
Serial.print(" Interval: ");
Serial.println(beepInterval);
}
lastBeepTime = currentTime;
}
}
// === UTILITY FUNCTIONS ===
String getDistanceRange(float distance) {
if (distance < CLOSE_THRESHOLD) return "CRITICAL";
else if (distance < MEDIUM_THRESHOLD) return "CLOSE";
else if (distance < FAR_THRESHOLD) return "MEDIUM";
else if (distance < MAX_THRESHOLD) return "FAR";
else return "CLEAR";
}
void testLED() {
Serial.println("Testing LED...");
setColor(255, 0, 0); delay(300); // Red
setColor(0, 255, 0); delay(300); // Green
setColor(0, 0, 255); delay(300); // Blue
setColor(0, 0, 0); // Off
}
// === SENSITIVITY PRESETS ===
void setHighSensitivity() {
CLOSE_THRESHOLD = 3.0;
MEDIUM_THRESHOLD = 15.0;
FAR_THRESHOLD = 30.0;
MAX_THRESHOLD = 50.0;
MAX_RANGE = 75.0;
FILTER_SAMPLES = 7;
CHANGE_THRESHOLD = 0.5;
SMOOTHING_FACTOR = 0.6;
Serial.println("HIGH sensitivity preset loaded");
}
void setMediumSensitivity() {
CLOSE_THRESHOLD = 5.0;
MEDIUM_THRESHOLD = 25.0;
FAR_THRESHOLD = 50.0;
MAX_THRESHOLD = 75.0;
MAX_RANGE = 100.0;
FILTER_SAMPLES = 5;
CHANGE_THRESHOLD = 1.5;
SMOOTHING_FACTOR = 0.3;
Serial.println("MEDIUM sensitivity preset loaded");
}
void setLowSensitivity() {
CLOSE_THRESHOLD = 10.0;
MEDIUM_THRESHOLD = 40.0;
FAR_THRESHOLD = 80.0;
MAX_THRESHOLD = 120.0;
MAX_RANGE = 150.0;
FILTER_SAMPLES = 3;
CHANGE_THRESHOLD = 3.0;
SMOOTHING_FACTOR = 0.1;
Serial.println("LOW sensitivity preset loaded");
}
// === SERIAL COMMANDS ===
void processSerialCommand() {
String command = Serial.readStringUntil('\n');
command.trim();
command.toLowerCase();
if (command == "help" || command == "h") {
printCommands();
}
else if (command == "settings" || command == "s") {
printSettings();
}
else if (command == "high" || command == "1") {
setHighSensitivity();
}
else if (command == "medium" || command == "2") {
setMediumSensitivity();
}
else if (command == "low" || command == "3") {
setLowSensitivity();
}
else if (command == "audio on") {
AUDIO_ENABLED = true;
Serial.println("Audio enabled");
}
else if (command == "audio off") {
AUDIO_ENABLED = false;
noTone(buzzerPin);
Serial.println("Audio disabled");
}
else if (command.startsWith("close ")) {
float value = command.substring(6).toFloat();
if (value > 0 && value < 50) {
CLOSE_THRESHOLD = value;
Serial.println("Close threshold set to " + String(value) + " cm");
}
}
else if (command.startsWith("samples ")) {
int value = command.substring(8).toInt();
if (value >= 1 && value <= 10) {
FILTER_SAMPLES = value;
Serial.println("Filter samples set to " + String(value));
}
}
else if (command.startsWith("smooth ")) {
float value = command.substring(7).toFloat();
if (value >= 0.1 && value <= 0.9) {
SMOOTHING_FACTOR = value;
Serial.println("Smoothing factor set to " + String(value));
}
}
else {
Serial.println("Unknown command. Type 'help' for available commands.");
}
}
void printCommands() {
Serial.println("\n=== AVAILABLE COMMANDS ===");
Serial.println("help / h - Show this help");
Serial.println("settings / s - Show current settings");
Serial.println("high / 1 - High sensitivity preset");
Serial.println("medium / 2 - Medium sensitivity preset (default)");
Serial.println("low / 3 - Low sensitivity preset");
Serial.println("audio on/off - Enable/disable buzzer");
Serial.println("close [value] - Set close threshold (1-50 cm)");
Serial.println("samples [value] - Set filter samples (1-10)");
Serial.println("smooth [value] - Set smoothing (0.1-0.9)");
Serial.println("========================\n");
}
void printSettings() {
Serial.println("\n=== CURRENT SETTINGS ===");
Serial.println("Close threshold: " + String(CLOSE_THRESHOLD) + " cm");
Serial.println("Medium threshold: " + String(MEDIUM_THRESHOLD) + " cm");
Serial.println("Far threshold: " + String(FAR_THRESHOLD) + " cm");
Serial.println("Max threshold: " + String(MAX_THRESHOLD) + " cm");
Serial.println("Max range: " + String(MAX_RANGE) + " cm");
Serial.println("Filter samples: " + String(FILTER_SAMPLES));
Serial.println("Change threshold: " + String(CHANGE_THRESHOLD) + " cm");
Serial.println("Smoothing factor: " + String(SMOOTHING_FACTOR));
Serial.println("Audio: " + String(AUDIO_ENABLED ? "ON" : "OFF"));
Serial.println("========================\n");
}