¿Cuántas veces le has pegado al muro guardando el auto?

Si tienes un garage estrecho, la coreografía es siempre la misma: bajas el espejo, te acercas un metro, miras de nuevo, vuelves a avanzar dos centímetros y rezas para no rayar la pintura ni romper el portón. Este tutorial resuelve ese problema con un sensor ultrasónico HC SR04, un Arduino Uno y un LED verde que se enciende cuando el auto queda exactamente donde quieres.

Al terminar vas a tener un dispositivo que mide la distancia entre el muro y el parachoques en tiempo real, te avisa con una luz verde cuando estás en la zona correcta (configurable por ti con un encoder rotatorio), y muestra todo en una pantalla LCD pegada en la pared. Es un proyecto de fin de semana, cuesta menos de CLP $35.000 en componentes y funciona con código que puedes leer y modificar sin morir en el intento.

Concepto: cómo "ve" un sensor ultrasónico

El HC SR04 funciona con eco. Emite un pulso de ultrasonido a 40 kHz (inaudible para nosotros, no para tu gato) y mide cuánto tarda en volver después de rebotar en una superficie. Como el sonido viaja a unos 343 metros por segundo en aire a 20 °C, basta una división simple para convertir tiempo en distancia. Funciona bien entre 2 cm y 4 metros, con precisión de unos pocos milímetros si la superficie es plana y dura. un parachoques de auto es ideal.

¿Por qué no usamos un sensor infrarrojo o un láser TOF? El IR sufre con luz solar directa (un garage con tragaluz lo enloquece) y los TOF baratos (VL53L0X) tienen un alcance máximo de 2 m que se queda corto para autos grandes. El HC SR04 vale CLP $1.500 y aguanta polvo, humedad relativa y temperaturas de garage chileno sin pestañear.

Sensor ultrasónico mostrando sus dos transductores cilíndricos al frente

Sensor Alcance Costo aprox. Problemas
HC SR04 ultrasónico 2 cm, 4 m CLP $1.500 Falla en superficies blandas o angulares
VL53L0X (láser TOF) 3 cm, 2 m CLP $7.000 Alcance corto para garage grande
Sharp GP2Y0A02 (IR) 20 cm, 1,5 m CLP $9.000 Falla con luz solar directa
TCT40 Qwiic (tutorial original) 2 cm, 4 m CLP $12.000 importado Difícil de conseguir en Chile

Hardware: lista corta y barata

Toda la electrónica cabe en un protoboard de 830 puntos y se monta en menos de 20 minutos. Lo que sí: arma todo en mesa antes de pegarlo al muro del garage. vas a querer cambiarle el rango varias veces hasta que quede.

  • Arduino Uno R3 o equivalente (Nano, Pro Mini, ESP32 también sirven).
  • Sensor ultrasónico HC SR04.
  • Pantalla LCD 16x2 con backpack I2C (controlador PCF8574, dirección 0x27).
  • Encoder rotatorio KY-040 con botón integrado.
  • LED verde 5 mm (o RGB si quieres más colores).
  • Resistencia 220 Ω para limitar la corriente del LED.
  • Protoboard 830 puntos + jumpers macho macho y macho hembra.
  • Fuente 9 V o cargador USB para alimentación final.

Placa Arduino Uno (equivalente a la RedBoard del tutorial original) que actúa como cerebro del montaje

El HC SR04 que se vende en Chile tiene 4 pines (VCC, Trig, Echo, GND); el TCT40 del tutorial original usa el bus Qwiic (I2C) y es plug and-play, pero a USD $11 importado no compite con el HC SR04 a CLP $1.500 en stock local. Lo mismo vale para la pantalla: el OLED Qwiic del original cuesta $20 USD; el LCD 16x2 I2C chileno se consigue a CLP $5.000 y se lee bien incluso de noche con el backlight encendido.

Cableado: 12 jumpers y a otra cosa

Conecta todo así (el orden no importa, pero respeta los pines de datos):

HC SR04 → Arduino Uno

  • VCC → 5V
  • Trig → D9
  • Echo → D10
  • GND → GND

LCD 16x2 I2C → Arduino Uno

  • VCC → 5V
  • GND → GND
  • SDA → A4
  • SCL → A5

KY-040 → Arduino Uno

  • CLK → D2 (idealmente pin con interrupción, pero polling también funciona)
  • DT → D3
  • SW → D4
    • → 5V
  • GND → GND

LED indicador

  • Ánodo (pata larga) → D8 a través de la resistencia 220 Ω
  • Cátodo → GND

Si tu LCD I2C no parece andar después de cargar el código, lo más probable es que su dirección I2C no sea 0x27 sino 0x3F. Es el cambio de una sola línea más abajo. Para confirmar la dirección puedes usar el sketch I2C Scanner clásico (busca "I2C Scanner Arduino". es el primer resultado).

Encoder rotatorio KY-040 con eje plástico y botón pulsador integrado

Librería LiquidCrystal_I2C en 30 segundos

Abre el IDE de Arduino y ve a Programa → Incluir Librería → Administrar Bibliotecas. Busca "LiquidCrystal I2C" y instala la de Frank de Brabander (es la más usada y mantenida). Para el encoder y el HC SR04 no necesitas librería: trabajas directo con pulseIn() y digitalRead().

Si prefieres una abstracción más limpia para el ultrasónico, instala NewPing de Tim Eckel. maneja timeouts y filtra ecos múltiples, pero para este caso simple pulseIn() alcanza y sobra.

Código: 100 líneas comentadas

Copia esto en un sketch nuevo y súbelo al Arduino:

C++
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Pines del HC-SR04
const int trigPin = 9;
const int echoPin = 10;

// Pines del encoder KY-040
const int encoderCLK = 2;
const int encoderDT = 3;
const int encoderSW = 4;

// Pin del LED indicador
const int ledPin = 8;

// LCD 16x2 con backpack I2C (cambia a 0x3F si tu LCD usa esa direccion)
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Rango ajustable (en mm)
int minDistance = 200;
int maxDistance = 400;
bool settingMin = true;
bool inRange = false;

// Estado encoder
int lastCLK = HIGH;
unsigned long lastButtonPress = 0;
unsigned long lastDisplay = 0;

float measureDistance() {
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    long duration = pulseIn(echoPin, HIGH, 30000);
    if (duration == 0) return -1.0;
    // velocidad del sonido = 0.343 mm/us, dividido 2 por ida y vuelta
    return duration * 0.343 / 2.0;
}

void setup() {
    Serial.begin(115200);
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    pinMode(encoderCLK, INPUT_PULLUP);
    pinMode(encoderDT, INPUT_PULLUP);
    pinMode(encoderSW, INPUT_PULLUP);
    pinMode(ledPin, OUTPUT);

    lcd.init();
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("Sensor garage");
    lcd.setCursor(0, 1);
    lcd.print("Calibrando...");
    delay(1500);
    lcd.clear();

    lastCLK = digitalRead(encoderCLK);
}

void loop() {
    float currentDistance = measureDistance();

    // Boton: cambia entre ajustar min y max
    if (digitalRead(encoderSW) == LOW && millis() - lastButtonPress > 250) {
        settingMin = !settingMin;
        lastButtonPress = millis();
    }

    // Encoder: cambia el limite seleccionado en pasos de 10 mm
    int currentCLK = digitalRead(encoderCLK);
    if (currentCLK != lastCLK && currentCLK == LOW) {
        int delta = (digitalRead(encoderDT) != currentCLK) ? 10 : -10;
        if (settingMin) {
            minDistance += delta;
            if (minDistance < 30) minDistance = 30;
            if (minDistance >= maxDistance) minDistance = maxDistance - 10;
        } else {
            maxDistance += delta;
            if (maxDistance > 4000) maxDistance = 4000;
            if (maxDistance <= minDistance) maxDistance = minDistance + 10;
        }
    }
    lastCLK = currentCLK;

    // En rango? LED verde
    inRange = (currentDistance > 0 && currentDistance >= minDistance && currentDistance <= maxDistance);
    digitalWrite(ledPin, inRange ? HIGH : LOW);

    // Refrescar LCD cada 150 ms (mas seguido parpadea)
    if (millis() - lastDisplay > 150) {
        lcd.setCursor(0, 0);
        lcd.print(settingMin ? "MIN " : "MAX ");
        if (currentDistance < 0) {
            lcd.print("---     ");
        } else {
            lcd.print((int)currentDistance);
            lcd.print(" mm    ");
        }
        lcd.setCursor(0, 1);
        lcd.print(minDistance);
        lcd.print("-");
        lcd.print(maxDistance);
        lcd.print(" mm   ");
        lastDisplay = millis();
    }
}

El código está pensado para ser legible antes que eficiente. Los puntos clave:

  • measureDistance() devuelve mm (no cm), porque ajustar el rango en pasos de 10 mm da resolución pareja en la pantalla. Si prefieres cm, divide entre 10 antes de comparar.
  • Botón del encoder con debounce de 250 ms: sin él, un click se registra 3 veces y termina seleccionando el modo opuesto al que querías.
  • Refresco del LCD cada 150 ms: si refrescas en cada loop el display parpadea como letrero de neón roto y cuesta leerlo. 150 ms es el dulce punto entre fluidez y estabilidad.
  • Timeout del pulseIn en 30 ms: cubre los 4 metros del HC SR04 con margen. Si el sensor no recibe eco (rango fuera, superficie absorbente), devuelve 0 y el código lo muestra como --- en el LCD.

Calibración: 2 minutos en el garage

Una vez todo conectado, ponlo a la altura del parachoques (más o menos 50 cm del suelo) apuntando al muro. El proceso:

  1. Mete el auto a la posición exacta donde quieres que quede.
  2. Mide visualmente la distancia entre el parachoques y el muro. digamos 25 cm.
  3. Gira el encoder hasta que el MAX muestre 280 mm (25 cm + 3 cm de tolerancia).
  4. Pulsa el botón del encoder para cambiar a MIN.
  5. Gira hasta poner MIN en 220 mm (25 cm, 3 cm).
  6. El LED debería encenderse verde con el auto donde está.

La tolerancia de ±3 cm es lo suficientemente amplia para no enloquecer con vibraciones del motor, pero lo suficientemente angosta para que no avances 10 cm más y todavía pienses que estás bien estacionado.

Solución de problemas habituales

Síntoma Causa típica Solución
LCD enciende pero no muestra texto Dirección I2C distinta a 0x27 Cambia a LiquidCrystal_I2C lcd(0x3F, 16, 2);
LCD totalmente apagado SDA/SCL invertidos o sin alimentación Revisa A4 (SDA) y A5 (SCL) en el Uno
Distancia salta entre valores absurdos Eco rebotando en techo o piso Apunta el HC SR04 más recto al muro
El encoder cuenta 2 al mover 1 Sin debounce o pull ups flotando Verifica INPUT_PULLUP en CLK/DT/SW
LED siempre apagado Polaridad invertida Ánodo (pata larga) al pin 8 vía resistencia
Distancia siempre 0 o -1 Cable Trig o Echo suelto Mide continuidad con tester si tienes dudas

Variantes y mejoras

Una vez que el sistema básico funcione, hay tres extensiones que valen la pena:

  • Caso 3D para colgar en el muro: imprime una carcasa pequeña con dos orificios al frente para los transductores del HC SR04, una ventana rectangular para el LCD y un agujero para el LED. El archivo STL más usado para esto es el de Thingiverse: "HC SR04 Holder". lo escalas un 110% para que entren también el LCD y la lógica. Imprime en PETG si tu garage tiene cambios de temperatura grandes (el PLA se deforma sobre 50 °C en verano santiaguino).
  • Buzzer escalonado por distancia: agrega un buzzer pasivo al pin D7 y modula la frecuencia de pitidos como en los sensores de retroceso de auto: lento cuando estás lejos, más rápido cuando te acercas a la zona, constante cuando entras al rango. Total: 5 líneas extra de código y CLP $800 de buzzer.
  • Memoria de últimos límites: el rango se reinicia cada vez que cortas la luz. Si guardas minDistance y maxDistance en la EEPROM del Arduino (función EEPROM.put()), conservan el valor para siempre. Solo escribe a la EEPROM cuando se presiona el botón del encoder por 2 segundos, no en cada vuelta. la EEPROM aguanta ~100.000 ciclos de escritura, no infinitos.

Personalización para Chile

Lista de componentes en stock chileno típico para armar el proyecto entero en MechatronicStore:

  • Arduino Uno R3. la base del montaje (también funciona con Arduino Nano si quieres hacerlo más compacto).
  • Sensor ultrasónico HC SR04. reemplazo directo del TCT40 Qwiic del tutorial original, mismo principio pero 8× más barato.
  • LCD 16x2 con backpack I2C. alternativa más legible y económica que el OLED Qwiic original; ocupa solo 2 pines del Arduino.
  • Encoder rotatorio KY-040. reemplaza al Qwiic Twist con la misma funcionalidad (giro + botón); el LED RGB se sustituye por un LED 5 mm separado.
  • LED 5 mm verde y resistencia de 220 Ω. indicador visual.
  • Protoboard 830 puntos + jumpers macho macho 20cm y jumpers macho hembra 20cm. para montar todo sin soldar.
  • Cable USB-A a USB-B. para programar el Arduino Uno.
  • Fuente 9V switching o cargador USB-A 5V 2A. para alimentación permanente en el garage.

Comparado con el tutorial original que pide componentes Qwiic importados (SparkFun Distance Sensor + RedBoard + OLED + Twist + dos cables Qwiic), esta versión chilena cuesta aproximadamente un tercio y se monta con componentes que llegan al día siguiente vía despacho local.

Recursos

Versión chilena inspirada en el tutorial de SparkFun, re angulada con HC SR04 + LCD I2C + encoder KY-040 y componentes en stock local en MechatronicStore.