Radar con Arduino: HC-SR04, servo SG90 y pantalla en Processing
Cómo hacer un radar con Arduino paso a paso: conexión del HC-SR04 y el servo SG90, código de ángulo y distancia, pantalla verde en Processing y mini radar OLED.
Un radar con Arduino es un proyecto que monta un sensor ultrasónico HC-SR04 sobre un servomotor SG90 y lo gira entre 0 y 180 grados para medir la dirección y la distancia de los objetos cercanos, mostrando el resultado en el ordenador como una pantalla de radar verde, igual que en las películas. En cada ángulo el Arduino toma una medida y envía una línea con el formato "ángulo,distancia" por el puerto serie; un pequeño programa de Processing que se ejecuta en el ordenador lee esos números y dibuja la línea de barrido que gira y los objetos detectados como líneas rojas.
En esta guía encontrarás cada paso explicado, desde la lista de materiales y el esquema de conexión hasta el código de Arduino y la pantalla de radar en Processing. También vemos un mini radar con pantalla OLED que no necesita ordenador, las versiones para ESP32 y Raspberry Pi Pico, cómo ajustar la velocidad del barrido y la precisión de las medidas y cómo resolver los errores más comunes del puerto serie. Es barato, se termina en una tarde y es uno de los proyectos de Arduino que más llaman la atención en las presentaciones del colegio.




¿Cómo funciona un radar con Arduino?
El corazón del sistema es el HC-SR04. Uno de los dos cilindros del sensor (T) emite una breve ráfaga de sonido de 40 kHz que el oído humano no puede oír; cuando el sonido choca con un objeto y vuelve, el otro (R) capta el eco. El Arduino mide ese tiempo de ida y vuelta en microsegundos. El sonido viaja por el aire a unos 343 m/s, así que tarda unos 29 microsegundos en recorrer un centímetro; como el camino se recorre dos veces, ida y vuelta, la fórmula queda distancia (cm) = tiempo (µs) / 58. El servo gira el sensor paso a paso y en cada paso se repite la medida. Al final tienes la información de "en qué ángulo y a cuántos centímetros hay algo", es decir, una coordenada polar. Para dibujarla en pantalla, el ángulo y la distancia se convierten en una posición en píxeles con x = distancia × cos(ángulo) e y = distancia × sin(ángulo).
| Pieza | Función | Valores clave |
|---|---|---|
| HC-SR04 | Medición de distancia por ultrasonidos | 40 kHz, 2–400 cm, ángulo de medida de unos 15°, 5 V, 15 mA |
| Servo SG90 | Gira el sensor de 0 a 180° | 0,1 s/60° (4,8 V), par de 1,8 kg·cm, 4,8–6 V, 9 g |
| Arduino Uno | Mide, mueve el servo y envía los datos | 16 MHz, nivel lógico de 5 V, puerto serie USB |
| Processing | Dibuja la pantalla del radar en el ordenador | Gratuito, basado en Java, incluye la librería Serial |
| OLED SSD1306 (opcional) | Mini pantalla de radar sin ordenador | 128×64 píxeles, I2C, dirección 0x3C |
Materiales para el radar con Arduino
- Arduino Uno o Nano y un cable USB que transmita datos (los cables que solo cargan no aparecen como puerto en el ordenador).
- Sensor ultrasónico de distancia HC-SR04.
- Micro servo SG90 y los brazos de plástico que vienen en su bolsa.
- Una protoboard y 8–10 cables jumper macho-macho y macho-hembra.
- Un condensador electrolítico de 470 µF (al menos 10 V): evita que la tensión caiga cuando el servo se mueve.
- Cinta de doble cara, silicona caliente o un pequeño soporte impreso en 3D para fijar el sensor al servo.
- Opcional: una pantalla OLED I2C de 0,96 pulgadas (para la versión sin ordenador) y un adaptador externo de 5 V y 2 A.
Esquema de conexión del radar con Arduino
| Conexión | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| HC-SR04 VCC | 5V | VIN (5 V) | VBUS (pin 40) |
| HC-SR04 GND | GND | GND | GND |
| HC-SR04 Trig | D10 | GPIO 26 | GP14 |
| HC-SR04 Echo | D11 | GPIO 27 (con divisor) | GP13 (con divisor) |
| SG90 marrón (GND) | GND | GND | GND |
| SG90 rojo (+5 V) | 5V | VIN (5 V) | VBUS (pin 40) |
| SG90 naranja (señal) | D9 | GPIO 13 | GP15 |
En el Uno, el cableado queda más ordenado si conectas los terminales de 5 V y GND del sensor y del servo a las líneas positiva y negativa de la protoboard, y esas líneas a los pines 5V y GND del Arduino. Coloca el condensador de 470 µF en esas mismas líneas, con la pata larga (+) en 5 V y la pata corta, marcada por la franja de su cuerpo, en GND. En algunos servos los cables son negro, rojo y blanco; en ese caso el negro es GND y el blanco la señal. Para comprobar dónde están los pines de tu placa, usa la herramienta de pinout.
Montar el sensor sobre el servo

Antes de colocar el brazo, lleva el servo a 90 grados: basta con subir un pequeño sketch de prueba con radarServo.write(90) y dejar el servo en esa posición. Después coloca el brazo de modo que el sensor mire justo al frente. Así 0° apunta a la derecha, 90° al frente y 180° a la izquierda, y las direcciones de la pantalla de Processing coinciden exactamente con el mundo real. Al pegar el HC-SR04 al brazo con cinta de doble cara o silicona caliente, asegúrate de que los dos cilindros queden paralelos al suelo; si el sensor queda inclinado hacia abajo, confundirá la superficie de la mesa con un objeto. Deja a los cables holgura suficiente para que no se tensen durante el giro de 180 grados y fija el servo a una base pesada o a una caja; un montaje que se sacude en cada paso estropea las medidas.
Cómo hacer un radar con Arduino paso a paso
- Conecta los componentes según la tabla anterior, no olvides el condensador y monta el sensor sobre el servo.
- Abre el IDE de Arduino; la librería Servo viene incluida, así que no tienes que instalar nada más.
- Sube el código del radar que aparece abajo. Si tienes problemas al elegir la placa o el puerto, consulta Arduino no sube el código.
- Abre el Monitor Serie a 9600 baudios; si van apareciendo líneas de ángulo y distancia como "30,45", la parte del Arduino está lista. Después cierra sin falta el Monitor Serie.
- Instala Processing 4 en tu ordenador, abre un sketch nuevo y pega el código de la pantalla del radar.
- Pulsa Run; en la consola de abajo aparece la lista de puertos y se abre la ventana del radar. Al mover la mano delante del sensor deberían aparecer líneas rojas.
Código del radar con Arduino
1#include <Servo.h>
2
3const byte SERVO_PIN = 9; // SG90 turuncu kablo / SG90 orange wire
4const byte TRIG_PIN = 10; // HC-SR04 Trig
5const byte ECHO_PIN = 11; // HC-SR04 Echo
6const int MIN_ANGLE = 0; // tarama başlangıcı / sweep start
7const int MAX_ANGLE = 180; // tarama sonu / sweep end
8const int STEP = 2; // adım başına derece / degrees per step
9const int STEP_DELAY = 40; // ölçümden önce bekleme (ms) / wait before measuring (ms)
10
11Servo radarServo;
12int angle = MIN_ANGLE;
13int dir = STEP;
14
15int measureCm() {
16 digitalWrite(TRIG_PIN, LOW);
17 delayMicroseconds(2);
18 digitalWrite(TRIG_PIN, HIGH); // 10 µs tetik darbesi / 10 µs trigger pulse
19 delayMicroseconds(10);
20 digitalWrite(TRIG_PIN, LOW);
21 unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL); // en çok 30 ms bekle / wait at most 30 ms
22 if (us == 0) return 0; // yankı yok = menzil dışı / no echo = out of range
23 return us / 58; // gidiş-dönüş süresi → cm / round-trip time → cm
24}
25
26void setup() {
27 Serial.begin(9600);
28 pinMode(TRIG_PIN, OUTPUT);
29 pinMode(ECHO_PIN, INPUT);
30 radarServo.attach(SERVO_PIN);
31 radarServo.write(angle);
32 delay(500); // başlangıç konumuna gitsin / reach the start position
33}
34
35void loop() {
36 radarServo.write(angle); // servoyu yeni açıya döndür / move the servo to the new angle
37 delay(STEP_DELAY); // titreşim geçsin / let the vibration settle
38 int distance = measureCm();
39
40 Serial.print(angle); // biçim: açı,mesafe / format: angle,distance
41 Serial.print(',');
42 Serial.println(distance);
43
44 if (angle + dir > MAX_ANGLE || angle + dir < MIN_ANGLE) dir = -dir; // uçta yön değiştir / reverse at the ends
45 angle += dir;
46}Explicación del código
| Parte del código | ¿Qué hace? |
|---|---|
| STEP y STEP_DELAY | Definen cuántos grados gira el servo en cada paso y cuánto se espera antes de medir; con estas dos constantes ajustas la velocidad del barrido. |
| measureCm() | Envía un pulso de 10 µs al pin Trig, mide con pulseIn cuánto tiempo permanece en HIGH el pin Echo y lo divide entre 58 para obtener centímetros. |
| pulseIn(..., 30000UL) | Espera como máximo 30 ms y devuelve 0 si no llega ningún eco. Sin este tiempo límite, la función podría quedarse bloqueada hasta 1 segundo al apuntar al vacío. |
| radarServo.write(angle) | Lleva el servo al ángulo deseado; la librería convierte el valor 0–180 en un pulso de 544–2400 µs. |
| Serial.print ... println | Envía cada medida como una sola línea "ángulo,distancia"; el salto de línea le indica a Processing que el dato está completo. |
| dir = -dir | Invierte el sentido cuando el ángulo llega a 180 o a 0, de modo que el servo barre de un lado a otro sin parar. |
Hay un motivo para que los datos sean tan sencillos: una sola línea separada por comas se lee cómodamente en el Monitor Serie y se puede separar con una línea de código en Processing, Python o Excel. Una distancia de 0 significa "no hay nada dentro del alcance en este ángulo" y Processing no dibuja esos valores. Si abres los mismos datos en el Serial Plotter del IDE de Arduino, verás que el ángulo sube y baja como un diente de sierra y que la distancia salta cada vez que el sensor pasa por delante de un objeto. Para este proyecto basta con usar delay; si quieres leer un botón o encender un LED mientras el radar funciona, reescribe el bucle con millis().
La pantalla de radar verde con Processing
Processing es un programa gratuito basado en Java pensado para la programación visual, y su interfaz se parece mucho al IDE de Arduino: escribes el código y pulsas Run. La librería Serial, necesaria para la comunicación serie, viene incluida con Processing; puedes añadirla desde el menú Sketch > Import Library o simplemente dejar la línea import del principio del código. El siguiente código se pega en Processing, no en el IDE de Arduino.
1// Processing 4 çizimi: Arduino IDE'ye değil, Processing'e yapıştır / Processing 4 sketch: paste into Processing, not the Arduino IDE
2import processing.serial.*; // Serial kütüphanesi / Serial library
3
4Serial port;
5int angle = 0; // son açı / last angle
6int distance = 0; // son mesafe (cm) / last distance (cm)
7final int MAX_CM = 100; // ekrandaki en uzak mesafe / farthest distance on screen
8float R; // radar yarıçapı (piksel) / radar radius (pixels)
9
10void setup() {
11 size(1200, 700);
12 R = width * 0.45;
13 printArray(Serial.list()); // portları konsola yaz / print the ports to the console
14 String portName = Serial.list()[0]; // gerekirse [1] ya da "COM4" yaz / use [1] or "COM4" if needed
15 port = new Serial(this, portName, 9600); // Arduino ile aynı baud / same baud as the Arduino
16 port.bufferUntil('\n'); // satır sonunu bekle / wait for the end of a line
17 background(0);
18}
19
20void draw() {
21 noStroke();
22 fill(0, 12); // yarı saydam siyah: solan iz / translucent black: fading trail
23 rect(0, 0, width, height);
24 translate(width / 2, height - 60); // radar merkezi alt ortada / radar centre at the bottom middle
25 drawGrid();
26 drawSweep();
27 drawObject();
28 drawLabels();
29}
30
31void drawGrid() {
32 noFill();
33 strokeWeight(2);
34 stroke(98, 245, 31);
35 for (int i = 1; i <= 4; i++) {
36 float d = 2 * R * i / 4;
37 arc(0, 0, d, d, PI, TWO_PI); // 25-50-75-100 cm yayları / 25-50-75-100 cm arcs
38 }
39 for (int a = 0; a <= 180; a += 30) {
40 line(0, 0, R * cos(radians(a)), -R * sin(radians(a))); // 30 derecelik çizgiler / 30-degree lines
41 }
42}
43
44void drawSweep() {
45 strokeWeight(5);
46 stroke(30, 250, 60);
47 line(0, 0, R * cos(radians(angle)), -R * sin(radians(angle))); // tarama çizgisi / sweep line
48}
49
50void drawObject() {
51 if (distance <= 0 || distance > MAX_CM) return; // menzil dışı / out of range
52 float p = R * distance / MAX_CM; // cm → piksel / cm → pixels
53 float c = cos(radians(angle));
54 float s = sin(radians(angle));
55 strokeWeight(7);
56 stroke(255, 10, 10);
57 line(p * c, -p * s, R * c, -R * s); // nesneden dışa kırmızı çizgi / red line from the object outwards
58}
59
60void drawLabels() {
61 resetMatrix();
62 noStroke();
63 fill(0);
64 rect(0, height - 40, width, 40); // yazı şeridi / text strip
65 fill(98, 245, 31);
66 textSize(20);
67 for (int i = 1; i <= 4; i++) {
68 text(MAX_CM * i / 4 + " cm", width / 2 + R * i / 4 + 4, height - 66); // yay etiketleri / arc labels
69 }
70 String d = (distance > 0 && distance <= MAX_CM) ? distance + " cm" : "-";
71 text("Açı / Angle: " + angle + "°", 40, height - 12);
72 text("Mesafe / Distance: " + d, width / 2, height - 12);
73}
74
75void serialEvent(Serial p) {
76 String msg = p.readStringUntil('\n'); // "açı,mesafe" satırı / "angle,distance" line
77 if (msg == null) return;
78 String[] parts = split(trim(msg), ',');
79 if (parts.length == 2) {
80 angle = int(parts[0]);
81 distance = int(parts[1]);
82 }
83}La parte más importante del código es la función serialEvent(). Gracias a bufferUntil('\n'), Processing va acumulando los datos hasta que llega un salto de línea y entonces llama automáticamente a esta función con una línea completa. La línea se limpia de espacios y del carácter \r con trim(), se divide en dos por la coma con split() y se convierte en números con int(). draw(), por su parte, se ejecuta unas 60 veces por segundo: primero pinta un rectángulo negro semitransparente sobre la pantalla (fill(0, 12)) y luego vuelve a dibujar la cuadrícula, la línea de barrido y el objeto. Como las líneas antiguas se oscurecen un poco en cada fotograma, el efecto de estela que se desvanece, típico de los radares, aparece solo.
| Ajuste | ¿Dónde? | ¿Para qué sirve? |
|---|---|---|
| MAX_CM = 100 | Processing | La distancia máxima que cubre la pantalla; el arco exterior es 100 cm y los interiores marcan 25, 50 y 75 cm. |
| Serial.list()[0] | Processing | Elige el primer puerto serie del ordenador; si tu Arduino está más abajo en la lista, cambia el índice o escribe directamente el nombre, por ejemplo "COM4". |
| 9600 | En ambos | Velocidad en baudios; el valor de Serial.begin en el Arduino y el de Processing deben coincidir. |
| fill(0, 12) | Processing | Velocidad del desvanecimiento; 5 deja una estela larga y 30 una imagen casi sin estela. |
| size(1200, 700) | Processing | Tamaño de la ventana; redúcelo si no cabe en tu pantalla. El radio depende del ancho, así que mantén la altura por encima de la mitad del ancho. |
Ajustar la velocidad del servo y el tiempo de barrido
Según su hoja de datos, el SG90 gira 60 grados en 0,1 segundos a 4,8 V, así que completa un paso de 2 grados en pocos milisegundos. Lo que de verdad marca el tiempo de barrido no es el servo, sino la espera y la medida en cada paso. Cuando el servo se detiene, el brazo y el sensor vibran un instante; si se mide en ese momento, las distancias saltan. Además, el fabricante del HC-SR04 recomienda dejar unos 60 ms entre dos medidas, porque los ecos del pulso anterior que rebotan por la habitación pueden colarse en la siguiente lectura. En la práctica, un total de 50–60 ms por paso (espera + medida) es un buen equilibrio. Un barrido completo dura aproximadamente (180 / paso + 1) × tiempo por paso.
| Paso | STEP_DELAY | Un barrido (0→180°) | Resultado |
|---|---|---|---|
| 1° | 20 ms | unos 7 s | La imagen más suave, pero lenta; el mismo objeto se mide muchas veces. |
| 2° | 40 ms | unos 5 s | Ajuste recomendado: fluido y estable. |
| 3° | 50 ms | unos 4 s | Más rápido; gracias al haz de 15° del sensor no se escapa ningún objeto. |
| 5° | 70 ms | unos 3,5 s | La pantalla se ve a saltos; con pasos grandes la vibración aumenta y la espera debe ser mayor. |
Para suavizar el movimiento, mantén el paso pequeño y la espera corta; si buscas velocidad, aumenta el paso y alarga un poco la espera. Limitar el barrido a la zona que te interesa (por ejemplo 45–135°) también reduce el tiempo a la mitad. Si el servo da tirones solo, el Arduino se reinicia de vez en cuando y Processing pierde la conexión, el problema no es la velocidad sino la alimentación: el SG90 puede consumir unos 100–250 mA al moverse y hasta 600 mA cuando está forzado. Añade el condensador y, si hace falta, alimenta el servo con una fuente externa de 5 V cuyo GND sea común con el del Arduino.
Mejorar la precisión de las medidas
Aunque sobre el papel el HC-SR04 promete una resolución de 3 mm, en un radar la precisión depende de tres cosas: el ancho del haz, la velocidad del sonido y el tipo de superficie. El haz de sonido del sensor se abre como un cono de unos 15 grados. Por eso un bolígrafo delgado a 50 cm no aparece en pantalla como un punto, sino como un arco de 15–20 grados; la resolución angular del radar la fija este haz, no el paso del servo, y la dirección real del objeto es el centro del arco. La velocidad del sonido cambia con la temperatura y se calcula con v = 331,3 + 0,606 × T (m/s, T en °C). El número 58 del código corresponde a unos 22 °C; en un garaje frío las medidas salen un pequeño porcentaje más largas.
| Temperatura | Velocidad del sonido | Ida y vuelta por 1 cm | Objeto a 100 cm (con /58) |
|---|---|---|---|
| 0 °C | 331,3 m/s | 60,4 µs | unos 104 cm |
| 10 °C | 337,4 m/s | 59,3 µs | unos 102 cm |
| 20 °C | 343,4 m/s | 58,2 µs | unos 100 cm |
| 30 °C | 349,5 m/s | 57,2 µs | unos 99 cm |
| 40 °C | 355,5 m/s | 56,3 µs | unos 97 cm |
Puedes medir la temperatura ambiente con un DHT11 o un DS18B20 y tener en cuenta la velocidad del sonido, y descartar las lecturas erróneas aisladas tomando la mediana de tres medidas. Solo tienes que añadir estas dos funciones al código principal y sustituir la llamada a measureCm() dentro de loop() por una de ellas. Como el filtro de mediana hace tres medidas en cada paso, el barrido se vuelve un poco más lento.
1// Ana radar koduna eklenecek fonksiyonlar / functions to add to the main radar sketch
2
3// Sıcaklığa göre düzeltilmiş ölçüm / temperature-compensated reading
4int measureCmTemp(float tempC) {
5 digitalWrite(TRIG_PIN, LOW);
6 delayMicroseconds(2);
7 digitalWrite(TRIG_PIN, HIGH);
8 delayMicroseconds(10);
9 digitalWrite(TRIG_PIN, LOW);
10 unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
11 if (us == 0) return 0; // yankı yok / no echo
12 float v = 331.3 + 0.606 * tempC; // ses hızı (m/s) / speed of sound (m/s)
13 return (int)(us * v / 20000.0 + 0.5); // µs × (m/s) / 20000 = cm
14}
15
16// Üç ölçümün ortancası: tek seferlik sıçramaları atar / median of three: drops one-off spikes
17int medianCm() {
18 int a = measureCm(); delay(20);
19 int b = measureCm(); delay(20);
20 int c = measureCm();
21 return max(min(a, b), min(max(a, b), c));
22}
23
24// loop() içinde kullanım / use inside loop():
25// int distance = medianCm();
26// int distance = measureCmTemp(18.5); // sıcaklık DHT11'den gelebilir / temperature can come from a DHT11- Las superficies blandas (cortinas, tela, espuma) absorben el sonido; puede que un objeto no aparezca donde está.
- Las superficies inclinadas desvían el sonido; una caja plana girada más de 45° respecto al sensor puede leerse como espacio vacío.
- Los objetos a menos de 2 cm no se pueden medir; en la práctica, considera poco fiable cualquier valor por debajo de 3–4 cm.
- Las esquinas de la habitación producen reflexiones múltiples y pueden crear "fantasmas" lejanos que no existen; haz las pruebas en una zona despejada y amplia.
- Alcance: la hoja de datos indica 400 cm, pero con objetos pequeños las medidas estables suelen llegar hasta unos 2 metros; elige MAX_CM en consecuencia.
Mini radar en una pantalla OLED (sin ordenador)
Si quieres que el radar sea un aparato portátil a pilas que no dependa del ordenador, puedes usar una pantalla OLED de 0,96 pulgadas en lugar de Processing. El punto central del borde inferior de la pantalla de 128×64 con controlador SSD1306 se convierte en el centro del radar; sobre ella se dibujan un semicírculo de 60 píxeles de radio, la línea de barrido y puntos que muestran el último objeto medido en cada ángulo. Para la conexión de la pantalla (SDA → A4, SCL → A5) y la instalación de las librerías, consulta la guía pantalla OLED SSD1306; el HC-SR04 y el servo se conectan igual que antes.

1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4#include <Servo.h>
5
6const byte SERVO_PIN = 9; // SG90 sinyal / SG90 signal
7const byte TRIG_PIN = 10; // HC-SR04 Trig
8const byte ECHO_PIN = 11; // HC-SR04 Echo
9const int MAX_CM = 50; // ekrandaki en uzak mesafe / farthest distance on screen
10const int STEP = 3; // adım başına derece / degrees per step
11const int CX = 64, CY = 63, R = 60; // radar merkezi ve yarıçapı (piksel) / radar centre and radius (px)
12
13Adafruit_SSD1306 display(128, 64, &Wire, -1);
14Servo radarServo;
15uint8_t dist[180 / STEP + 1]; // her açının son ölçümü (cm) / last reading per angle (cm)
16int angle = 0;
17int dir = STEP;
18
19int measureCm() {
20 digitalWrite(TRIG_PIN, LOW);
21 delayMicroseconds(2);
22 digitalWrite(TRIG_PIN, HIGH);
23 delayMicroseconds(10);
24 digitalWrite(TRIG_PIN, LOW);
25 unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
26 if (us == 0) return 0; // yankı yok / no echo
27 return us / 58;
28}
29
30void setup() {
31 pinMode(TRIG_PIN, OUTPUT);
32 pinMode(ECHO_PIN, INPUT);
33 radarServo.attach(SERVO_PIN);
34 if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
35 for (;;); // ekran bulunamadı / display not found
36 }
37 display.setTextColor(SSD1306_WHITE);
38}
39
40void loop() {
41 radarServo.write(angle);
42 delay(20); // çizim de zaman aldığı için kısa / short, drawing takes time too
43 int d = measureCm();
44 dist[angle / STEP] = (d > 255) ? 255 : d; // byte'a sığdır / fit into a byte
45
46 display.clearDisplay();
47 display.drawCircle(CX, CY, R, SSD1306_WHITE); // dış yay, alt yarısı ekran dışında / outer arc, lower half off-screen
48 display.drawCircle(CX, CY, R / 2, SSD1306_WHITE); // orta yay = MAX_CM / 2 / middle arc = MAX_CM / 2
49 for (int i = 0; i <= 180 / STEP; i++) {
50 if (dist[i] > 0 && dist[i] <= MAX_CM) {
51 float rad = radians(i * STEP);
52 int r = map(dist[i], 0, MAX_CM, 0, R); // cm → piksel / cm → pixels
53 display.fillCircle(CX + r * cos(rad), CY - r * sin(rad), 1, SSD1306_WHITE);
54 }
55 }
56 float rad = radians(angle);
57 display.drawLine(CX, CY, CX + R * cos(rad), CY - R * sin(rad), SSD1306_WHITE); // tarama çizgisi / sweep line
58 display.setCursor(0, 0);
59 display.print(angle); // açı / angle
60 display.setCursor(98, 0);
61 display.print(d); // mesafe / distance
62 display.print(F("cm"));
63 display.display();
64
65 if (angle + dir > 180 || angle + dir < 0) dir = -dir; // uçta yön değiştir / reverse at the ends
66 angle += dir;
67}En esta versión las distancias se guardan por ángulo en el array dist, de modo que los puntos siguen en pantalla después de que pase la línea de barrido y se actualizan en la siguiente pasada. El centro del círculo está en el borde inferior de la pantalla, así que su mitad inferior queda fuera y la librería no la dibuja: queda un semicírculo limpio. Enviar un fotograma a la pantalla tarda unos 25 ms con I2C a 400 kHz, por eso la espera se redujo a 20 ms y el paso subió a 3 grados; un barrido dura unos 4–5 segundos. En una pantalla pequeña una escala de 50 cm se entiende mejor, por eso MAX_CM vale 50. La mitad de los 2 KB de memoria del Uno se la lleva el búfer de la pantalla, así que es importante guardar el array como bytes (uint8_t).
Radar con ESP32
En el ESP32 la librería Servo de Arduino no funciona; tienes que instalar la librería ESP32Servo desde el Gestor de bibliotecas. El resto del código es casi igual. Como el ESP32 trabaja a 3,3 V, no olvides el divisor de tensión en la línea Echo del HC-SR04; en cambio, el pulso de 3,3 V en la línea Trig basta para disparar la mayoría de los sensores. Este código usa 115200 baudios, así que cambia también el 9600 del código de Processing por 115200. Gracias al Wi-Fi del ESP32, más adelante podrías enviar los datos del radar a una página web en el móvil en lugar de al ordenador; si el ESP32 es nuevo para ti, empieza por qué es el ESP32.
1#include <ESP32Servo.h> // Kütüphane Yöneticisi: ESP32Servo / Library Manager: ESP32Servo
2
3const int SERVO_PIN = 13; // SG90 sinyal / SG90 signal
4const int TRIG_PIN = 26; // HC-SR04 Trig
5const int ECHO_PIN = 27; // 1k/2k bölücüden / through the 1k/2k divider
6const int STEP = 2; // adım başına derece / degrees per step
7const int STEP_DELAY = 40; // ölçümden önce bekleme (ms) / wait before measuring (ms)
8
9Servo radarServo;
10int angle = 0;
11int dir = STEP;
12
13int measureCm() {
14 digitalWrite(TRIG_PIN, LOW);
15 delayMicroseconds(2);
16 digitalWrite(TRIG_PIN, HIGH);
17 delayMicroseconds(10);
18 digitalWrite(TRIG_PIN, LOW);
19 unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
20 if (us == 0) return 0; // yankı yok / no echo
21 return us / 58;
22}
23
24void setup() {
25 Serial.begin(115200); // Processing'de de 115200 / 115200 in Processing too
26 pinMode(TRIG_PIN, OUTPUT);
27 pinMode(ECHO_PIN, INPUT);
28 radarServo.setPeriodHertz(50); // standart servo 50 Hz / standard servo 50 Hz
29 radarServo.attach(SERVO_PIN, 500, 2400); // SG90 darbe aralığı (µs) / SG90 pulse range (µs)
30 radarServo.write(angle);
31 delay(500);
32}
33
34void loop() {
35 radarServo.write(angle);
36 delay(STEP_DELAY);
37 int distance = measureCm();
38 Serial.printf("%d,%d\n", angle, distance); // açı,mesafe / angle,distance
39 if (angle + dir > 180 || angle + dir < 0) dir = -dir; // uçta yön değiştir / reverse at the ends
40 angle += dir;
41}Radar con Raspberry Pi Pico y MicroPython
En la Pico no hace falta una librería aparte para el servo: basta con ajustar el ancho de pulso de una señal PWM de 50 Hz con duty_ns(). El tiempo del eco se mide con machine.time_pulse_us(), que devuelve un número negativo si se agota el tiempo. Los pines de la Pico también son de 3,3 V, así que el divisor en la línea Echo es obligatorio. Guarda el código en la Pico como main.py con Thonny y después cierra Thonny; si no, el puerto sigue ocupado y Processing no puede conectarse. Como la Pico abre un puerto serie virtual por USB, el valor de baudios en Processing da igual: la misma pantalla de radar funciona sin cambios.
1from machine import Pin, PWM, time_pulse_us
2import time
3
4servo = PWM(Pin(15)) # SG90 sinyal / SG90 signal
5servo.freq(50) # standart servo 50 Hz / standard servo 50 Hz
6trig = Pin(14, Pin.OUT)
7echo = Pin(13, Pin.IN) # bölücüden gelir / comes through the divider
8
9def set_angle(a):
10 # 0° = 500 µs, 180° = 2400 µs darbe / pulse
11 servo.duty_ns(500000 + a * 1900000 // 180)
12
13def measure_cm():
14 trig.value(0)
15 time.sleep_us(2)
16 trig.value(1) # 10 µs tetik / 10 µs trigger
17 time.sleep_us(10)
18 trig.value(0)
19 t = time_pulse_us(echo, 1, 30000) # en çok 30 ms bekle / wait at most 30 ms
20 if t < 0:
21 return 0 # yankı yok / no echo
22 return t // 58
23
24angle, step = 0, 2
25set_angle(angle)
26time.sleep_ms(500)
27
28while True:
29 set_angle(angle)
30 time.sleep_ms(40) # servo otursun / let the servo settle
31 print("{},{}".format(angle, measure_cm())) # açı,mesafe / angle,distance
32 if angle + step > 180 or angle + step < 0:
33 step = -step # uçta yön değiştir / reverse at the ends
34 angle += stepErrores comunes y soluciones
| Síntoma o mensaje de error | Causa | Solución |
|---|---|---|
| Error opening serial port COM3: Port busy | El Monitor Serie o el Serial Plotter del IDE de Arduino, Thonny o una segunda ventana de Processing están usando el puerto. | Cierra el Monitor Serie y los demás programas y vuelve a ejecutar el sketch de Processing; si hace falta, desconecta y vuelve a conectar el cable USB. |
| ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 | Serial.list() está vacío: la placa no está conectada, el cable solo sirve para cargar o falta el driver CH340. | Usa un cable de datos e instala el driver; si el IDE de Arduino ve el puerto, Processing también lo verá. |
| La ventana se abre pero la línea de barrido no se mueve | Se eligió el puerto equivocado (en Windows, COM1 suele salir el primero) o las velocidades en baudios no coinciden. | Busca la posición del Arduino en la lista de la consola, cámbialo a Serial.list()[1] o similar e iguala los baudios en ambos lados. |
| The package “processing.serial” does not exist. You might be missing a library. | No se encuentra la librería Serial; el instalador de Processing 4.4.8 venía sin ella. | Actualiza Processing a una versión más reciente o usa la 4.4.7, y comprueba que la línea import esté bien escrita. |
| Error opening serial port /dev/ttyACM0: Permission denied | En Linux tu usuario no tiene permiso para acceder al puerto serie. | Añade tu usuario al grupo dialout (sudo usermod -a -G dialout $USER) y cierra e inicia sesión de nuevo. |
| No se puede subir código al Arduino con Processing abierto | Processing está usando el puerto. | Detén el sketch de Processing con el botón Stop antes de subir el código. |
| La distancia siempre es 0 o da valores sin sentido | Trig y Echo están intercambiados, el sensor no tiene alimentación o el objeto está fuera de alcance. | Revisa las conexiones con la tabla y prueba primero con un sketch sencillo que solo mida la distancia. |
| El servo tiembla y el Arduino se reinicia solo | El puerto USB no da la corriente que pide el servo y la tensión cae. | Añade un condensador de 470 µF o alimenta el servo con una fuente externa de 5 V con GND común. |
| Izquierda y derecha invertidas en la pantalla del radar | El servo o el sensor están montados al revés. | En Processing escribe angle = 180 - int(parts[0]); o quita el brazo del servo y vuelve a colocarlo girado. |
Ideas para ampliar el proyecto de radar
- Radar de seguridad con alarma: cuando un objeto se acerque a menos de 30 cm, haz sonar un zumbador (buzzer) y enciende un LED rojo; combínalo con las ideas de sistema de alarma con Arduino.
- Robot que esquiva obstáculos: coloca el radar en la parte delantera de un robot; cuando se detenga, que explore a izquierda y derecha y gire hacia la dirección más despejada. Más detalles en robot evita obstáculos.
- Mapa de la habitación: guarda los datos del barrido en un módulo de tarjeta SD y dibújalos en el ordenador como una nube de puntos.
- Radar inalámbrico: envía las medidas desde un ESP32 por Wi-Fi a una página web en el móvil; con un servidor web en el ESP32 puedes dibujar en tiempo real.
- Mapa más nítido: usa un sensor láser (ToF) de haz estrecho en lugar del HC-SR04; encontrarás las opciones en la comparativa de sensores de distancia.
- Bastón inteligente: construye un bastón que avise de obstáculos a personas con discapacidad visual usando un sensor de distancia y un motor de vibración: proyecto de bastón inteligente.
Como combina un sensor de distancia, el control de un servo, la comunicación serie y el dibujo de gráficos en el ordenador en un solo montaje, el radar con Arduino es un gran siguiente paso para quien está empezando. Para afianzar las bases, echa un vistazo también a las guías del sensor de distancia HC-SR04 y del servomotor. En la aplicación BlueGrays encontrarás, paso a paso y con esquemas de circuito y código comentado, proyectos de medición de distancia con el HC-SR04, sensor de aparcamiento, uso de un servomotor y robot que esquiva obstáculos.
Preguntas frecuentes
¿Un radar con Arduino es un radar de verdad?
Técnicamente no, es un sonar. Los radares reales emiten ondas de radio, mientras que este proyecto usa las ondas de sonido de 40 kHz del HC-SR04. Se le llama "radar con Arduino" porque el principio es el mismo (emitir una onda, medir el tiempo del eco y dibujarlo junto con su dirección) y la pantalla se parece a la de un radar.
¿Hasta qué distancia detecta un radar con Arduino?
Según su hoja de datos, el HC-SR04 mide de 2 a 400 cm. Superficies grandes y planas como una pared se detectan hasta 3–4 metros, pero con objetos como la pata de una silla o una persona el alcance fiable suele ser de 1,5–2 metros. Ajustar MAX_CM en el código de Processing a ese alcance da la imagen más clara.
¿Qué materiales necesito para hacer un radar con Arduino?
Basta con un Arduino Uno o Nano, un sensor ultrasónico HC-SR04, un servo SG90, una protoboard, algunos cables jumper y un condensador de 470 µF para el servo. El programa gratuito Processing dibuja la pantalla del radar en el ordenador; para la versión sin ordenador se añade una pantalla OLED de 0,96 pulgadas.
¿Se puede hacer un radar con Arduino sin Processing?
Sí. Con una pantalla OLED SSD1306 puedes dibujar el radar directamente en el Arduino y convertirlo en un aparato portátil a pilas. Incluso sin pantalla, puedes seguir los valores de ángulo y distancia como gráfica en el Serial Plotter del IDE de Arduino.
¿Cómo se soluciona el error "Port busy" en Processing?
Este error indica que otro programa está usando el puerto serie. Cierra el Monitor Serie y el Serial Plotter del IDE de Arduino, Thonny o cualquier otro sketch de Processing que haya quedado abierto, y vuelve a intentarlo. Si sigue igual, desconecta el cable USB y vuelve a conectarlo.
¿Por qué tiembla el servo y se reinicia el Arduino?
El SG90 pide picos de corriente al moverse y la línea de 5 V de un Arduino alimentado por USB cae un instante. Un condensador de 470 µF en la alimentación del servo suele resolverlo; si no, alimenta el servo con una fuente externa de 5 V que comparta GND con el Arduino.
Proyectos para hacer después de leer esto
Ver todos los proyectos
HC-SR04 Medición de distancia (pantalla en serie)
El sensor HC-SR04 funciona igual que un murciélago que se orienta en la oscuridad: emite un sonido que no puedes oír, escucha el eco y mide a qué distancia está el objeto que tiene delante. El Arduino

Uso del servomotor
El brazo de un pequeño servomotor gira por turnos a tres posiciones: al principio del todo, justo al centro y al final del todo, esperando dos segundos en cada parada. El Arduino le dice al motor en q

SG90 Servocontrol de ángulo con potenciómetro
Control de servomotor (SG90) con potenciómetro El objetivo principal de este proyecto es controlar con precisión la posición angular de un servomotor en tiempo real utilizando una unidad de entrada analógica, el potenciómetro. El proyecto es un ejemplo básico de ingeniería para comprender la lógica de la conversión analógico-digital (ADC) y el mapeo de señales. Lógica de funcionamiento: Lectura de Datos Analógicos: Cuando el usuario gira el potenciómetro, se aplica una señal de voltaje entre 0V

Sensor de aparcamiento con HC-SR04
Una versión en miniatura del sensor de aparcamiento de los coches: cuanto más se acerca algo, más rápidos son los pitidos. El sensor de distancia mide el objeto que tiene delante; si está a más de 20

Robot para evitar obstáculos
¿Qué le parece construir un vehículo inteligente que encuentre su propio camino? El Robot Evitador de Obstáculos explora constantemente su entorno gracias al sensor ultrasónico que lleva delante. Cuan

ESP32 HC-SR04 Medidor de distancia por ultrasonidos
El sensor ultrasónico HC-SR04 calcula la distancia midiendo el tiempo de vuelo (Time of Flight) de la onda sonora que emite al chocar contra un objeto y rebotar. En este proyecto, enviaremos un pulso de 10 microsegundos desde el ESP32 al pin TRIG del sensor y leeremos el tiempo de eco procedente del pin ECHO mediante `pulseIn()`. Mostraremos la distancia calculada en centímetros en una pantalla LCD I2C de 16x2. Dado que el HC-SR04 funciona a 5 V, es obligatorio utilizar un **divisor de tensión**

Sensor de aparcamiento ESP32 (HC-SR04 + barra de 5 LED + zumbador + OLED)
¡La versión ESP32 del sensor de aparcamiento para coches! Medimos la distancia al objeto que hay delante mediante el sensor ultrasónico HC-SR04. A medida que la distancia disminuye, la barra de 5 LED se va llenando (verde → amarillo → rojo) y la frecuencia de los pitidos del zumbador se acorta. Cuando se acerca demasiado (menos de 10 cm), suena una alarma continua y se encienden todos los LED. En la pantalla OLED SSD1306 se muestra, en letra grande, el valor actual en centímetros, un mensaje de

Medición de distancias mediante pantalla LCD
Un aparato que mide distancias sin regla: mueve la mano delante del sensor y mira cómo cambia el número. El HC-SR04 envía una onda de sonido y escucha su eco, y el Arduino calcula la distancia en cent
Más artículos
App BlueGrays
Monta este circuito paso a paso en tu teléfono
Esquema, código y lista de piezas en una sola pantalla. Más de 160 proyectos de Arduino, ESP32 y Pico listos para montar.
Escanea con tu teléfono
Apunta la cámara al código y se abrirá la tienda de apps de tu teléfono.
o ábrela en la tienda

