Práctica Arduino: Detector de obstáculos con sensor ultrasónico y servomotor

Vamos a montar un sistema que detecte obstáculos mediante un sensor ultrasónico HC-SR04 y utilice un servomotor SG90 para señalar la dirección que está libre.

La idea es construir un pequeño radar inteligente: cuando detecte un obstáculo delante, el sensor mirará hacia la izquierda y hacia la derecha, comparará las distancias y el servo terminará apuntando hacia el lado con más espacio disponible.

1. Material necesario

  • Arduino UNO o Arduino Mega 2560.
  • Sensor ultrasónico HC-SR04.
  • Servomotor SG90 de 180°.
  • Cables Dupont.
  • Protoboard (opcional).
  • Cable USB para programar el Arduino.

2. Conexiones

Sensor ultrasónico HC-SR04

Pin del sensorArduino
VCC5V
GNDGND
TRIGDigital 9
ECHODigital 10

Servomotor SG90

Cable del servoArduino
Marrón (GND)GND
Rojo (alimentación)5V
Naranja (señal)Digital 6

Para una prueba sencilla, un SG90 sin carga puede funcionar alimentado por el Arduino. Si hay reinicios, movimientos erráticos o el servo soporta peso, utiliza una fuente externa de 5 V adecuada, compartiendo GND con Arduino. No conectes el servo directamente a una fuente de 12 V.

3. Funcionamiento del proyecto

Ejemplo: el sistema detecta un obstáculo frontal y elige la izquierda porque mide una distancia mayor.

El programa seguirá esta secuencia:

  1. El servo coloca el sensor mirando al frente (90°).
  2. El HC-SR04 mide la distancia.
  3. Si el obstáculo está a menos de 20 cm, comienza la exploración.
  4. El servo gira a 150° para medir la izquierda y a 30° para medir la derecha.
  5. Compara las dos distancias.
  6. El servo se queda apuntando hacia la dirección con más espacio libre durante dos segundos y vuelve al centro.

4. Código completo de Arduino

Puedes copiar directamente este programa en Arduino IDE. No necesitas instalar bibliotecas adicionales: Servo.h viene incluida normalmente con el entorno de placas Arduino AVR.


#include <Servo.h>

// Pines del sensor ultrasónico
const int TRIG = 9;
const int ECHO = 10;

// Pin del servomotor
const int PIN_SERVO = 6;

// Ángulos del servo
const int CENTRO = 90;
const int IZQUIERDA = 150;
const int DERECHA = 30;

// Distancia mínima de seguridad (cm)
const int DISTANCIA_ALERTA = 20;

Servo radar;

// Función para medir distancia en centímetros
long medirDistancia() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);

  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  // Esperar respuesta como máximo 30 ms
  unsigned long duracion = pulseIn(ECHO, HIGH, 30000UL);

  // Sin eco: consideramos distancia máxima
  if (duracion == 0) {
    return 400;
  }

  return duracion / 58;
}

// Orientar sensor y realizar medición
long mirar(int angulo) {
  radar.write(angulo);
  delay(600);  // Esperar al movimiento del servo
  return medirDistancia();
}

void setup() {
  Serial.begin(9600);

  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);

  radar.attach(PIN_SERVO);
  radar.write(CENTRO);

  delay(1000);

  Serial.println("Sistema detector de obstaculos");
}

void loop() {

  // 1. Miramos hacia delante
  long frente = mirar(CENTRO);

  Serial.print("Distancia frontal: ");
  Serial.print(frente);
  Serial.println(" cm");

  // 2. Si hay un obstáculo cercano
  if (frente < DISTANCIA_ALERTA) {

    Serial.println("OBSTACULO DETECTADO");

    // 3. Explorar izquierda
    long distanciaIzquierda = mirar(IZQUIERDA);

    Serial.print("Izquierda: ");
    Serial.print(distanciaIzquierda);
    Serial.println(" cm");

    // 4. Explorar derecha
    long distanciaDerecha = mirar(DERECHA);

    Serial.print("Derecha: ");
    Serial.print(distanciaDerecha);
    Serial.println(" cm");

    // 5. Elegir dirección con más espacio
    if (distanciaIzquierda > distanciaDerecha) {

      Serial.println("Direccion recomendada: IZQUIERDA");
      radar.write(IZQUIERDA);

    } else if (distanciaDerecha > distanciaIzquierda) {

      Serial.println("Direccion recomendada: DERECHA");
      radar.write(DERECHA);

    } else {

      Serial.println("Distancias iguales");
      radar.write(CENTRO);
    }

    // 6. Mantener la dirección indicada
    delay(2000);

    // Volver al centro
    radar.write(CENTRO);
    delay(600);

  } else {
    Serial.println("Camino frontal despejado");
  }

  delay(300);
}

5. Prueba del funcionamiento

Abre el Monitor Serie del Arduino IDE y selecciona una velocidad de 9600 baudios.

Coloca un objeto a unos 10 cm del sensor. Deberías ver algo parecido a esto:

Distancia frontal: 12 cm
OBSTACULO DETECTADO
Izquierda: 85 cm
Derecha: 30 cm
Direccion recomendada: IZQUIERDA

El servo apuntará hacia la izquierda durante dos segundos y después regresará a su posición central.

Puedes modificar la sensibilidad cambiando esta línea:

const int DISTANCIA_ALERTA = 20;

Por ejemplo, puedes cambiar 20 por 40 para que comience a buscar caminos alternativos cuando detecte algo a menos de 40 cm.

6. Montaje físico

Es importante que el sensor HC-SR04 esté sujeto a la parte móvil del servo. De esta manera, cuando el motor gira, también gira el sensor y puede medir las distancias en diferentes direcciones.

Ten en cuenta que los ángulos de izquierda y derecha pueden estar invertidos según cómo coloques físicamente el servomotor. Si ocurre, intercambia los valores 150 y 30.

El código considera una ausencia de eco como 400 cm. Esto es útil para una demostración, pero no demuestra que exista un camino libre: también puede significar que el sensor no ha recibido una reflexión válida.

7. Actividad adicional para los alumnos

Una vez terminado el montaje, puedes pedirles que mejoren el proyecto incorporando tres condiciones diferentes:

  • Verde: no hay obstáculos a menos de 20 cm.
  • Amarillo: hay un obstáculo, pero se encuentra una dirección alternativa.
  • Rojo: las dos direcciones exploradas tienen obstáculos a menos de 20 cm.