A real radar spins an antenna and listens for echoes. Yours does the same with sound you can't hear: a servo turns the ultrasonic sensor from side to side, the UNO measures the distance at every degree, and your computer draws it all as a green radar screen. Three LEDs and a buzzer work as a warning light on the desk, so the radar is useful even without the computer.
What you'll learn
- How to sweep a servo and take a measurement at every step
- How to send data to the computer over the serial port
- How a program on the computer reads that data and draws it
- How to turn a distance into a traffic-light warning
What you need
- UNO R3 board and USB cable (UNO R3 Starter Kit)
- Ultrasonic sensor HC-SR04 (UNO R3 Starter Kit)
- SG90 micro servo (UNO R3 Starter Kit)
- Green, yellow and red LEDs and three 220 Ω resistors (UNO R3 Starter Kit)
- Active buzzer (UNO R3 Starter Kit)
- Breadboard and jumper wires, including four female-to-male wires for the sensor (UNO R3 Starter Kit)
- Double-sided tape or a small printed bracket to hold the sensor on the servo
- A computer with the free Processing app for the radar screen
Build the radar turret
- Push the long two-sided horn onto the servo, but don't screw it on yet.
- Centre the servo before you fix the horn: wire the servo as shown below, upload a sketch with
turret.attach(9); turret.write(90);insetup(), then take the horn off and put it back pointing straight forward. - Stick the HC-SR04 on the horn with double-sided tape, with its "eyes" facing forward and its pins pointing up.
- Connect the sensor with four female-to-male jumper wires, and leave them loose enough for the servo to turn through its whole sweep.
Have a 3D printer? A small bracket that clips the sensor onto the servo horn makes the turret sturdier. Any HC-SR04 servo bracket works.
Wiring

| From | To |
|---|---|
| Ultrasonic VCC | + rail (5V) |
| Ultrasonic Trig | UNO pin 10 |
| Ultrasonic Echo | UNO pin 11 |
| Ultrasonic GND | − rail (GND) |
| Servo signal (orange) | UNO pin 9 |
| Servo + (red) | + rail (5V) |
| Servo − (brown) | − rail (GND) |
| Green LED, long leg | UNO pin 7 |
| Yellow LED, long leg | UNO pin 6 |
| Red LED, long leg | UNO pin 5 |
| Each LED's short leg | 220 Ω resistor to the − rail |
| Active buzzer + | UNO pin 8 |
| Active buzzer − | − rail (GND) |
| UNO 5V | + rail |
| UNO GND | − rail |
Use the active buzzer: it beeps on its own when its pin goes HIGH. The long leg of each LED is the + side.
The Arduino sketch
#include <Servo.h>
const int TRIG_PIN = 10;
const int ECHO_PIN = 11;
const int SERVO_PIN = 9;
const int GREEN_LED = 7;
const int YELLOW_LED = 6;
const int RED_LED = 5;
const int BUZZER_PIN = 8;
const int MIN_ANGLE = 15; // the servo sweeps from here...
const int MAX_ANGLE = 165; // ...to here and back
const int RANGE_CM = 40; // the radar only "sees" this far
const int NEAR_CM = 15; // closer than this: red LED and beep
Servo turret;
long readCm() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long us = pulseIn(ECHO_PIN, HIGH, 30000); // give up after 30 ms (about 5 m)
if (us == 0) return 0; // 0 means "nothing found"
return us / 58;
}
void showDistance(long cm) {
bool found = cm > 0 && cm <= RANGE_CM;
bool near = found && cm <= NEAR_CM;
digitalWrite(GREEN_LED, !found); // green: all clear
digitalWrite(YELLOW_LED, found && !near); // yellow: something in range
digitalWrite(RED_LED, near); // red: something close
digitalWrite(BUZZER_PIN, near); // and the buzzer beeps
}
void scanAt(int angle) {
turret.write(angle);
delay(30); // let the servo arrive
long cm = readCm();
showDistance(cm);
Serial.print(angle); // send "angle,distance." to the PC
Serial.print(",");
Serial.print(cm);
Serial.print(".");
}
void setup() {
Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
turret.attach(SERVO_PIN);
}
void loop() {
for (int angle = MIN_ANGLE; angle <= MAX_ANGLE; angle++) scanAt(angle);
for (int angle = MAX_ANGLE; angle >= MIN_ANGLE; angle--) scanAt(angle);
}
The radar screen (Processing)
Install Processing, start it, paste this sketch into a new window and click Run. Close the Arduino IDE's Serial Monitor first: only one program can use the port at a time.
import processing.serial.*;
final int RANGE_CM = 40; // must match RANGE_CM in the Arduino sketch
Serial port;
String buffer = "";
int angle = 0;
int distance = 0;
int[] seen = new int[181]; // the last distance found at each angle
void setup() {
size(1200, 700);
smooth();
println(Serial.list()); // the list of ports, in the console
port = new Serial(this, Serial.list()[0], 9600); // change [0] if needed
}
void serialEvent(Serial p) {
char c = p.readChar();
if (c == '.') { // one full "angle,distance" has arrived
String[] parts = split(trim(buffer), ',');
if (parts.length == 2) {
angle = int(parts[0]);
distance = int(parts[1]);
if (angle >= 0 && angle <= 180) seen[angle] = distance;
}
buffer = "";
} else {
buffer += c;
}
}
void draw() {
fill(0, 20); // a see-through black: old lines fade out
noStroke();
rect(0, 0, width, height);
float cx = width / 2.0;
float cy = height - 70;
float r = width * 0.45; // radius of the radar on screen
// rings and angle lines
noFill();
stroke(60, 220, 100);
strokeWeight(2);
for (int i = 1; i <= 4; i++) arc(cx, cy, 2 * r * i / 4, 2 * r * i / 4, PI, TWO_PI);
for (int a = 30; a <= 150; a += 30) line(cx, cy, cx + r * cos(radians(a)), cy - r * sin(radians(a)));
// objects: a red line from the object to the edge
stroke(230, 60, 60);
strokeWeight(5);
for (int a = 0; a <= 180; a++) {
int d = seen[a];
if (d > 0 && d <= RANGE_CM) {
float p = r * d / RANGE_CM;
line(cx + p * cos(radians(a)), cy - p * sin(radians(a)),
cx + r * cos(radians(a)), cy - r * sin(radians(a)));
}
}
// the sweep line
stroke(60, 255, 120);
strokeWeight(6);
line(cx, cy, cx + r * cos(radians(angle)), cy - r * sin(radians(angle)));
// the status bar
noStroke();
fill(0);
rect(0, height - 50, width, 50);
fill(60, 255, 120);
textSize(24);
boolean inRange = distance > 0 && distance <= RANGE_CM;
text("Angle: " + angle + "°", 40, height - 17);
text("Status: " + (inRange ? "In range " + distance + " cm" : "Out of range"), width / 2 - 120, height - 17);
for (int i = 1; i <= 4; i++) text(RANGE_CM * i / 4 + " cm", cx + r * i / 4 - 50, cy - 8);
}

Try it
- Upload the Arduino sketch. The servo starts sweeping slowly from left to right and back, and the green LED is on.
- Run the Processing sketch. A green line sweeps across the screen in time with the servo.
- Put your hand or a toy about 30 cm in front of the sensor. A red line appears on the screen at that angle, and the yellow LED lights up.
- Move it closer than 15 cm. The red LED comes on and the buzzer beeps.
How it works
For every angle the UNO sends a short message such as 87,23.: the angle, a comma, the distance in centimetres and a full stop. The full stop marks the end of the message, so the computer knows when it has the whole thing. A distance of 0 means nothing came back.
Processing turns each angle and distance into a point with a little trigonometry: x = cos(angle) × distance and y = sin(angle) × distance, scaled to fit the screen. It keeps the last distance for each angle in an array, so objects stay on the screen until the sweep comes round again. Drawing a see-through black rectangle over the whole window every frame makes the old sweep lines fade away slowly, just like a real radar screen.
Try this next
- Change
RANGE_CMin both sketches to 60 to see further. Readings get less reliable beyond about 1 m. - Make the servo sweep faster by changing
delay(30)todelay(15). What happens to the picture? - Add the LCD from the LCD lesson and show the angle and distance of the nearest object.
- Go wireless: the ESP32 radar shows the same picture on your phone, with no cable to the computer.
Troubleshooting
-
Processing says the port is busy or doesn't exist: close the Serial Monitor. Look at the list printed in Processing's console and change
Serial.list()[0]to the number of the port your UNO uses (often the last one). - The UNO resets or the servo jitters: the servo pulls a lot of current when it starts. Plug the UNO into a USB port directly, not through a hub, or power the servo from the breadboard power module.
- Objects appear in the wrong place: the horn is not pointing forward at 90°. Take it off and put it back while the servo is at 90°.
- Everything shows as "Out of range": check that Trig is on pin 10 and Echo on pin 11. Swapping them is the most common mistake.