You dont have javascript enabled! Please enable it!

Caso práctico: alarma ultrasónica con Arduino UNO

Caso práctico: alarma ultrasónica con Arduino UNO — hero

Objetivo y caso de uso

Qué construirás: Construirás un prototipo educativo de alarma de distancia de estacionamiento ultrasónica que mide la proximidad del vehículo y proporciona retroalimentación visual y acústica en tiempo real. El sistema utiliza lógica no bloqueante para calcular simultáneamente la distancia, actualizar una pantalla LCD y modular la frecuencia de los pitidos de un zumbador según la proximidad.

Por qué es importante / Casos de uso

  • Estacionamiento en garaje residencial: Ayuda a visualizar la distancia desde una pared para evitar daños en el parachoques (por ejemplo, alertando con precisión a los 30 cm).
  • Fundamentos de ADAS: Demuestra los principios fundamentales detrás de los sensores de estacionamiento automotrices comerciales.
  • Lógica no bloqueante: Reemplaza las rudimentarias llamadas delay() con máquinas de estado basadas en millis(), permitiendo lecturas concurrentes del sensor y actualizaciones de la pantalla a 10+ Hz sin bloqueos.

Resultado esperado

  • Una alarma de proximidad funcional con < 50ms de latencia entre la detección del objeto y la respuesta del zumbador.
  • Una interfaz LCD que muestra métricas de distancia en tiempo real (cm) y advertencias de estado dinámicas.
  • Un zumbador pasivo que escala su frecuencia de pulso dinámicamente, culminando en un tono continuo y sólido a < 10 cm.

Audiencia: Estudiantes de sistemas embebidos y aficionados a la electrónica automotriz; Nivel: Intermedio

Arquitectura/flujo: Sensor ultrasónico (Trigger/Echo) → Microcontrolador (Máquina de estados no bloqueante) → Pantalla LCD I2C & Zumbador pasivo PWM

Nota educativa de validación

Antes de publicar este caso, el contenido pasó la puerta automática de validación de Prometeo con estado PASS. El validador comprobó los bloques de código, la estructura del artículo, los comandos copiables y la coherencia con el catálogo de dispositivos soportados.

Evidencia de validación publicada

  • Resultado automático: PASS.
  • Estructura parseada: 3 apartados, 3 tablas y 2 bloques de código detectados antes de publicar.
  • Código comprobado: 1 Arduino/arduino-cli compile, 1 Bash/copy-paste checks.
  • Catálogo soportado: el texto se contrastó contra los perfiles de dispositivo validables de Prometeo y los stacks no soportados bloquean la publicación.
  • Hallazgos del informe: sin hallazgos bloqueantes.

Esta validación confirma compatibilidad sintáctica y de herramientas para el material publicado, pero no sustituye la prueba física sobre tu hardware, cableado y entorno exactos.

Nota educativa de seguridad

Este proyecto es un prototipo educativo, no un producto certificado. Antes de encender la configuración, verifica la disposición de pines de tu revisión exacta de la placa ULX3S, mantén las señales de E/S de la FPGA a 3.3 V, nunca conectes 5 V directamente a los pines de E/S, desconecta la alimentación antes de cambiar el cableado y usa fuentes externas adecuadas para cargas, motores o servos, compartiendo la tierra solo cuando el cableado lo requiera.

Diagrama de bloques conceptual

Vista de alto nivel: qué entra, qué procesa cada bloque y qué sale del sistema.

Arquitectura funcional

Botones ULX3S

Sincronizador/antirrebote

Selector de modo

Generador periodo 20 ms

Comparador ancho de pulso

Salida PWM 50 Hz

Servo SG90

Flujo conceptual de control: entrada de botones, selección de modo, temporización PWM y movimiento del servo.

Ruta de validación

Verilog fuente

Verilator lint/testbench

Yosys síntesis

nextpnr-ecp5

ecppack bitstream

ULX3S programada

La validación automática comprueba sintaxis, simulación/lint y compatibilidad con la toolchain ULX3S/ECP5.

Requisitos previos

Para completar con éxito este tutorial, debes tener:
* Una comprensión básica de la sintaxis de C++ (variables, declaraciones if/else, funciones).
* Familiaridad con la creación de prototipos en protoboard y conexiones de cables puente.
* Una computadora con Windows, macOS o Linux con una interfaz de línea de comandos.
* La arduino-cli (Interfaz de línea de comandos de Arduino) instalada y añadida al PATH de tu sistema.

Materiales

Necesitarás los componentes exactos enumerados a continuación para garantizar la compatibilidad con el código proporcionado y las instrucciones de cableado:
* Microcontrolador: 1x Arduino UNO R3 (ATmega328P).
* Sensor: 1x Sensor ultrasónico HC-SR04.
* Pantalla: 1x LCD 16×2 HD44780 (interfaz paralela estándar, sin mochila I2C).
* Audio: 1x Zumbador pasivo (requiere una señal de frecuencia para generar sonido).
* Componentes: 1x Potenciómetro de 10kΩ (para el ajuste de contraste del LCD), 1x Resistencia de 220Ω (para limitar la corriente de la retroiluminación del LCD).
* Prototipado: 1x Protoboard estándar y un juego de cables puente macho a macho.
* Alimentación/Datos: 1x Cable USB Tipo-A a Tipo-B.

Configuración/Conexión

El LCD HD44780 utiliza una interfaz paralela de 4 bits para ahorrar pines digitales en el Arduino. El HC-SR04 requiere un pin para activar el pulso ultrasónico y otro para leer el eco de retorno.

Distribución de energía

  1. Conecta el pin de 5V del Arduino al riel de alimentación positivo de la protoboard.
  2. Conecta el pin GND del Arduino al riel de tierra de la protoboard.

Conexiones del sensor ultrasónico HC-SR04

Pin HC-SR04Pin Arduino UNO R3Descripción
VCC5V (Riel de alimentación)Fuente de alimentación de 5V
TrigPin Digital 9Emite el pulso de disparo de 10µs
EchoPin Digital 10Recibe el ancho de pulso de retorno
GNDGND (Riel de tierra)Conexión a tierra

Conexiones del zumbador pasivo

Pin del ZumbadorPin Arduino UNO R3Descripción
Positivo (+)Pin Digital 8Salida de PWM/Frecuencia vía tone()
Negativo (-)GND (Riel de tierra)Conexión a tierra

Conexiones del LCD 16×2 HD44780

Nota: Las patas exteriores del potenciómetro de 10kΩ se conectan a 5V y GND. El cursor central se conecta al pin V0 del LCD para ajustar el contraste del texto.

Pin LCDNombreConexión Arduino / ComponenteDescripción
1VSSGND (Riel de tierra)Tierra
2VDD5V (Riel de alimentación)Alimentación lógica de 5V
3V0Cursor central del potenciómetroAjuste de contraste
4RSPin Digital 12Selección de registro (Register Select)
5RWGND (Riel de tierra)Lectura/Escritura (conectado a bajo para solo escritura)
6EPin Digital 11Pin de habilitación (Enable)
11D4Pin Digital 5Línea de datos 4
12D5Pin Digital 4Línea de datos 5
13D6Pin Digital 3Línea de datos 6
14D7Pin Digital 2Línea de datos 7
15A5V a través de resistencia de 220ΩÁnodo de retroiluminación (+)
16KGND (Riel de tierra)Cátodo de retroiluminación (-)

Código validado

Crea un nuevo directorio llamado ParkingAlarm y guarda el siguiente código como ParkingAlarm.ino. Las definiciones de pines y los umbrales se incluyen en la parte superior del archivo para facilitar el ajuste.

#include <LiquidCrystal.h>

// -----------------------------------------
// Pin Definitions
// -----------------------------------------
#define TRIG_PIN 9
#define ECHO_PIN 10
#define BUZZER_PIN 8

// HD44780 LCD (4-bit mode)
#define LCD_RS 12
#define LCD_EN 11
#define LCD_D4 5
#define LCD_D5 4
#define LCD_D6 3
#define LCD_D7 2

// -----------------------------------------
// System Thresholds (in centimeters)
// -----------------------------------------
#define DIST_MAX   200  // Maximum reliable distance to process
#define DIST_WARN  100  // Start warning (slow beep)
#define DIST_ALARM 50   // Start alarm (dynamic fast beep)
#define DIST_STOP  10   // Stop immediately (continuous tone)

// Initialize the LCD library with the interface pins
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);

// Variables for non-blocking buzzer timing
unsigned long previousBuzzerMillis = 0;
bool buzzerState = false;

void setup() {
    // Initialize Serial for debugging
    Serial.begin(115200);

    // Configure hardware pins
    pinMode(TRIG_PIN, OUTPUT);
    pinMode(ECHO_PIN, INPUT);
    pinMode(BUZZER_PIN, OUTPUT);

    // Initialize the LCD's columns and rows
    lcd.begin(16, 2);

    // Display a startup message
    lcd.setCursor(0, 0);
    lcd.print("Parking Assist");
    lcd.setCursor(0, 1);
    lcd.print("System Booting..");
    delay(2000); // 2-second boot delay is acceptable here
    lcd.clear();
}

// Function to trigger the HC-SR04 and calculate distance
long readDistance() {
    // Ensure the trigger pin is low before pulsing
    digitalWrite(TRIG_PIN, LOW);
    delayMicroseconds(2);

    // Send a 10 microsecond high pulse to trigger the sensor
    digitalWrite(TRIG_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG_PIN, LOW);

    // Read the echo pin; timeout after 30,000 microseconds (approx 5 meters)
    long duration = pulseIn(ECHO_PIN, HIGH, 30000);

    // If timeout occurred, return -1 to indicate out of range
    if (duration == 0) {
        return -1;
    }

    // Calculate distance in centimeters
    // Speed of sound is 343 m/s or 0.0343 cm/microsecond
    // Divide by 2 to account for the round trip (ping and echo)
    return (duration * 0.0343) / 2;
}

void loop() {
    long distance = readDistance();
    unsigned long currentMillis = millis();

    // Debug output
    Serial.print("Distance: ");
    Serial.println(distance);

    // Top row: Display distance
    lcd.setCursor(0, 0);
    if (distance == -1 || distance > DIST_MAX) {
        lcd.print("Out of Range    "); // Pad with spaces to clear old chars
        noTone(BUZZER_PIN);

        lcd.setCursor(0, 1);
        lcd.print("Status: STANDBY ");
    } else {
        lcd.print("Dist: ");
        if (distance < 100) lcd.print(" "); // Alignment padding
        if (distance < 10)  lcd.print(" "); // Alignment padding
        lcd.print(distance);
        lcd.print(" cm      ");

        // Bottom row: Display status and handle buzzer logic
        lcd.setCursor(0, 1);

        if (distance > DIST_WARN) {
            // Safe zone
            lcd.print("Status: SAFE    ");
            noTone(BUZZER_PIN);

        } else if (distance > DIST_ALARM) {
            // Warning zone: Slow beep
            lcd.print("Status: SLOW    ");
            if (currentMillis - previousBuzzerMillis >= 500) { // 500ms interval
                previousBuzzerMillis = currentMillis;
                buzzerState = !buzzerState;
                if (buzzerState) {
                    tone(BUZZER_PIN, 1000); // 1000 Hz pitch
                } else {
                    noTone(BUZZER_PIN);
                }
            }

        } else if (distance > DIST_STOP) {
            // Alarm zone: Dynamic fast beep
            lcd.print("Status: ALARM   ");

            // Map the distance to a beep interval (closer = faster beep)
            // 50cm -> 400ms interval, 10cm -> 50ms interval
            int beepInterval = map(distance, DIST_STOP, DIST_ALARM, 50, 400);

            if (currentMillis - previousBuzzerMillis >= beepInterval) {
                previousBuzzerMillis = currentMillis;
                buzzerState = !buzzerState;
                if (buzzerState) {
                    tone(BUZZER_PIN, 1500); // 1500 Hz pitch
                } else {
                    noTone(BUZZER_PIN);
                }
            }

        } else {
            // Stop zone: Continuous tone
            lcd.print("Status: STOP!   ");
            tone(BUZZER_PIN, 2000); // 2000 Hz high pitch alert
        }
    }

    // Small delay to stabilize the loop and prevent LCD flickering
    delay(50);
}

Comandos de compilación/flasheo/ejecución

Usaremos la CLI de Arduino para compilar y cargar el código. Abre tu terminal, navega hasta el directorio que contiene la carpeta ParkingAlarm y ejecuta los siguientes comandos.

Nota: Reemplaza /dev/ttyACM0 con tu puerto serie real (por ejemplo, COM3 en Windows o /dev/cu.usbmodem14101 en macOS).

# Update the core index
arduino-cli core update-index

# Install the AVR core
arduino-cli core install arduino:avr

# Compile the sketch
arduino-cli compile --fqbn arduino:avr:uno ParkingAlarm

# Upload to the board
arduino-cli upload --fqbn arduino:avr:uno --port /dev/ttyACM0 ParkingAlarm

# Monitor serial output
arduino-cli monitor --port /dev/ttyACM0 --config baudrate=115200

Validación paso a paso

Sigue estos puntos de control para asegurarte de que tu prototipo funciona correctamente y cumple con las afirmaciones de rendimiento.

  1. Comprobación de inicialización del LCD
    • Acción: Suministra energía al Arduino a través de USB.
    • Evidencia esperada: La retroiluminación del LCD se enciende y el texto «Parking Assist» seguido de «System Booting..» aparece durante 2 segundos antes de borrarse. Ajusta el potenciómetro si el texto no es visible.
  2. Validación de precisión de distancia
    • Acción: Coloca un objeto plano y rígido (como un trozo de cartón o un libro) exactamente a 50 cm de distancia del sensor, medido con una cinta métrica física.
    • Evidencia esperada: El LCD debería mostrar Dist: 50 cm (una tolerancia de ± 1-2 cm es aceptable debido a que la velocidad del sonido varía ligeramente con la temperatura ambiente).
  3. Validación de tasa de actualización a 10 Hz
    • Acción: Observa las marcas de tiempo de salida del Monitor Serie.
    • Evidencia esperada: El delay(50) más el tiempo de espera del sensor limitan el bucle a aproximadamente 100 ms por ciclo. Deberías ver aproximadamente 10 lecturas de distancia impresas en la consola serie cada segundo, lo que confirma la tasa objetivo de 10 Hz.
  4. Validación de zona acústica
    • Acción: Mueve el objeto rígido progresivamente más cerca del sensor, comenzando desde 150 cm hasta 5 cm.
    • Evidencia esperada:
      • > 100 cm: El LCD muestra «Status: SAFE», el zumbador está completamente en silencio.
      • 99 cm a 51 cm: El LCD muestra «Status: SLOW», el zumbador emite 1 pitido constante por segundo.
      • 50 cm a 11 cm: El LCD muestra «Status: ALARM», la frecuencia de los pitidos del zumbador aumenta dinámicamente a medida que el objeto se acerca.
      • <= 10 cm: El LCD muestra «Status: STOP!», el zumbador emite un tono agudo, continuo e ininterrumpido.

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a Amazon

Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.

Quiz rápido

Pregunta 1: ¿Qué tipo de prototipo educativo se construirá según el texto?




Pregunta 2: ¿Qué tipo de retroalimentación proporciona el sistema en tiempo real?




Pregunta 3: ¿Qué componente se utiliza para emitir los pitidos según la proximidad?




Pregunta 4: ¿Qué tipo de lógica utiliza el sistema para realizar múltiples tareas simultáneamente?




Pregunta 5: ¿Cuál es un caso de uso mencionado para este prototipo en un entorno residencial?




Pregunta 6: ¿A qué distancia de ejemplo menciona el texto que el sistema puede alertar con precisión en un garaje?




Pregunta 7: ¿Qué principios fundamentales demuestra este prototipo?




Pregunta 8: ¿Qué función de programación rudimentaria se reemplaza para evitar bloqueos en el sistema?




Pregunta 9: ¿Qué función se utiliza en las máquinas de estado para permitir lecturas concurrentes sin bloqueos?




Pregunta 10: ¿Cuál es la latencia esperada entre la detección del objeto y la respuesta del zumbador?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll al inicio