Guías · 14 min de lectura

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.

Arduino Uno
Arduino Uno
HC-SR04
HC-SR04
SG90 servo
SG90 servo
Breadboard
Breadboard

¿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).

PiezaFunciónValores clave
HC-SR04Medición de distancia por ultrasonidos40 kHz, 2–400 cm, ángulo de medida de unos 15°, 5 V, 15 mA
Servo SG90Gira 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 UnoMide, mueve el servo y envía los datos16 MHz, nivel lógico de 5 V, puerto serie USB
ProcessingDibuja la pantalla del radar en el ordenadorGratuito, basado en Java, incluye la librería Serial
OLED SSD1306 (opcional)Mini pantalla de radar sin ordenador128×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ónArduino UnoESP32Raspberry Pi Pico
HC-SR04 VCC5VVIN (5 V)VBUS (pin 40)
HC-SR04 GNDGNDGNDGND
HC-SR04 TrigD10GPIO 26GP14
HC-SR04 EchoD11GPIO 27 (con divisor)GP13 (con divisor)
SG90 marrón (GND)GNDGNDGND
SG90 rojo (+5 V)5VVIN (5 V)VBUS (pin 40)
SG90 naranja (señal)D9GPIO 13GP15

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.

Cuando el HC-SR04 se alimenta con 5 V, su pin Echo también entrega 5 V. Para el Arduino Uno no es problema, pero los pines del ESP32 y de la Raspberry Pi Pico no toleran 5 V. Pon un divisor de tensión de 1 kΩ y 2 kΩ en la línea Echo (Echo → 1 kΩ → GPIO, GPIO → 2 kΩ → GND); la tensión en el pin baja a unos 3,3 V. Puedes comprobar los valores con la calculadora de divisor de tensión.

Montar el sensor sobre el servo

Micro servo SG90
Servo SG90: marrón es GND, rojo +5 V y naranja la señal. El HC-SR04 se pega sobre el brazo de plástico del 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

  1. Conecta los componentes según la tabla anterior, no olvides el condensador y monta el sensor sobre el servo.
  2. Abre el IDE de Arduino; la librería Servo viene incluida, así que no tienes que instalar nada más.
  3. 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.
  4. 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.
  5. Instala Processing 4 en tu ordenador, abre un sketch nuevo y pega el código de la pantalla del radar.
  6. 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

Arduino (C++)
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_DELAYDefinen 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 ... printlnEnví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 = -dirInvierte 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().

Si el servo zumba y tiembla justo en 0° o en 180°, está llegando a su tope mecánico. Reduce el barrido a 10–170° o inicia el servo con radarServo.attach(SERVO_PIN, 500, 2400) y ajusta el rango de pulsos a tu servo.

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.

Arduino (C++)
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 = 100ProcessingLa 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]ProcessingElige 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".
9600En ambosVelocidad en baudios; el valor de Serial.begin en el Arduino y el de Processing deben coincidir.
fill(0, 12)ProcessingVelocidad del desvanecimiento; 5 deja una estela larga y 30 una imagen casi sin estela.
size(1200, 700)ProcessingTamañ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.

PasoSTEP_DELAYUn barrido (0→180°)Resultado
1°20 msunos 7 sLa imagen más suave, pero lenta; el mismo objeto se mide muchas veces.
2°40 msunos 5 sAjuste recomendado: fluido y estable.
3°50 msunos 4 sMás rápido; gracias al haz de 15° del sensor no se escapa ningún objeto.
5°70 msunos 3,5 sLa 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.

TemperaturaVelocidad del sonidoIda y vuelta por 1 cmObjeto a 100 cm (con /58)
0 °C331,3 m/s60,4 µsunos 104 cm
10 °C337,4 m/s59,3 µsunos 102 cm
20 °C343,4 m/s58,2 µsunos 100 cm
30 °C349,5 m/s57,2 µsunos 99 cm
40 °C355,5 m/s56,3 µsunos 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.

Arduino (C++)
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.

Pantalla OLED I2C de 0,96 pulgadas SSD1306
Pantalla OLED de 0,96 pulgadas: en el mini radar sin ordenador se convierte en una pantalla de barrido semicircular de 128×64 píxeles.
Arduino (C++)
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.

Arduino (C++)
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.

MicroPython
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 += step

Errores comunes y soluciones

Síntoma o mensaje de errorCausaSolución
Error opening serial port COM3: Port busyEl 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 0Serial.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 mueveSe 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 deniedEn 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 abiertoProcessing 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 sentidoTrig 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 soloEl 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 radarEl 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.
Sigue este orden al depurar: primero comprueba las líneas "ángulo,distancia" en el Monitor Serie, luego cierra el Monitor Serie y ejecuta Processing. Si los datos llegan bien desde el Arduino, el problema casi siempre está en la elección del puerto o en los baudios.

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.

Ver todos los proyectos
HC-SR04 Medición de distancia (pantalla en serie)
#27Principiante

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

4.6(45)
68
Uso del servomotor
#35Principiante
Premium

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

4.7(48)
67
SG90 Servocontrol de ángulo con potenciómetro
#99Principiante
Premium

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

4.5(24)
38
Sensor de aparcamiento con HC-SR04
#28Intermedio
Premium

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

4.8(64)
84
Robot para evitar obstáculos
#81Avanzado
Premium

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

5.0(38)
49
ESP32 HC-SR04 Medidor de distancia por ultrasonidos
#116Intermedio

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**

4.9(28)
44
Sensor de aparcamiento ESP32 (HC-SR04 + barra de 5 LED + zumbador + OLED)
#142Avanzado
Premium

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

0.0(0)
14
Medición de distancias mediante pantalla LCD
#31Avanzado
Premium

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

4.6(45)
59