Overview

The HC-SR04 ultrasonic sensor is one of the most popular distance measuring sensors in electronics projects. It uses ultrasonic waves (sound waves above human hearing range) to measure distances from 2cm to 400cm with 3mm accuracy.

Unlike infrared sensors, ultrasonic sensors are less affected by color or transparency of objects, making them ideal for various applications from robotics to industrial automation.

Key Advantages

Ultrasonic vs Other Sensors:

  • ✓ Not affected by object color or transparency
  • ✓ Works in dark or bright environments
  • ✓ Can detect various materials (metal, plastic, wood, etc.)
  • ✓ Relatively long range (up to 4 meters)
  • ✓ Good accuracy (3mm at close range)
  • ✓ Reasonably priced and widely available

Prerequisites

Before starting, make sure you have completed:

Completed Lessons
  • Lesson 1: Blinking LED (Digital Output)
  • Lesson 2: Push Button (Digital Input)
  • Lesson 4: Potentiometer (Timing concepts)
  • Lesson 9: Servo Motor Control (for radar project)
  • Understanding of pulseIn() function
Hardware Requirements
  • Vumbua Synapse Kit with HC-SR04 sensor
  • USB Type-C cable
  • Computer with Arduino IDE
  • Various objects for testing
Vumbua Synapse Kit Configuration

The HC-SR04 ultrasonic sensor is pre-connected to your Vumbua board:

  • Trigger (TR): Connected to Digital Pin 6 (D6)
  • Echo (EC): Connected to Digital Pin 5 (D5)
  • VCC: Connected to 5V
  • GND: Connected to Ground

Learning Objectives

By the end of this lesson, you will be able to:

  • Understand how ultrasonic sensors work (sonar principle)
  • Properly wire the HC-SR04 sensor to ATmega328P
  • Use the pulseIn() function to measure time intervals
  • Calculate distance using time-of-flight measurements
  • Create an obstacle detection system
  • Build a parking sensor with visual/audio feedback
  • Develop a simple radar display using servo motor
  • Troubleshoot common ultrasonic sensor issues
  • Apply ultrasonic sensing to real-world projects

What is an Ultrasonic Sensor?

Definition

An ultrasonic sensor is a device that measures distance by emitting high-frequency sound waves (ultrasonic waves) and listening for their echo. By measuring the time it takes for the echo to return, it calculates the distance to an object.

This technique is called SONAR (SOund Navigation And Ranging), the same technology used by bats, submarines, and medical ultrasound.

HC-SR04 Specifications
  • Operating Voltage: 5V DC
  • Operating Current: 15mA
  • Measuring Angle: 15 degrees
  • Measuring Range: 2cm to 400cm (4 meters)
  • Resolution: 0.3cm
  • Accuracy: ±3mm
  • Frequency: 40kHz
  • Dimensions: 45mm × 20mm × 15mm
Components of HC-SR04
  • Ultrasonic Transmitter: Emits 40kHz sound waves
  • Ultrasonic Receiver: Detects reflected waves
  • Control Circuit: Manages timing and signal processing
  • Power Regulator: Ensures stable 5V operation

How Ultrasonic Distance Measurement Works

Distance: 150 cm
Step 1: Trigger Pulse

The microcontroller sends a 10μs HIGH pulse to the Trigger pin. This tells the sensor to emit 8 cycles of 40kHz ultrasonic bursts.

digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Step 2: Sound Emission & Echo

The sensor emits ultrasonic waves that travel through air at 343 meters/second (at 20°C). When the waves hit an object, they bounce back as an echo.

The Echo pin goes HIGH when waves are emitted and stays HIGH until the echo is detected.

Step 3: Echo Detection

The receiver detects the echo and the Echo pin goes LOW. We measure how long the Echo pin was HIGH using pulseIn().

duration = pulseIn(echoPin, HIGH);
Step 4: Distance Calculation

Distance = (Speed of Sound × Time) ÷ 2

We divide by 2 because the sound travels to the object AND back.

distance = (duration × 0.0343) ÷ 2

Where 0.0343 cm/μs is the speed of sound at 20°C.

HC-SR04 Pin Connections

The HC-SR04 ultrasonic sensor has 4 pins:

VCC
Power Supply (5V)
5V
TRIG
Trigger Input (Digital)
D6
ECHO
Echo Output (Digital)
D5
GND
Ground (0V)
GND
Important Note on Vumbua Kit

On the Vumbua Synapse Kit, the HC-SR04 is pre-connected to:

  • TRIG (Trigger): Digital Pin 6 (D6) - ATmega328P PD6
  • ECHO (Echo): Digital Pin 5 (D5) - ATmega328P PD5

This configuration ensures optimal performance and avoids pin conflicts with other sensors on the board.

HC-SR04 on Vumbua Synapse Kit

The ultrasonic sensor on your Vumbua Kit is specially configured for ease of use:

Connection Details
  • Sensor: HC-SR04 Ultrasonic Module
  • Trigger Pin: D6 (Digital Pin 6)
  • Echo Pin: D5 (Digital Pin 5)
  • Voltage: 5V regulated
  • Current: 15mA max
  • Position: Front-facing for easy testing
Technical Specifications
  • Max Range: 400cm (4 meters)
  • Min Range: 2cm (0.02 meters)
  • Accuracy: ±3mm (close range)
  • Beam Angle: 15 degrees
  • Update Rate: 20Hz (50ms interval)
  • Temperature Compensation: Software-based
Optimized for Education

The Vumbua Kit's ultrasonic sensor is positioned and configured for optimal learning experience:

  1. Front-facing placement for easy object testing
  2. Pre-wired connections eliminate wiring errors
  3. Optimal pin selection (D5 & D6) for reliable operation
  4. Stable 5V power supply for consistent readings
  5. Clear line of sight for accurate measurements

Basic Distance Measurement

Let's start with a simple program to measure and display distance:

ultrasonic_basic.ino
/*
  Vumbua Synapse Kit - Lesson 10: Basic Ultrasonic Distance Measurement
  HC-SR04 Connections on Vumbua:
    TRIG (Trigger) = D6
    ECHO (Echo)    = D5
*/

// Define pin connections for Vumbua Synapse Kit
const int trigPin = 6;    // Trigger pin connected to D6
const int echoPin = 5;    // Echo pin connected to D5

void setup() {
  // Initialize Serial communication for debugging
  Serial.begin(9600);
  
  // Initialize ultrasonic sensor pins
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  
  Serial.println("Ultrasonic Distance Measurement");
  Serial.println("Vumbua Synapse Kit - Lesson 10");
  Serial.println("==============================");
  Serial.println();
}

void loop() {
  // Clear the trigPin condition
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  // Send 10μs pulse to trigger pin
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Read echo pin, returns the sound wave travel time in microseconds
  long duration = pulseIn(echoPin, HIGH);
  
  // Calculate the distance
  // Speed of sound = 343 m/s = 0.0343 cm/μs
  // Distance = (Time × Speed) / 2 (round trip)
  float distance = duration * 0.0343 / 2;
  
  // Display the distance on Serial Monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  // Wait 100ms between measurements
  // HC-SR04 needs at least 60ms between measurements
  delay(100);
}

Testing the Program

1. Upload the Code

Upload to your Vumbua Synapse Kit. The ultrasonic sensor is already connected to pins D5 (Echo) and D6 (Trigger).

2. Open Serial Monitor

Go to Tools → Serial Monitor or press Ctrl+Shift+M. Set the baud rate to 9600.

3. Test Different Distances

Place objects at various distances from the sensor:

  • Close range (2-20cm): High accuracy (±3mm)
  • Medium range (20-100cm): Good accuracy (±1cm)
  • Long range (100-400cm): Reduced accuracy (±3cm)
  • Beyond 400cm: May not detect or show incorrect values
4. Test Different Materials

Ultrasonic sensors work best with solid, flat surfaces. Try:

  • Good: Wood, metal, plastic, glass
  • Fair: Fabric, foam, rough surfaces
  • Poor: Soft, absorbent materials
  • Angled surfaces: May reflect away from sensor

Enhanced Serial Monitor Display

Let's create a more informative display with better formatting:

ultrasonic_advanced.ino
/*
  Vumbua Synapse Kit - Enhanced Ultrasonic Display
  Shows distance in multiple units and visual representation
*/

const int trigPin = 6;
const int echoPin = 5;

// Variables for filtering and smoothing
const int numReadings = 5;
float readings[numReadings];
int readIndex = 0;
float total = 0;
float average = 0;

void setup() {
  Serial.begin(115200);  // Higher baud rate for faster updates
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  
  // Initialize all readings to 0
  for (int i = 0; i < numReadings; i++) {
    readings[i] = 0;
  }
  
  Serial.println("==================================================");
  Serial.println("VUMBUA SYNAPSE KIT - ULTRASONIC DISTANCE METER");
  Serial.println("==================================================");
  Serial.println("Object Distance    |   Range Status   |   Visual");
  Serial.println("--------------------------------------------------");
}

void loop() {
  float distance = getDistance();
  
  // Apply moving average filter
  total = total - readings[readIndex];
  readings[readIndex] = distance;
  total = total + readings[readIndex];
  readIndex = readIndex + 1;
  
  if (readIndex >= numReadings) {
    readIndex = 0;
  }
  
  average = total / numReadings;
  
  // Display results
  displayDistance(average);
  
  delay(100);  // Update every 100ms
}

float getDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH);
  float distance = duration * 0.0343 / 2;
  
  // Validate reading
  if (distance > 400 || distance < 2) {
    distance = 0;  // Out of range
  }
  
  return distance;
}

void displayDistance(float distance) {
  // Convert to different units
  float inches = distance / 2.54;
  float meters = distance / 100;
  
  // Determine range status
  String status;
  if (distance == 0) {
    status = "OUT OF RANGE ";
  } else if (distance < 20) {
    status = "VERY CLOSE   ";
  } else if (distance < 50) {
    status = "CLOSE        ";
  } else if (distance < 150) {
    status = "MEDIUM       ";
  } else {
    status = "FAR          ";
  }
  
  // Create visual representation
  String visual = "";
  int bars = map(constrain(distance, 0, 400), 0, 400, 0, 20);
  
  for (int i = 0; i < 20; i++) {
    if (i < bars) {
      visual += "█";
    } else {
      visual += "░";
    }
  }
  
  // Display formatted output
  Serial.print(" ");
  if (distance < 100) Serial.print(" ");
  if (distance < 10) Serial.print(" ");
  Serial.print(distance);
  Serial.print(" cm (");
  Serial.print(inches, 1);
  Serial.print(" in, ");
  Serial.print(meters, 2);
  Serial.print(" m)");
  Serial.print("  |  ");
  Serial.print(status);
  Serial.print("  |  ");
  Serial.print(visual);
  Serial.println();
}

Expected Serial Monitor Output

Serial Monitor Output
==================================================
VUMBUA SYNAPSE KIT - ULTRASONIC DISTANCE METER
==================================================
Object Distance    |   Range Status   |   Visual
--------------------------------------------------
   15.3 cm (6.0 in, 0.15 m)  |  VERY CLOSE    |  ███░░░░░░░░░░░░░░░░░
   87.5 cm (34.4 in, 0.88 m)  |  CLOSE        |  ██████████░░░░░░░░░░
  234.8 cm (92.4 in, 2.35 m)  |  MEDIUM       |  ███████████████░░░░░
    0.0 cm (0.0 in, 0.00 m)  |  OUT OF RANGE |  ░░░░░░░░░░░░░░░░░░░░

Improving Accuracy and Reliability

Several factors affect ultrasonic sensor accuracy. Here's how to improve it:

Factor Effect on Accuracy Solution
Temperature Speed of sound changes with temperature (0.6m/s per °C) Add temperature compensation in code
Angle of Object Angled surfaces reflect waves away from sensor Use flat, perpendicular surfaces for testing
Material Soft materials absorb sound waves Use hard, reflective surfaces
Multiple Echoes Waves can bounce multiple times Use timeouts and validate readings
Electrical Noise Can interfere with echo detection Add capacitors and proper grounding

Temperature-Compensated Distance Calculation

temperature_compensation.ino
/*
  Temperature-compensated ultrasonic distance measurement
  More accurate calculation considering air temperature
*/

const int trigPin = 6;
const int echoPin = 5;

// Simulated temperature in Celsius (use DHT20 from Lesson 6 for real temp)
float temperature = 25.0;  // Default 25°C

void setup() {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  // Calculate speed of sound based on temperature
  // Formula: v = 331.3 + 0.606 * T (m/s)
  float speedOfSound = 331.3 + (0.606 * temperature);
  
  // Convert to cm/μs for calculation
  float speedCmPerMicrosecond = (speedOfSound * 100) / 1000000;
  
  // Get raw duration
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH);
  
  // Calculate distance with temperature compensation
  float distance = duration * speedCmPerMicrosecond / 2;
  
  // Display results
  Serial.print("Temp: ");
  Serial.print(temperature);
  Serial.print("°C | Speed of Sound: ");
  Serial.print(speedOfSound);
  Serial.print(" m/s | Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  // Simulate temperature change for demonstration
  temperature = 20.0 + (sin(millis() / 10000.0) * 10.0);
  
  delay(500);
}
Pro Tip: Combine with DHT20

For maximum accuracy, combine the ultrasonic sensor with the DHT20 temperature sensor from Lesson 6. Use real-time temperature readings to dynamically adjust the speed of sound in your calculations.

This can improve accuracy by up to 5% in environments with temperature variations.

Obstacle Detection System

Create a practical obstacle detection system with visual and audio alerts:

obstacle_detection.ino
/*
  Vumbua Synapse Kit - Obstacle Detection System
  Uses ultrasonic sensor and LED/buzzer for alerts
*/

const int trigPin = 6;
const int echoPin = 5;
const int redLed = 9;
const int yellowLed = 10;
const int greenLed = 11;
const int buzzer = 3;

// Alert thresholds (in cm)
const int warningDistance = 50;
const int criticalDistance = 20;

void setup() {
  Serial.begin(9600);
  
  // Initialize pins
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(redLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(buzzer, OUTPUT);
  
  Serial.println("Obstacle Detection System Active");
  Serial.println("================================");
}

void loop() {
  float distance = measureDistance();
  
  // Determine alert level and control outputs
  if (distance > warningDistance || distance == 0) {
    // Safe zone: Green LED on, others off, no buzzer
    digitalWrite(greenLed, HIGH);
    digitalWrite(yellowLed, LOW);
    digitalWrite(redLed, LOW);
    noTone(buzzer);
    Serial.println("Status: SAFE          ");
    
  } else if (distance > criticalDistance && distance <= warningDistance) {
    // Warning zone: Yellow LED blinking, slow beeps
    digitalWrite(greenLed, LOW);
    digitalWrite(yellowLed, millis() / 500 % 2);
    digitalWrite(redLed, LOW);
    tone(buzzer, 1000, 100);
    Serial.print("Status: WARNING (");
    Serial.print(distance);
    Serial.println(" cm)");
    
  } else if (distance <= criticalDistance) {
    // Critical zone: Red LED blinking fast, fast beeps
    digitalWrite(greenLed, LOW);
    digitalWrite(yellowLed, LOW);
    digitalWrite(redLed, millis() / 200 % 2);
    tone(buzzer, 2000, 50);
    Serial.print("Status: CRITICAL (");
    Serial.print(distance);
    Serial.println(" cm) - OBSTACLE TOO CLOSE!");
  }
  
  delay(100);
}

float measureDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH);
  float distance = duration * 0.0343 / 2;
  
  // Validate reading
  if (distance > 400 || distance < 2) {
    distance = 0;
  }
  
  return distance;
}

System Operation

Distance Range LED Status Buzzer Alert Serial Output
> 50cm or Out of Range Green LED ON No sound Status: SAFE
20-50cm Yellow LED Blinking (0.5Hz) Slow beeps (1Hz, 1000Hz) Status: WARNING (XX cm)
< 20cm Red LED Blinking (2.5Hz) Fast beeps (5Hz, 2000Hz) Status: CRITICAL (XX cm)

Parking Sensor System

Create a complete parking assistance system with distance-based feedback:

parking_sensor.ino
/*
  Vumbua Synapse Kit - Parking Sensor System
  Simulates car parking sensor with distance-based feedback
*/

const int trigPin = 6;
const int echoPin = 5;
const int buzzer = 3;
const int leds[] = {9, 10, 11, 12, 13};
const int numLeds = 5;

// Parking distance thresholds (cm)
const int maxDistance = 200;
const int minDistance = 10;

void setup() {
  Serial.begin(9600);
  
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(buzzer, OUTPUT);
  
  for (int i = 0; i < numLeds; i++) {
    pinMode(leds[i], OUTPUT);
  }
  
  Serial.println("Parking Sensor System Active");
  Serial.println("Move object closer to sensor to simulate parking...");
}

void loop() {
  float distance = measureDistance();
  
  // Constrain distance to parking range
  distance = constrain(distance, minDistance, maxDistance);
  
  // Calculate which LEDs to light based on distance
  int ledsToLight = map(distance, maxDistance, minDistance, 0, numLeds);
  
  // Update LED display
  for (int i = 0; i < numLeds; i++) {
    if (i < ledsToLight) {
      digitalWrite(leds[i], HIGH);
    } else {
      digitalWrite(leds[i], LOW);
    }
  }
  
  // Control buzzer based on distance
  if (distance <= minDistance) {
    // Continuous tone when too close
    tone(buzzer, 2000);
  } else {
    // Beep frequency increases as distance decreases
    int beepDelay = map(distance, minDistance, maxDistance, 100, 1000);
    int beepDuration = map(distance, minDistance, maxDistance, 50, 200);
    
    if (millis() % (beepDelay * 2) < beepDuration) {
      tone(buzzer, 1000 + (1000 - distance));
    } else {
      noTone(buzzer);
    }
  }
  
  // Display parking status
  displayParkingStatus(distance, ledsToLight);
  
  delay(50);
}

float measureDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH, 30000); // Timeout for 30ms
  
  if (duration == 0) {
    return maxDistance + 100; // No object detected
  }
  
  float distance = duration * 0.0343 / 2;
  return distance;
}

void displayParkingStatus(float distance, int ledsLit) {
  Serial.print("Distance: ");
  if (distance > maxDistance) {
    Serial.print(">200");
  } else {
    Serial.print(distance);
  }
  Serial.print(" cm | LEDs: ");
  
  for (int i = 0; i < numLeds; i++) {
    if (i < ledsLit) {
      Serial.print("█");
    } else {
      Serial.print("░");
    }
  }
  
  Serial.print(" | Status: ");
  
  if (distance > maxDistance) {
    Serial.println("NO OBJECT      ");
  } else if (distance > 100) {
    Serial.println("SAFE           ");
  } else if (distance > 50) {
    Serial.println("APPROACHING    ");
  } else if (distance > 20) {
    Serial.println("CLOSE          ");
  } else {
    Serial.println("TOO CLOSE! STOP");
  }
}

Simple Radar System

Combine ultrasonic sensor with servo motor to create a scanning radar system:

simple_radar.ino
/*
  Vumbua Synapse Kit - Simple Radar System
  Uses servo motor to scan area and ultrasonic sensor to detect objects
  Displays results on Serial Monitor as radar screen
*/

#include <Servo.h>

const int trigPin = 6;
const int echoPin = 5;
const int servoPin = 9;

Servo radarServo;
int currentAngle = 0;
int sweepDirection = 1; // 1 for increasing, -1 for decreasing
const int minAngle = 15;
const int maxAngle = 165;
const int angleStep = 1;

void setup() {
  Serial.begin(115200);
  
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  
  radarServo.attach(servoPin);
  radarServo.write(currentAngle);
  
  delay(1000);
  
  Serial.println("Simple Radar System - Vumbua Synapse Kit");
  Serial.println("==========================================");
  Serial.println("Angle | Distance | Radar Display");
  Serial.println("------|----------|----------------------------");
}

void loop() {
  // Move servo to next position
  currentAngle += (angleStep * sweepDirection);
  
  if (currentAngle >= maxAngle || currentAngle <= minAngle) {
    sweepDirection *= -1; // Reverse direction
    currentAngle = constrain(currentAngle, minAngle, maxAngle);
  }
  
  radarServo.write(currentAngle);
  delay(15); // Give servo time to move
  
  // Measure distance at current angle
  float distance = measureDistance();
  
  // Display radar screen
  displayRadar(currentAngle, distance);
}

float measureDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH, 30000);
  
  if (duration == 0) {
    return 400; // No echo detected
  }
  
  float distance = duration * 0.0343 / 2;
  return constrain(distance, 2, 400);
}

void displayRadar(int angle, float distance) {
  // Display angle
  Serial.print(" ");
  if (angle < 100) Serial.print(" ");
  if (angle < 10) Serial.print(" ");
  Serial.print(angle);
  Serial.print("° | ");
  
  // Display distance
  if (distance >= 400) {
    Serial.print(" No Object ");
  } else {
    Serial.print(" ");
    if (distance < 100) Serial.print(" ");
    if (distance < 10) Serial.print(" ");
    Serial.print(distance, 1);
    Serial.print(" cm ");
  }
  Serial.print(" | ");
  
  // Create radar visualization
  int totalSpaces = 60;
  int centerPos = map(angle, minAngle, maxAngle, 0, totalSpaces);
  int objectPos = 0;
  
  if (distance < 400) {
    objectPos = map(constrain(distance, 0, 200), 0, 200, totalSpaces/2, 0);
  }
  
  for (int i = 0; i <= totalSpaces; i++) {
    if (i == centerPos) {
      Serial.print("|"); // Current angle position
    } else if (distance < 400 && i == objectPos) {
      Serial.print("*"); // Detected object
    } else if (i == totalSpaces/2) {
      Serial.print("+"); // Center (sensor position)
    } else {
      Serial.print(".");
    }
  }
  
  Serial.println();
}
Radar System Operation

This system creates a 150° scanning radar (15° to 165°). The servo sweeps back and forth while the ultrasonic sensor takes distance measurements at each angle.

The Serial Monitor displays a radar screen showing:

  • + = Sensor position (center)
  • | = Current scanning direction
  • * = Detected object
  • . = Empty space

Advanced Applications

Here are some real-world applications of ultrasonic sensors:

Autonomous Robot Navigation

Use multiple ultrasonic sensors for obstacle avoidance and mapping.

Robotics
Smart Parking Systems

Detect available parking spaces and guide vehicles.

Smart Cities
Industrial Level Monitoring

Measure liquid levels in tanks without contact.

Industry 4.0
Assistive Technology

Smart canes for visually impaired with obstacle detection.

Healthcare

Multi-Sensor Array

For more complex applications, consider using multiple ultrasonic sensors:

multi_sensor_array.ino
/*
  Concept: Multi-sensor ultrasonic array
  For applications requiring wider coverage or 3D sensing
*/

// Multiple sensor configurations
struct UltrasonicSensor {
  int trigPin;
  int echoPin;
  float angle;  // Mounting angle relative to forward direction
  float offset; // Position offset from center
};

// Create sensor array (conceptual)
UltrasonicSensor sensors[4] = {
  {6, 5, 0, 0},    // Center forward
  {7, 8, 30, 10},   // Right front
  {9, 10, -30, -10},  // Left front
  {11, 12, 0, 0}     // Rear
};

void setup() {
  // Initialize all sensors
  for (int i = 0; i < 4; i++) {
    pinMode(sensors[i].trigPin, OUTPUT);
    pinMode(sensors[i].echoPin, INPUT);
  }
  Serial.begin(9600);
}

void loop() {
  // Read all sensors
  float distances[4];
  for (int i = 0; i < 4; i++) {
    distances[i] = measureDistance(sensors[i].trigPin, sensors[i].echoPin);
  }
  
  // Process data for navigation decisions
  makeNavigationDecision(distances);
  
  delay(100);
}

float measureDistance(int trigPin, int echoPin) {
  // Standard distance measurement code
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH);
  float distance = duration * 0.0343 / 2;
  
  return distance;
}

void makeNavigationDecision(float distances[4]) {
  // Simple obstacle avoidance logic
  if (distances[0] < 30) {  // Obstacle directly ahead
    if (distances[1] > distances[2]) {
      Serial.println("Turn RIGHT - Clearer path on right");
    } else {
      Serial.println("Turn LEFT - Clearer path on left");
    }
  } else {
    Serial.println("Move FORWARD - Path clear ahead");
  }
}

Troubleshooting Common Issues

Possible Causes:
  • Incorrect pin connections: Verify D5 (Echo) and D6 (Trigger)
  • Power issues: Ensure 5V and GND are properly connected
  • Object too close/far: HC-SR04 range is 2cm-400cm
  • No object in range: Sensor returns 0 for no detection
  • Sensor damage: Check for physical damage
Solutions:
  1. Use Serial.println(duration); to check raw pulseIn value
  2. Test with a flat, solid object at 20cm distance
  3. Verify Vumbua Kit connections are secure
  4. Check Serial Monitor baud rate matches code (9600)

Possible Causes:
  • Electrical noise: From motors or other components
  • Multiple echoes: Sound bouncing off multiple surfaces
  • Object material: Soft materials absorb sound
  • Angled surfaces: Reflecting sound away from sensor
  • Temperature fluctuations: Affects speed of sound
Solutions:
  1. Implement software filtering (moving average)
  2. Add delay(60) between readings (HC-SR04 needs 60ms)
  3. Use flat, hard surfaces perpendicular to sensor
  4. Add timeout to pulseIn(): pulseIn(echoPin, HIGH, 30000)
  5. Keep sensor away from motors and power supplies

Vumbua Kit Specific Issues:
  • Pin conflicts: D5 and D6 are dedicated to ultrasonic
  • Power sharing: All sensors share 5V rail
  • Timing conflicts: Other sensors interrupting pulseIn
  • Physical obstruction: Other components blocking sensor
Solutions:
  1. Don't use D5/D6 for other purposes when using ultrasonic
  2. Add noInterrupts() during critical timing sections
  3. Ensure clear line of sight for sensor
  4. Stagger sensor readings if using multiple sensors
  5. Use dedicated power supply for high-current applications
Diagnostic Test Program
void testUltrasonic() {
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH, 30000);
  
  Serial.print("Duration: ");
  Serial.print(duration);
  Serial.print("μs | ");
  
  if (duration == 0) {
    Serial.println("NO ECHO - Check connections");
  } else if (duration > 25000) {
    Serial.println("TIMEOUT - No object detected");
  } else {
    float distance = duration * 0.0343 / 2;
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
  }
}

Video Demonstration

Ultrasonic Sensor Tutorial Coming Soon!

Watch our detailed video walkthrough for building advanced projects.

Subscribe to our YouTube channel to be notified when it's available.

Subscribe to OLSPACE

What's Next?

Congratulations! You've successfully mastered ultrasonic distance sensing. Here's what you've accomplished:

  • ✓ Understood ultrasonic sensor operation and SONAR principle
  • ✓ Properly used HC-SR04 with ATmega328P on pins D5/D6
  • ✓ Mastered pulseIn() for precise timing measurements
  • ✓ Created obstacle detection systems with multi-level alerts
  • ✓ Built a parking sensor with visual/audio feedback
  • ✓ Developed a scanning radar system with servo motor
  • ✓ Implemented temperature compensation for accuracy
  • ✓ Learned troubleshooting techniques for reliable operation

In the next lesson, you'll explore infrared sensing:

Lesson 11: Infrared (IR) Sensor

Discover infrared sensing technology for object detection, line following robots, and remote control systems. Learn to use IR sensors for proximity detection and create projects that respond to invisible light.

Resources & Downloads