Project 8 : Ultrasonic Radar using Servo and ESP32

ESP32 Radar Project - Complete Beginner Tutorial

Overview

This project creates a radar system using an ESP32 microcontroller, ultrasonic sensor, servo motor, and a visual display on your computer. The radar sweeps in a 180-degree arc, detecting objects and displaying them on a colorful radar screen - just like in movies!

What You'll Learn

  • How to use ultrasonic sensors for distance measurement
  • Servo motor control with ESP32
  • Serial communication between ESP32 and computer
  • Visual programming with Processing IDE
  • Real-time data visualization

Components Needed

Hardware:

  • ESP32 Development Board - The brain of the project
  • HC-SR04 Ultrasonic Sensor - For distance measurement (like a bat's echolocation!)
  • SG90 Servo Motor - To rotate the sensor
  • Breadboard - For connecting components
  • Jumper Wires - Male-to-male and male-to-female
  • USB Cable - To connect ESP32 to computer
  • Power Supply - 5V (optional, USB can power everything)

Software:

  • Arduino IDE - To program the ESP32
  • Processing IDE - To create the radar display
  • ESP32 Board Package - For Arduino IDE

Part 1: Hardware Setup

Step 1: Wiring Connections

Ultrasonic Sensor (HC-SR04) to ESP32:

HC-SR04    →    ESP32
VCC        →    3.3V
GND        →    GND
TRIGGER    →    GPIO 5
ECHO       →    GPIO 18

Servo Motor to ESP32:

Servo      →    ESP32
Red Wire   →    5V
Brown Wire →    GND
Orange Wire→    GPIO 13

Step 2: Physical Assembly

  1. Mount the ultrasonic sensor on the servo horn (the plastic piece that comes with servo)
  2. Secure with hot glue or double-sided tape
  3. Connect all wires according to the wiring diagram above
  4. Place on breadboard for stability

Wiring Diagram Description:


Part 2: Software Setup

Step 1: Install Arduino IDE

Step 2: Install Processing IDE

  1. Download from processing.org
  2. Install and run it once to set up

Step 3: Install Required Libraries

In Arduino IDE:

  • Go to Tools → Manage Libraries
  • Search and install: "ESP32Servo"

Part 3: Programming the ESP32

Step 1: Understanding the ESP32 Code

The ESP32 code does three main things:

  1. Controls the servo - Makes it sweep back and forth
  2. Reads the ultrasonic sensor - Measures distances
  3. Sends data to computer - Via serial communication

Step 2: Upload the ESP32 Code

Arduino Ide Code : 

-------------------------------------------------------------------------------

#include <ESP32Servo.h>

// Pin definitions
#define TRIGGER_PIN 5  // GPIO pin connected to ultrasonic trigger
#define ECHO_PIN 18    // GPIO pin connected to ultrasonic echo
#define SERVO_PIN 13   // GPIO pin connected to servo signal

// Constants
#define SERVO_DELAY 50      // Delay between servo movements (ms)
#define SCAN_ANGLE_MIN 15   // Minimum sweep angle
#define SCAN_ANGLE_MAX 165  // Maximum sweep angle
#define SCAN_STEP 1         // Degrees to move each step
#define MAX_DISTANCE 200    // Maximum distance to measure (cm)

Servo radarServo;
int currentAngle = SCAN_ANGLE_MIN;
bool scanningForward = true;
unsigned long lastMeasurement = 0;
const unsigned long measurementInterval = 100; // ms between measurements

void setup() {
  // Initialize serial communication
  Serial.begin(115200);
  
  // Configure ultrasonic sensor pins
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  
  // ESP32 specific - allow allocation of timers
  ESP32PWM::allocateTimer(0);
  ESP32PWM::allocateTimer(1);
  ESP32PWM::allocateTimer(2);
  ESP32PWM::allocateTimer(3);
  
  // Initialize servo with ESP32 servo settings
  radarServo.setPeriodHertz(50);    // Standard 50hz servo
  radarServo.attach(SERVO_PIN, 500, 2400); // Default min/max pulse width values
  radarServo.write(SCAN_ANGLE_MIN);
  
  delay(2000); // Give time for the servo to reach starting position
  
  Serial.println("ESP32 Radar Starting...");
}

void loop() {
  // Move the servo
  radarServo.write(currentAngle);
  delay(SERVO_DELAY);
  
  // Measure distance at appropriate intervals
  unsigned long currentTime = millis();
  if (currentTime - lastMeasurement >= measurementInterval) {
    lastMeasurement = currentTime;
    
    // Measure distance
    int distance = measureDistance();
    
    // Send data to Processing in format: angle,distance
    Serial.print(currentAngle);
    Serial.print(",");
    Serial.println(distance);
  }
  
  // Update angle for next measurement
  if (scanningForward) {
    currentAngle += SCAN_STEP;
    if (currentAngle >= SCAN_ANGLE_MAX) {
      scanningForward = false;
    }
  } else {
    currentAngle -= SCAN_STEP;
    if (currentAngle <= SCAN_ANGLE_MIN) {
      scanningForward = true;
    }
  }
}

int measureDistance() {
  // Clear the trigger pin
  digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  
  // Set the trigger pin high for 10 microseconds
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  
  // Read the echo pin, return pulse duration in microseconds
  long duration = pulseIn(ECHO_PIN, HIGH, 30000); // Timeout after 30ms
  
  // Calculate the distance
  int distance = duration * 0.034 / 2; // Speed of sound wave divided by 2
  
  // Constrain the distance to maximum range
  if (distance > MAX_DISTANCE || distance <= 0) {
    distance = MAX_DISTANCE;
  }
  
  return distance;
}


----------------------------------------------------------------------------------

Processing Code:

----------------------------------------------------------------------------------

import processing.serial.*;

Serial myPort;        // Serial port object
String serialData;    // Data received from serial port
boolean connected = false;
int dataCount = 0;    // Count received data points for debugging

// Display configuration - made larger for kids
int displaySize = 900;
int radarRadius = 400;  // Bigger radar for better visibility
int centerX, centerY;

// Radar settings - optimized for short range
int maxDistance = 100;  // Reduced to 100cm (1 meter) for short range
float currentAngle = 15;
float previousAngle = currentAngle;
boolean scanningForward = true;
float[] distances = new float[181];
int[] objectAge = new int[181];  // Track how long objects have been detected

// Servo timing simulation
int servoDelay = 50;
int scanStep = 1;
int scanAngleMin = 15;
int scanAngleMax = 165;
long lastMoveTime = 0;

// Enhanced visual settings for kids
color backgroundColor = color(5, 15, 25);
color gridColor = color(0, 80, 120);
color sweepColor = color(100, 255, 100);
color objectColor = color(255, 80, 80);
color textColor = color(200, 255, 200);
color warningColor = color(255, 255, 0);
color dangerColor = color(255, 50, 50);

// Kid-friendly features
boolean showDebug = false;  // Start with debug off for kids
StringList debugLog = new StringList();
int maxLogLines = 5;
boolean forceTestObject = false;
boolean playWarningSound = true;
int warningDistance = 30;  // Objects closer than 30cm show warning

// Distance zones for kids
int[] distanceZones = {20, 40, 60, 80, 100};
String[] zoneLabels = {"VERY CLOSE!", "Close", "Medium", "Far", "Very Far"};
color[] zoneColors = {
  color(255, 0, 0),    // Red - Very close
  color(255, 100, 0),  // Orange - Close
  color(255, 255, 0),  // Yellow - Medium
  color(0, 255, 0),    // Green - Far
  color(0, 150, 255)   // Blue - Very far
};

// IMPORTANT: Change this to match your ESP32's port
String ESP32_PORT = ""; // Leave blank to force manual selection

void setup() {
  size(900, 900);
  centerX = width / 2;
  centerY = height / 2;
  smooth();
  
  // Initialize arrays
  for (int i = 0; i < distances.length; i++) {
    distances[i] = 0;
    objectAge[i] = 0;
  }
  
  // List available serial ports
  println("Available serial ports:");
  String[] portList = Serial.list();
  for (int i = 0; i < portList.length; i++) {
    println(i + ": " + portList[i]);
  }
  
  addDebugMessage("Available ports: " + portList.length);
  
  if (ESP32_PORT.isEmpty()) {
    println("Press 0-9 keys to select a serial port");
    addDebugMessage("Press 0-9 to select a serial port");
  } else {
    connectToPort(ESP32_PORT);
  }
}

void addDebugMessage(String message) {
  println(message);
  debugLog.append(message);
  if (debugLog.size() > maxLogLines) {
    debugLog.remove(0);
  }
}

void connectToPort(String portName) {
  try {
    if (myPort != null) {
      myPort.stop();
    }
    
    println("Connecting to: " + portName);
    addDebugMessage("Connecting to: " + portName);
    
    myPort = new Serial(this, portName, 115200);
    myPort.bufferUntil('\n');
    
    connected = true;
    println("Connected successfully!");
    addDebugMessage("Connected successfully!");
    dataCount = 0;
  } catch (Exception e) {
    println("Failed to connect to: " + portName);
    addDebugMessage("Failed: " + portName);
    connected = false;
  }
}

void draw() {
  background(backgroundColor);
  
  // Age objects (fade old detections)
  for (int i = 0; i < objectAge.length; i++) {
    if (objectAge[i] > 0) {
      objectAge[i]--;
      if (objectAge[i] == 0) {
        distances[i] = 0;  // Clear old detections
      }
    }
  }
  
  // Draw title for kids
  fill(textColor);
  textSize(28);
  textAlign(CENTER);
  text("RADAR DETECTOR", width/2, 40);
  textAlign(LEFT);
  
  // Draw connection status
  if (!connected) {
    fill(dangerColor);
    textSize(20);
    textAlign(CENTER);
    text("NOT CONNECTED - PRESS 0-9 TO SELECT PORT", width/2, 80);
    textAlign(LEFT);
    
    // Simulate movement when not connected
    if (millis() - lastMoveTime >= servoDelay) {
      updateServoPosition();
      lastMoveTime = millis();
    }
    
    // Add test objects for demonstration
    if (forceTestObject) {
      distances[90] = 50;  // Test object at 90 degrees, 50cm
      distances[60] = 25;  // Another test object
      objectAge[90] = 30;
      objectAge[60] = 30;
    }
  } else {
    fill(color(0, 255, 0));
    textSize(18);
    textAlign(CENTER);
    text("CONNECTED ✓ - Objects detected: " + countObjects(), width/2, 80);
    textAlign(LEFT);
  }
  
  // Draw the enhanced radar
  drawRadarGrid();
  drawSweepLine();
  drawDetectedObjects();
  drawInfoPanel();
  
  // Draw warning if objects are too close
  drawWarnings();
  
  // Draw debug panel if enabled
  if (showDebug) {
    drawDebugPanel();
  }
}

void updateServoPosition() {
  if (scanningForward) {
    currentAngle += scanStep;
    if (currentAngle >= scanAngleMax) {
      scanningForward = false;
    }
  } else {
    currentAngle -= scanStep;
    if (currentAngle <= scanAngleMin) {
      scanningForward = true;
    }
  }
}

void drawRadarGrid() {
  // Draw colorful distance zones
  noFill();
  strokeWeight(2);
  
  // Draw zone circles with colors
  for (int i = 0; i < distanceZones.length; i++) {
    float radius = map(distanceZones[i], 0, maxDistance, 0, radarRadius);
    stroke(zoneColors[i], 100);
    arc(centerX, centerY, radius * 2, radius * 2, PI, TWO_PI);
    
    // Draw zone labels
    fill(zoneColors[i]);
    textSize(14);
    text(zoneLabels[i] + " (" + distanceZones[i] + "cm)", 
         centerX + radius + 10, centerY - 5);
  }
  
  // Draw angle lines
  stroke(gridColor);
  strokeWeight(1);
  for (int angle = 0; angle <= 180; angle += 30) {
    float rad = radians(angle);
    float x = centerX + radarRadius * cos(rad);
    float y = centerY - radarRadius * sin(rad);
    line(centerX, centerY, x, y);
    
    // Draw bigger angle labels
    fill(textColor);
    textSize(16);
    float labelX = x + 20 * cos(rad);
    float labelY = y - 20 * sin(rad);
    text(angle + "°", labelX, labelY);
  }
  
  // Draw the radar base (bigger)
  fill(gridColor);
  stroke(gridColor);
  strokeWeight(2);
  arc(centerX, centerY, 80, 80, PI, TWO_PI);
  
  // Add "RADAR" text in the base
  fill(textColor);
  textSize(12);
  textAlign(CENTER);
  text("RADAR", centerX, centerY - 5);
  textAlign(LEFT);
}

void drawSweepLine() {
  // Draw animated sweep line
  stroke(sweepColor);
  strokeWeight(3);
  
  // Convert angle correctly for display
  float displayAngle = currentAngle; // 0 is up, 90 is right, 180 is down
  float rad = radians(displayAngle);
  float x = centerX + radarRadius * cos(rad);
  float y = centerY - radarRadius * sin(rad);
  
  line(centerX, centerY, x, y);
  
  // Draw glowing effect at the end
  noStroke();
  fill(sweepColor, 200);
  ellipse(x, y, 12, 12);
  fill(sweepColor, 100);
  ellipse(x, y, 20, 20);
  
  // Draw trail effect
  for (int i = 1; i <= 10; i++) {
    float trailAngle = scanningForward ? 
                      displayAngle - i * 2 : 
                      displayAngle + i * 2;
    
    if (trailAngle >= 0 && trailAngle <= 180) {
      float trailRad = radians(trailAngle);
      float trailX = centerX + radarRadius * cos(trailRad);
      float trailY = centerY - radarRadius * sin(trailRad);
      
      float alpha = map(i, 1, 10, 100, 10);
      stroke(sweepColor, alpha);
      strokeWeight(2);
      line(centerX, centerY, trailX, trailY);
    }
  }
}

void drawDetectedObjects() {
  noStroke();
  
  for (int angle = 0; angle <= 180; angle++) {
    if (distances[angle] > 0 && distances[angle] <= maxDistance) {
      float distance = distances[angle];
      
      // Calculate screen position
      float displayAngle = angle;
      float rad = radians(displayAngle);
      
      // Improved distance mapping - linear and accurate
      float screenDistance = map(distance, 0, maxDistance, 0, radarRadius);
      float x = centerX + screenDistance * cos(rad);
      float y = centerY - screenDistance * sin(rad);
      
      // Determine object color based on distance
      color objColor = getObjectColor(distance);
      
      // Draw object with size based on age (newer = bigger)
      float objSize = map(objectAge[angle], 0, 30, 8, 20);
      
      // Draw glow effect
      fill(objColor, 50);
      ellipse(x, y, objSize * 2, objSize * 2);
      
      // Draw main object
      fill(objColor);
      ellipse(x, y, objSize, objSize);
      
      // Draw distance label for close objects
      if (distance <= 50) {
        fill(255);
        textSize(10);
        textAlign(CENTER);
        text(int(distance) + "cm", x, y - objSize/2 - 5);
        textAlign(LEFT);
      }
    }
  }
}

color getObjectColor(float distance) {
  // Return color based on distance zones
  for (int i = 0; i < distanceZones.length; i++) {
    if (distance <= distanceZones[i]) {
      return zoneColors[i];
    }
  }
  return zoneColors[zoneColors.length - 1];
}

void drawInfoPanel() {
  // Overlay panel on lower part of radar
  int panelWidth = 400;
  int panelHeight = 100;
  int panelX = centerX - panelWidth / 2;
  int panelY = centerY + radarRadius - panelHeight - 20 - 200;
  // Draw main info panel
  fill(0, 100);
  stroke(gridColor);
  strokeWeight(2);
  rect(panelX, panelY, panelWidth, panelHeight, 15);
  
  // Current angle and direction
  fill(textColor);
  textSize(18);
  text("Scanning: " + int(currentAngle) + "° " + 
       (scanningForward ? "→" : "←"), panelX + 20, panelY + 30);
  
  // Current distance reading
  int angleIndex = int(currentAngle);
  if (angleIndex >= 0 && angleIndex < distances.length && distances[angleIndex] > 0) {
    float currentDistance = distances[angleIndex];
    fill(getObjectColor(currentDistance));
    text("Distance: " + int(currentDistance) + "cm", panelX + 20, panelY + 55);
    
    // Status message
    String status = getDistanceStatus(currentDistance);
    text("Status: " + status, panelX + 20, panelY + 80);
  } else {
    fill(textColor);
    text("Distance: No object detected", panelX + 20, panelY + 55);
    text("Status: Clear", panelX + 20, panelY + 80);
  }
  
  // Object counter
  fill(textColor);
  textSize(16);
  text("Objects in range: " + countObjects(), panelX + 230, panelY + 30);
}

String getDistanceStatus(float distance) {
  if (distance <= 20) return "VERY CLOSE!";
  if (distance <= 40) return "Close";
  if (distance <= 60) return "Medium distance";
  if (distance <= 80) return "Far";
  return "Very far";
}

void drawWarnings() {
  // Check for very close objects
  boolean hasCloseObjects = false;
  for (int i = 0; i < distances.length; i++) {
    if (distances[i] > 0 && distances[i] <= warningDistance) {
      hasCloseObjects = true;
      break;
    }
  }
  
  if (hasCloseObjects) {
    // Flash warning
    int flashRate = millis() / 300;
    if (flashRate % 2 == 0) {
      fill(dangerColor, 150);
      textSize(32);
      textAlign(CENTER);
      text("⚠️ VERY CLOSE OBJECT! ⚠️", width/2, height/2 - 100);
      textAlign(LEFT);
    }
  }
}

int countObjects() {
  int count = 0;
  for (int i = 0; i < distances.length; i++) {
    if (distances[i] > 0 && distances[i] <= maxDistance) {
      count++;
    }
  }
  return count;
}

void drawDebugPanel() {
  // Debug panel for troubleshooting
  fill(0, 150);
  rect(width - 350, 100, 330, 200, 10);
  
  fill(255, 200, 0);
  textSize(14);
  text("DEBUG MODE", width - 340, 125);
  text("Press 'D' to hide", width - 340, 145);
  
  if (serialData != null) {
    text("Data: " + serialData, width - 340, 170);
  }
  
  text("Angle: " + currentAngle + "°", width - 340, 190);
  text("Objects: " + countObjects(), width - 340, 210);
  text("Connected: " + connected, width - 340, 230);
  
  // Show recent debug messages
  for (int i = 0; i < min(debugLog.size(), 3); i++) {
    text(debugLog.get(debugLog.size() - 1 - i), width - 340, 250 + i * 20);
  }
}

void serialEvent(Serial port) {
  serialData = port.readStringUntil('\n');
  
  if (serialData != null) {
    serialData = trim(serialData);
    
    String[] data = split(serialData, ',');
    
    if (data.length == 2) {
      try {
        int angle = int(data[0]);
        float distance = float(data[1]);
        
        // Update scanning direction
        if (angle > currentAngle) {
          scanningForward = true;
        } else if (angle < currentAngle) {
          scanningForward = false;
        }
        
        previousAngle = currentAngle;
        currentAngle = angle;
        
        // Store distance and set object age for persistence
        if (angle >= 0 && angle < distances.length) {
          distances[angle] = distance;
          objectAge[angle] = 30;  // Keep object visible for 30 frames
          dataCount++;
        }
      } catch (Exception e) {
        addDebugMessage("Parse error: " + e.toString());
      }
    }
  }
}

void keyPressed() {
  // Port selection
  if (key >= '0' && key <= '9') {
    int portIndex = key - '0';
    String[] portList = Serial.list();
    if (portIndex < portList.length) {
      connectToPort(portList[portIndex]);
    }
  }
  
  // Toggle debug mode
  if (key == 'd' || key == 'D') {
    showDebug = !showDebug;
  }
  
  // Toggle test objects
  if (key == 't' || key == 'T') {
    forceTestObject = !forceTestObject;
  }
  
  // Clear all objects
  if (key == 'c' || key == 'C') {
    for (int i = 0; i < distances.length; i++) {
      distances[i] = 0;
      objectAge[i] = 0;
    }
    addDebugMessage("Cleared all objects");
  }
}

----------------------------------------------------------------------------------

  1. Connect your ESP32 to computer via USB
  2. Open Arduino IDE
  3. Select your board: Tools → Board → ESP32 Arduino → "ESP32 Dev Module"
  4. Select the port: Tools → Port → (choose your ESP32 port)
  5. Copy and paste the ESP32 code (the one you provided)
  6. Click Upload (arrow button)

Key Code Explanations:

// This part measures distance
int measureDistance() {
    digitalWrite(TRIGGER_PIN, HIGH);  // Send ultrasonic pulse
    delayMicroseconds(10);
    digitalWrite(TRIGGER_PIN, LOW);
    
    long duration = pulseIn(ECHO_PIN, HIGH);  // Wait for echo
    int distance = duration * 0.034 / 2;     // Convert to centimeters
    return distance;
}
// This part moves the servo
if (scanningForward) {
    currentAngle += SCAN_STEP;  // Move forward
} else {
    currentAngle -= SCAN_STEP;  // Move backward
}
radarServo.write(currentAngle);  // Move servo to new position

Part 4: Setting Up the Processing Radar Display

Step 1: Understanding the Processing Code

The Processing code creates a visual radar display that:

  1. Receives data from ESP32 via serial port
  2. Draws a radar screen with distance rings and angle lines
  3. Shows detected objects as colored dots
  4. Provides kid-friendly interface with warnings and status

Step 2: Run the Processing Code

  1. Open Processing IDE
  2. Copy and paste the Processing code (the one you provided)
  3. Click Run (play button)

Step 3: Connect to ESP32

When the Processing program runs:

  1. It will show available serial ports
  2. Press the number key (0-9) corresponding to your ESP32 port
  3. You should see "CONNECTED ✓" message
  4. The radar should start showing objects!

Part 5: How It Works

The Radar Process:

  1. Servo rotates from 15° to 165° and back
  2. At each angle, ultrasonic sensor measures distance
  3. ESP32 sends angle and distance data: "90,45" (90 degrees, 45cm)
  4. Processing receives this data and draws it on screen
  5. Objects appear as colored dots based on distance

Distance Zones (Kid-Friendly):

  • Red: Very Close (0-20cm) - "VERY CLOSE!"
  • Orange: Close (20-40cm) - "Close"
  • Yellow: Medium (40-60cm) - "Medium"
  • Green: Far (60-80cm) - "Far"
  • Blue: Very Far (80-100cm) - "Very Far"

Part 6: Testing and Troubleshooting

Testing Your Radar:

  1. Move your hand in front of the sensor at different distances
  2. Place objects at various positions
  3. Watch the radar screen - objects should appear as colored dots
  4. Test the range - maximum detection is about 100cm (1 meter)

Common Issues and Solutions:

"Port not found" or "Connection failed":

  • Check USB cable - Make sure it's a data cable, not power-only
  • Check drivers - Install ESP32 drivers if needed
  • Try different port - Use different USB port on computer
  • Restart Arduino IDE and try again

"Servo not moving smoothly":

  • Check power supply - Servo needs enough power (5V recommended)
  • Check connections - Ensure all wires are secure
  • Adjust delay - Increase SERVO_DELAY in ESP32 code

"No objects detected" or "Incorrect distances":

  • Check sensor connections - TRIGGER and ECHO pins
  • Sensor orientation - Make sure sensor faces forward
  • Remove obstacles - Clear area in front of sensor
  • Check sensor mounting - Should be stable on servo

"Processing display not working":

  • Select correct port - Press right number key for ESP32 port
  • Check baud rate - Should be 115200 in both codes
  • Try debug mode - Press 'D' in Processing to see debug info

Useful Processing Controls:

  • Press 'D' - Toggle debug mode
  • Press 'T' - Add test objects (when not connected)
  • Press 'C' - Clear all detected objects
  • Press 0-9 - Select serial port

Part 7: Customization Ideas

For Beginners:

  1. Change colors - Modify the color variables in Processing code
  2. Adjust range - Change maxDistance to scan further/closer
  3. Speed control - Modify SERVO_DELAY for faster/slower scanning
  4. Add sounds - Use Processing's sound library for beeps

For Advanced Users:

  1. Add LCD display - Show distance on hardware display
  2. Multiple sensors - Use multiple ultrasonics for wider coverage
  3. Object tracking - Remember object positions over time
  4. Save radar data - Log detections to file
  5. WiFi connectivity - Send data over network

Part 8: Understanding the Science

How Ultrasonic Sensors Work:

  • Send sound wave at 40kHz (too high for humans to hear)
  • Wait for echo to return from objects
  • Calculate distance using: Distance = (Time × Speed of Sound) ÷ 2
  • Speed of sound ≈ 343 meters/second in air

Why Divide by 2?

Sound travels to the object and back, so total distance is double the actual distance to object.

Servo Motor Basics:

  • PWM Control - Uses pulse width to set position
  • 50Hz frequency - Standard for servo motors
  • Pulse width: 1ms = 0°, 1.5ms = 90°, 2ms = 180°

Part 9: Safety and Best Practices

Safety Tips:

  • Low voltage - This project uses safe 5V/3.3V levels
  • Secure connections - Ensure all wires are properly connected
  • Stable mounting - Prevent servo/sensor from falling
  • Adult supervision - For younger builders

Best Practices:

  • Comment your code - Add explanations for future reference
  • Test incrementally - Test each component separately first
  • Keep backups - Save working code versions
  • Document changes - Note what modifications you make

Conclusion

Congratulations! You've built a working radar system that can detect objects and display them in real-time. This project demonstrates many important concepts:

  • Sensor interfacing - Reading real-world data
  • Motor control - Precise positioning
  • Serial communication - Data transfer between devices
  • Data visualization - Converting numbers to graphics
  • Real-time systems - Processing continuous data streams

Next Steps:

  1. Experiment with different objects and distances
  2. Modify the code to add new features
  3. Share your project with friends and family
  4. Learn more about robotics and programming

Additional Resources:

Happy building! 🚀

Back to blog

Leave a comment