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 enmillis(), 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
Flujo conceptual de control: entrada de botones, selección de modo, temporización PWM y movimiento del servo.
Ruta de validación
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
- Conecta el pin de 5V del Arduino al riel de alimentación positivo de la protoboard.
- Conecta el pin GND del Arduino al riel de tierra de la protoboard.
Conexiones del sensor ultrasónico HC-SR04
| Pin HC-SR04 | Pin Arduino UNO R3 | Descripción |
|---|---|---|
| VCC | 5V (Riel de alimentación) | Fuente de alimentación de 5V |
| Trig | Pin Digital 9 | Emite el pulso de disparo de 10µs |
| Echo | Pin Digital 10 | Recibe el ancho de pulso de retorno |
| GND | GND (Riel de tierra) | Conexión a tierra |
Conexiones del zumbador pasivo
| Pin del Zumbador | Pin Arduino UNO R3 | Descripción |
|---|---|---|
| Positivo (+) | Pin Digital 8 | Salida 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 LCD | Nombre | Conexión Arduino / Componente | Descripción |
|---|---|---|---|
| 1 | VSS | GND (Riel de tierra) | Tierra |
| 2 | VDD | 5V (Riel de alimentación) | Alimentación lógica de 5V |
| 3 | V0 | Cursor central del potenciómetro | Ajuste de contraste |
| 4 | RS | Pin Digital 12 | Selección de registro (Register Select) |
| 5 | RW | GND (Riel de tierra) | Lectura/Escritura (conectado a bajo para solo escritura) |
| 6 | E | Pin Digital 11 | Pin de habilitación (Enable) |
| 11 | D4 | Pin Digital 5 | Línea de datos 4 |
| 12 | D5 | Pin Digital 4 | Línea de datos 5 |
| 13 | D6 | Pin Digital 3 | Línea de datos 6 |
| 14 | D7 | Pin Digital 2 | Línea de datos 7 |
| 15 | A | 5V a través de resistencia de 220Ω | Ánodo de retroiluminación (+) |
| 16 | K | GND (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.
- 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.
- 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).
- 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.
- 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
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.




