Radar and sonar systems have played critical roles in a diverse array of applications, spanning from military and aerospace to autonomous vehicles and robotics. In this article, TechSparks explores a technical project that integrates the principles of sonar, servo motors, and the ESP32 microcontroller to craft an effective object detection system. This project finds applications in various domains, including robotics, security systems, and autonomous vehicles, offering versatile use cases like obstacle avoidance, object tracking, and the development of interactive installations.
Project Principle
Sonar, which stands for Sound Navigation and Ranging, is a technique that uses sound waves to determine the distance and location of objects in its path. It operates based on the principle of echolocation, where an ultrasonic transducer emits a sound wave and measures the time it takes for the sound wave to bounce off an object and return. By calculating the time delay, we can determine the distance to the object.
A servo motor is a precise and highly controllable rotary actuator that can move to a specific angle or position. It works on the feedback control principle, where a control signal (in this case, from the ESP32) dictates the desired position, and the servo adjusts itself to reach that position. The servo’s feedback mechanism ensures accuracy and stability in its movements.
Wiring Diagram
To implement the sonar detection system using ESP32 and a servo motor, it is essential to correctly wire the components. Below is a basic wiring diagram:
- Connect the VCC and GND pins of the ESP32 to a power supply or battery.
- Link the trigger and echo pins of the sonar sensor to specific GPIO pins 12 and 32, respectively, on the ESP32.
- Connect the servo motor to the ESP32’s PWM (Pulse Width Modulation) capable GPIO pins, such as pin 14.
- Ensure that all components are grounded together for a common reference point.

Installing ESP32 Servo
Select the tools form the Arduino IDE >ESP32 dev module>board manager.



In the search bar types Esp32Servo click on the install button and click install.
Code for Interfacing Sonar Sensor, Servo Motor, and ESP32 Control
#include
This line includes the ‘ESP32Servo’ library, enabling servo motor control with an ESP32 microcontroller.
const int trigPin = 13;
const int echoPin = 12;
The trigger pin (trigPin) sends a signal from the ESP32 to initiate ultrasonic measurements, while the echo pin (echoPin) receives the echo signal.
long duration;
int distance;
These variables store the ultrasonic pulse duration and the calculated object distance.
Servo myServo;
This line creates an instance of the Servo class named myServo, which will control the servo motor.
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
myServo.attach(14);
}
In the setup() function:
- pinMode(trigPin, OUTPUT); configures trigPin as an output for sending signals to the ultrasonic sensor.
- pinMode(echoPin, INPUT); configures echoPin as an input for receiving signals from the ultrasonic sensor.
- Serial.begin(9600); initializes serial communication with a baud rate of 9600, facilitating debugging information transmission to your computer.
- myServo.attach(14); attaches the servo motor to GPIO pin 14 on the ESP32.
void loop() {
for (int i = 15; i <= 165; i++) {
myServo.write(i);
delay(30);
distance = calculateDistance();
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
}
for (int i = 165; i > 15; i--) {
myServo.write(i);
delay(30);
distance = calculateDistance();
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
}
}
In the loop() function, a loop oscillates the servo motor between 15 and 165 degrees. For each degree:
- myServo.write(i); sets the servo motor angle to the value represented by the variable i.
- delay(30); introduces a 30-millisecond delay, allowing the servo motor to reach the desired angle.
- distance = calculateDistance(); calls the calculateDistance() function to measure object distance using the ultrasonic sensor.
- Serial.print(i);, Serial.print(“,”);, and Serial.print(“.”); send the current servo angle and measured distance information to the serial port for later analysis.
After reaching 165 degrees, the code reverses the rotation to cover the full range of motion.
int calculateDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
return distance;
}
The calculateDistance() function measures distance using the ultrasonic sensor:
- digitalWrite(trigPin, LOW); sets the trigger pin to a low state.
- delayMicroseconds(2); introduces a short delay.
- digitalWrite(trigPin, HIGH); sets the trigger pin to a high state for 10 microseconds, emitting an ultrasonic pulse.
- delayMicroseconds(10); introduces another short delay.
- digitalWrite(trigPin, LOW); sets the trigger pin back to a low state.
- duration = pulseIn(echoPin, HIGH); measures the echo signal’s return time and reads the echo pin. The pulseIn function returns the sound wave travel time in microseconds.
- distance = duration * 0.034 / 2; calculates the distance in centimeters using the formula “distance = (duration * speed of sound) / 2” (assuming the speed of sound in air is approximately 0.034 cm/µs).
The calculated distance is returned.
Installing Processing-APP
For data visualization and advanced data processing, you can develop a Processing application that retrieves data from the ESP32 and presents it in a user-friendly interface.
Download the application from the official source using the provided link: https://processing.org/download.
After downloading, extract the executable file and proceed with the installation.
The application’s code provides a visual context for the software. It enables the sonar to rotate and provides a visual representation within the application, displaying the footprint as it scans its surroundings.
Radar Data Visualization Application Based on Processing
import processing.serial.*; // imports library for serial communication
import java.awt.event.KeyEvent; // imports library for reading the data from the serial port
import java.io.IOException;
Serial myPort; // defines Object Serial
// defubes variables
String angle="";
String distance="";
String data="";
String noObject;
float pixsDistance;
int iAngle, iDistance;
int index1=0;
int index2=0;
PFont orcFont;
void setup() {
size (1200, 700); // ***CHANGE THIS TO YOUR SCREEN RESOLUTION***
smooth();
myPort = new Serial(this,"COM5", 9600); // starts the serial communication
myPort.bufferUntil('.'); // reads the data from the serial port up to the character '.'. So actually it reads this: angle,distance.
}
void draw() {
fill(98,245,31);
// simulating motion blur and slow fade of the moving line
noStroke();
fill(0,4);
rect(0, 0, width, height-height*0.065);
fill(98,245,31); // green color
// calls the functions for drawing the radar
drawRadar();
drawLine();
drawObject();
drawText();
}
void serialEvent (Serial myPort) { // starts reading data from the Serial Port
// reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
data = myPort.readStringUntil('.');
data = data.substring(0,data.length()-1);
index1 = data.indexOf(","); // find the character ',' and puts it into the variable "index1"
angle= data.substring(0, index1); // read the data from position "0" to position of the variable index1 or thats the value of the angle the Arduino Board sent into the Serial Port
distance= data.substring(index1+1, data.length()); // read the data from position "index1" to the end of the data pr thats the value of the distance
// converts the String variables into Integer
iAngle = int(angle);
iDistance = int(distance);
}
void drawRadar() {
pushMatrix();
translate(width/2,height-height*0.074); // moves the starting coordinats to new location
noFill();
strokeWeight(2);
stroke(98,245,31);
// draws the arc lines
arc(0,0,(width-width*0.0625),(width-width*0.0625),PI,TWO_PI);
arc(0,0,(width-width*0.27),(width-width*0.27),PI,TWO_PI);
arc(0,0,(width-width*0.479),(width-width*0.479),PI,TWO_PI);
arc(0,0,(width-width*0.687),(width-width*0.687),PI,TWO_PI);
// draws the angle lines
line(-width/2,0,width/2,0);
line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30)));
line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60)));
line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90)));
line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120)));
line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150)));
line((-width/2)*cos(radians(30)),0,width/2,0);
popMatrix();
}
void drawObject() {
pushMatrix();
translate(width/2,height-height*0.074); // moves the starting coordinats to new location
strokeWeight(9);
stroke(255,10,10); // red color
pixsDistance = iDistance*((height-height*0.1666)*0.025); // covers the distance from the sensor from cm to pixels
// limiting the range to 40 cms
if(iDistance<40){
// draws the object according to the angle and the distance
line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),(width-width*0.505)*cos(radians(iAngle)),-(width-width*0.505)*sin(radians(iAngle)));
}
popMatrix();
}
void drawLine() {
pushMatrix();
strokeWeight(9);
stroke(30,250,60);
translate(width/2,height-height*0.074); // moves the starting coordinats to new location
line(0,0,(height-height*0.12)*cos(radians(iAngle)),-(height-height*0.12)*sin(radians(iAngle))); // draws the line according to the angle
popMatrix();
}
void drawText() { // draws the texts on the screen
pushMatrix();
if(iDistance>40) {
noObject = "Out of Range";
}
else {
noObject = "In Range";
}
fill(0,0,0);
noStroke();
rect(0, height-height*0.0648, width, height);
fill(98,245,31);
textSize(25);
text("10cm",width-width*0.3854,height-height*0.0833);
text("20cm",width-width*0.281,height-height*0.0833);
text("30cm",width-width*0.177,height-height*0.0833);
text("40cm",width-width*0.0729,height-height*0.0833);
textSize(40);
text("Hani's Experiments", width-width*0.875, height-height*0.0277);
text("Angle: " + iAngle +" °", width-width*0.48, height-height*0.0277);
text("Distance: ", width-width*0.26, height-height*0.0277);
if(iDistance<40) {
text(" " + iDistance +" cm", width-width*0.225, height-height*0.0277);
}
textSize(25);
fill(98,245,60);
translate((width-width*0.4994)+width/2*cos(radians(30)),(height-height*0.0907)-width/2*sin(radians(30)));
rotate(-radians(-60));
text("30°",0,0);
resetMatrix();
translate((width-width*0.503)+width/2*cos(radians(60)),(height-height*0.0888)-width/2*sin(radians(60)));
rotate(-radians(-30));
text("60°",0,0);
resetMatrix();
translate((width-width*0.507)+width/2*cos(radians(90)),(height-height*0.0833)-width/2*sin(radians(90)));
rotate(radians(0));
text("90°",0,0);
resetMatrix();
translate(width-width*0.513+width/2*cos(radians(120)),(height-height*0.07129)-width/2*sin(radians(120)));
rotate(radians(-30));
text("120°",0,0);
resetMatrix();
translate((width-width*0.5104)+width/2*cos(radians(150)),(height-height*0.0574)-width/2*sin(radians(150)));
rotate(radians(-60));
text("150°",0,0);
popMatrix();


Ending
In summary, we have successfully created a radar-inspired object detection system utilizing an ESP32 microcontroller, a sonar sensor, and a servo motor. This project’s completion involved gaining insights into sonar technology, configuring the hardware components, and crafting code to collect and analyze data. The result is a versatile tool with a wide range of real-world applications. Whether you are an enthusiastic hobbyist, a curious student, or a seasoned professional, this project offers a valuable opportunity to delve into the capabilities of contemporary technology and its potential across diverse domains.
You Might Be Interested


This article delves into PWM on the ESP32, crucial for precise control in applications like LED dimming, motor regulation, and audio generation. It explains the


This guide illustrates how to integrate LVGL with the ESP32, enabling the creation of engaging graphical user interfaces for embedded systems. By configuring libraries and


This comprehensive guide elucidates the process of enabling multi-core functionality on the ESP32 microcontroller, leveraging its dual-core architecture for enhanced parallel processing capabilities. Through detailed


Dive into the world of microcontrollers with TechSparks’ comprehensive guide to the ESP32! Discover the power of this versatile chip, renowned for its integration, low


The ESP32 is a versatile microcontroller with extensive functionalities. Its pinout includes GPIO pins for digital, analog, and capacitive touch, PWM pins for precise control,


This guide introduces an efficient method, “ESP-IDF + VSCode,” for ESP32 development, simplifying environment setup and allowing seamless switching between ESP-IDF versions. It covers downloading


Unlock the potential of your ESP32 with these 4 simple steps to WiFi connectivity! Dive into the world of IoT and remote control effortlessly, as


In the world of IoT, the ESP32 microcontroller stands out as a versatile champion with its integrated Bluetooth Low Energy (BLE) technology. This article explores